TFT ST7735的Netduino驱动

好久没写关于netduino的文章了,工作忙是一方面,主要原因还是因为没解决TFT显示的问题,功夫不负有心人,在经过多轮研究后,总算在今天2013年12月15日的晚上9点解决了。

下面先介绍一下我所用的这款tft

        概述:

OJ TFT液晶屏是含有插针和背光的LCD屏,使用TFT library 库文件,你可以显示文本、图片等。液晶背面含有板载的micro-SD卡槽,使您能够存储位图图像并在屏幕上显示。屏幕的引脚扩展接口完全兼容 Arduino Esplora 可以直接插在扩展口上。

  • 参数:

模块尺寸:60mm*42mm

像素:128(RGB)*160

显示色彩:全彩

供电电压:5V

  • 引脚定义:

a.正面 b.反面
引脚号 标识 功能
1 +5V 电源DC 5V+
2 MISO SPI接口
3 SCK
4 MOSI
5 CS-LD 液晶屏使能
6 CS-TF TF卡使能
7 D/C-LD 液晶屏数据/指令控制
8 RESET 液晶屏复位
9 BL 液晶屏背光控制:

 

背光亮:置High,并可通过PWM控制亮度

背光灭:置Low或悬空

10 GND 电源DC
  • TFT淘宝地址:

  • http://item.taobao.com/item.htm?spm=686.1000925.1000774.17.ttK7h5&id=35934491963

  • Netduino淘宝地址:

  • http://item.taobao.com/item.htm?spm=686.1000925.1000774.32.ttK7h5&id=21448079990

  • netduino与ST7735的接线

  • netduino D11 -----ST7735   MOSI

  • netduino D12 -----ST7735   MISO

  • netduino D13 -----ST7735   SCK

  • netduino D9   -----ST7735   CS-LD

  • netduino D7 -----ST7735   D/C-LD

  • netduino D8 -----ST7735   RESET

  • netduino D1 -----ST7735   BL

  • netduino 5v -----ST7735   5v

  • netduino GND -----ST7735   GND

  •  驱动

  • 通过与arduino的驱动对比,修改了从netduinohelper上下在的st7735驱动,对比了arduino和netduinohelper的驱动的区别, 修改对应的寄存器参数才可以正常显示

  • 这款tft的优点是采用spi口,可以节省相关的D口接线。

  • SPI初始化

  •   var extendedSpiConfig = new ExtendedSpiConfiguration(
                    SPI_mod: spiModule,
                    ChipSelect_Port: chipSelect,
                    ChipSelect_ActiveState: false,
                    ChipSelect_SetupTime: 0,
                    ChipSelect_HoldTime: 0,
                    Clock_IdleState: false,
                    Clock_Edge: true,
                    Clock_RateKHz: speedKHz,
                    BitsPerTransfer: 8);

  •             Spi = new SPI(extendedSpiConfig);

  • 初始化寄存器

  • private void Initialize()
            {
                Reset.Write(true);
                Thread.Sleep(50);
                Reset.Write(false);
                Thread.Sleep(50);
                Reset.Write(true);
                Thread.Sleep(50);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.SWRESET); // software reset
                Thread.Sleep(150);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.SLPOUT);  // out of sleep mode
                Thread.Sleep(255);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.FRMCTR1);  // frame rate control - normal mode
                DataCommand.Write(Data);
                Write(0x01);  // frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
                Write(0x2C);
                Write(0x2D);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.FRMCTR2);  // frame rate control - idle mode
                DataCommand.Write(Data);
                Write(0x01);  // frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
                Write(0x2C);
                Write(0x2D);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.FRMCTR3);  // frame rate control - partial mode
                DataCommand.Write(Data);
                Write(0x01); // dot inversion mode
                Write(0x2C);
                Write(0x2D);
                Write(0x01); // line inversion mode
                Write(0x2C);
                Write(0x2D);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.INVCTR);  // display inversion control
                DataCommand.Write(Data);
                Write(0x07);  // no inversion

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.PWCTR1);  // power control
                DataCommand.Write(Data);
                Write(0xA2);
                Write(0x02);      // -4.6V
                Write(0x84);      // AUTO mode

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.PWCTR2);  // power control
                DataCommand.Write(Data);
                Write(0xC5);      // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.PWCTR3);  // power control
                DataCommand.Write(Data);
                Write(0x0A);      // Opamp current small
                Write(0x00);      // Boost frequency

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.PWCTR4);  // power control
                DataCommand.Write(Data);
                Write(0x8A);      // BCLK/2, Opamp current small & Medium low
                Write(0x2A);

  •             Write((byte)LcdCommand.PWCTR5);  // power control
                DataCommand.Write(Data);
                Write(0x8A);
                Write(0xEE);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.VMCTR1);  // power control
                DataCommand.Write(Data);
                Write(0x0E);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.INVOFF);    // don't invert display

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.MADCTL);  // memory access control (directions)
                DataCommand.Write(Data);
                Write(0xC8);  // row address/col address, bottom to top refresh

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.COLMOD);  // set color mode
                DataCommand.Write(Data);
                Write(0x05);        // 16-bit color

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.CASET);  // column addr set
                DataCommand.Write(Data);
                Write(0x00);
                Write(0x00);   // XSTART = 0
                Write(0x00);
                Write(0x7F);   // XEND = 127

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.RASET);  // row addr set
                DataCommand.Write(Data);
                Write(0x00);
                Write(0x00);    // XSTART = 0
                Write(0x00);
                Write(0x9F);    // XEND = 159

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.GMCTRP1);
                DataCommand.Write(Data);
                Write(0x02);
                Write(0x1c);
                Write(0x07);
                Write(0x12);
                Write(0x37);
                Write(0x32);
                Write(0x29);
                Write(0x2d);
                Write(0x29);
                Write(0x25);
                Write(0x2B);
                Write(0x39);
                Write(0x00);
                Write(0x01);
                Write(0x03);
                Write(0x10);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.GMCTRN1);
                DataCommand.Write(Data);
                Write(0x03);
                Write(0x1d);
                Write(0x07);
                Write(0x06);
                Write(0x2E);
                Write(0x2C);
                Write(0x29);
                Write(0x2D);
                Write(0x2E);
                Write(0x2E);
                Write(0x37);
                Write(0x3F);
                Write(0x00);
                Write(0x00);
                Write(0x02);
                Write(0x10);


  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.NORON);  // normal display on
                Thread.Sleep(10);

  •             DataCommand.Write(Command);
                Write((byte)LcdCommand.DISPON);
                Thread.Sleep(100);

  •             //SetAddressWindow(0, 0, (byte)(Width - 1), (byte)(Height - 1));
                //SetAddressWindow(0, 0, Width - 1, Height - 1);

  •             DataCommand.Write(Data);

  •         }

  • 初始化之后就可以调用相关的函数绘制图形了

  • 附上驱动代码

  • ST7735TFT.cs

  •  

    using System;
    
    using System.Threading;
    
    using Microsoft.SPOT.Hardware;
    
    using SecretLabs.NETMF.Hardware;
    
    
    
    namespace ST7735TFT
    
    {
    
        /// <summary>
    
        /// netduino ST7735 driver (based on AdaFruit's library http://github.com/adafruit/ST7735-Library)
    
        /// </summary>
    
        public class ST7735TFT : IDisposable
    
        {
    
    
    
            public byte Width { get; set; }
    
            public byte Height { get; set; }
    
    
    
            public enum LcdCommand
    
            {
    
                NOP = 0x0,
    
                SWRESET = 0x01,
    
                RDDID = 0x04,
    
                RDDST = 0x09,
    
                SLPIN = 0x10,
    
                SLPOUT = 0x11,
    
                PTLON = 0x12,
    
                NORON = 0x13,
    
                INVOFF = 0x20,
    
                INVON = 0x21,
    
                DISPOFF = 0x28,
    
                DISPON = 0x29,
    
                CASET = 0x2A,
    
                RASET = 0x2B,
    
                RAMWR = 0x2C,
    
                RAMRD = 0x2E,
    
                PTLAR = 0x30,
    
                COLMOD = 0x3A,
    
                MADCTL = 0x36,
    
                FRMCTR1 = 0xB1,
    
                FRMCTR2 = 0xB2,
    
                FRMCTR3 = 0xB3,
    
                INVCTR = 0xB4,
    
                DISSET5 = 0xB6,
    
                PWCTR1 = 0xC0,
    
                PWCTR2 = 0xC1,
    
                PWCTR3 = 0xC2,
    
                PWCTR4 = 0xC3,
    
                PWCTR5 = 0xC4,
    
                VMCTR1 = 0xC5,
    
                RDID1 = 0xDA,
    
                RDID2 = 0xDB,
    
                RDID3 = 0xDC,
    
                RDID4 = 0xDD,
    
                PWCTR6 = 0xFC,
    
                GMCTRP1 = 0xE0,
    
                GMCTRN1 = 0xE1
    
            }
    
    
    
            public enum Colors
    
            {
    
                Black = 0x0000,
    
                Blue = 0x001F,
    
                Red = 0xF800,
    
                Green = 0x07E0,
    
                Cyan = 0x07FF,
    
                Magenta = 0xF81F,
    
                Yellow = 0xFFE0,
    
                White = 0xFFFF
    
            }
    
    
    
            public ST7735TFT(
    
                Cpu.Pin chipSelect,
    
                Cpu.Pin dc,
    
                Cpu.Pin reset,
    
                SPI.SPI_module spiModule = SPI.SPI_module.SPI1,
    
                uint speedKHz = (uint)9500,
    
                VirtualMemory vm = null)
    
            {
    
    
    
                Width = 128;
    
                Height = 160;
    
    
    
                AutoRefreshScreen = true;
    
    
    
                DataCommand = new OutputPort(dc, false);
    
                Reset = new OutputPort(reset, true);
    
                //SPI.Configuration SPI_Config = new SPI.Configuration(chipSelect, false, 0, 0, false, true, 10000, SPI.SPI_module.SPI1);
    
                var extendedSpiConfig = new ExtendedSpiConfiguration(
    
                    SPI_mod: spiModule,
    
                    ChipSelect_Port: chipSelect,
    
                    ChipSelect_ActiveState: false,
    
                    ChipSelect_SetupTime: 0,
    
                    ChipSelect_HoldTime: 0,
    
                    Clock_IdleState: false,
    
                    Clock_Edge: true,
    
                    Clock_RateKHz: speedKHz,
    
                    BitsPerTransfer: 8);
    
    
    
                Spi = new SPI(extendedSpiConfig);
    
    
    
                if (vm == null)
    
                {
    
                    SpiBuffer = new byte[Width * Height * sizeof(ushort)];
    
                    MemoryWriteFunction = SpiBufferWrite;
    
                }
    
                else
    
                {
    
                    VM = vm;
    
                    MemoryWriteFunction = VirtualMemoryWrite;
    
                }
    
    
    
                Initialize();
    
            }
    
    
    
            public bool AutoRefreshScreen { get; set; }
    
    
    
            public void Refresh()
    
            {
    
                if (VM == null)
    
                {
    
                    Spi.Write(SpiBuffer);
    
                }
    
                else
    
                {
    
                    var address = 0;
    
                    var memorySegments = (VM.Stream.Length / VM.Buffer.Length);
    
                    var heightIncrement = Height / memorySegments;
    
                    for (var y0 = 0; y0 < Height; y0 += (byte)heightIncrement)
    
                    {
    
                        SetAddressWindow(0, (byte)y0, (byte)(Width - 1), (byte)((y0 + heightIncrement) - 1));
    
                        VM.ReadVM(address, 0);
    
                        address += VM.Buffer.Length;
    
                        Spi.Write(VM.Buffer);
    
                    }
    
                }
    
            }
    
    
    
            public ushort GetRGBColor(byte red, byte green, byte blue)
    
            {
    
                red &= 0x1F;
    
                ushort color = red;
    
                color <<= 6;
    
                green &= 0x3F;
    
                color |= green;
    
                color <<= 5;
    
                blue &= 0x1F;
    
                color |= blue;
    
                return color;
    
            }
    
    
    
            public void DrawPixel(int x, int y, ushort color)
    
            {
    
                SetPixel(x, y, color);
    
                if (AutoRefreshScreen)
    
                {
    
                    Refresh();
    
                }
    
            }
    
    
    
            // Bresenham's algorithm: http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
    
            public void DrawLine(int startX, int startY, int endX, int endY, ushort color)
    
            {
    
                int steep = (System.Math.Abs(endY - startY) > System.Math.Abs(endX - startX)) ? 1 : 0;
    
    
    
                if (steep != 0)
    
                {
    
                    Swap(ref startX, ref startY);
    
                    Swap(ref endX, ref endY);
    
                }
    
    
    
                if (startX > endX)
    
                {
    
                    Swap(ref startX, ref endX);
    
                    Swap(ref startY, ref endY);
    
                }
    
    
    
                int dx, dy;
    
                dx = endX - startX;
    
                dy = System.Math.Abs(endY - startY);
    
    
    
                int err = dx / 2;
    
                int ystep = 0;
    
    
    
                if (startY < endY)
    
                {
    
                    ystep = 1;
    
                }
    
                else
    
                {
    
                    ystep = -1;
    
                }
    
    
    
                for (; startX < endX; startX++)
    
                {
    
                    if (steep != 0)
    
                    {
    
                        SetPixel(startY, startX, color);
    
                    }
    
                    else
    
                    {
    
                        SetPixel(startX, startY, color);
    
                    }
    
                    err -= dy;
    
                    if (err < 0)
    
                    {
    
                        startY += ystep;
    
                        err += dx;
    
                    }
    
                }
    
                if (AutoRefreshScreen)
    
                {
    
                    Refresh();
    
                }
    
            }
    
    
    
            public void DrawCircle(int centerX, int centerY, int radius, ushort color)
    
            {
    
                int f = 1 - radius;
    
                int ddF_x = 1;
    
                int ddF_y = -2 * radius;
    
                int x = 0;
    
                int y = radius;
    
    
    
                SetPixel(centerX, centerY + radius, color);
    
                SetPixel(centerX, centerY - radius, color);
    
                SetPixel(centerX + radius, centerY, color);
    
                SetPixel(centerX - radius, centerY, color);
    
    
    
                while (x < y)
    
                {
    
                    if (f >= 0)
    
                    {
    
                        y--;
    
                        ddF_y += 2;
    
                        f += ddF_y;
    
                    }
    
    
    
                    x++;
    
                    ddF_x += 2;
    
                    f += ddF_x;
    
    
    
                    SetPixel(centerX + x, centerY + y, color);
    
                    SetPixel(centerX - x, centerY + y, color);
    
                    SetPixel(centerX + x, centerY - y, color);
    
                    SetPixel(centerX - x, centerY - y, color);
    
    
    
                    SetPixel(centerX + y, centerY + x, color);
    
                    SetPixel(centerX - y, centerY + x, color);
    
                    SetPixel(centerX + y, centerY - x, color);
    
                    SetPixel(centerX - y, centerY - x, color);
    
                }
    
                if (AutoRefreshScreen)
    
                {
    
                    Refresh();
    
                }
    
            }
    
    
    
            public void ClearScreen(ushort color = (ushort) Colors.Black)
    
            {
    
                var high = (byte)(color >> 8);
    
                var low = (byte)color;
    
    
    
                var index = 0;
    
    
    
                if (VM == null)
    
                {
    
                    SpiBuffer[index++] = high;
    
                    SpiBuffer[index++] = low;
    
                    SpiBuffer[index++] = high;
    
                    SpiBuffer[index++] = low;
    
                    SpiBuffer[index++] = high;
    
                    SpiBuffer[index++] = low;
    
                    SpiBuffer[index++] = high;
    
                    SpiBuffer[index++] = low;
    
                    SpiBuffer[index++] = high;
    
                    SpiBuffer[index++] = low;
    
                    SpiBuffer[index++] = high;
    
                    SpiBuffer[index++] = low;
    
                    SpiBuffer[index++] = high;
    
                    SpiBuffer[index++] = low;
    
                    SpiBuffer[index++] = high;
    
                    SpiBuffer[index++] = low;
    
    
    
                    Array.Copy(SpiBuffer, 0, SpiBuffer, 16, 16);
    
                    Array.Copy(SpiBuffer, 0, SpiBuffer, 32, 32);
    
                    Array.Copy(SpiBuffer, 0, SpiBuffer, 64, 64);
    
                    Array.Copy(SpiBuffer, 0, SpiBuffer, 128, 128);
    
                    Array.Copy(SpiBuffer, 0, SpiBuffer, 256, 256);
    
    
    
                    index = 512;
    
                    var line = 0;
    
                    var Half = Height / 2;
    
                    while (++line < Half - 1)
    
                    {
    
                        Array.Copy(SpiBuffer, 0, SpiBuffer, index, 256);
    
                        index += 256;
    
                    }
    
    
    
                    Array.Copy(SpiBuffer, 0, SpiBuffer, index, SpiBuffer.Length / 2);
    
                }
    
                else
    
                {
    
                    for (; index < VM.Buffer.Length; )
    
                    {
    
                        VM.Buffer[index++] = high;
    
                        VM.Buffer[index++] = low;
    
                    }
    
                    VM.FillFromBuffer();
    
                }
    
    
    
                if (AutoRefreshScreen)
    
                {
    
                    Refresh();
    
                }
    
            }
    
    
    
            public void Dispose()
    
            {
    
                Spi.Dispose();
    
                SpiBuffer = null;
    
                Spi = null;
    
                DataCommand = null;
    
                Reset = null;
    
                VM = null;
    
            }
    
    
    
            private void Initialize()
    
            {
    
                Reset.Write(true);
    
                Thread.Sleep(50);
    
                Reset.Write(false);
    
                Thread.Sleep(50);
    
                Reset.Write(true);
    
                Thread.Sleep(50);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.SWRESET); // software reset
    
                Thread.Sleep(150);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.SLPOUT);  // out of sleep mode
    
                Thread.Sleep(255);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.FRMCTR1);  // frame rate control - normal mode
    
                DataCommand.Write(Data);
    
                Write(0x01);  // frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
    
                Write(0x2C);
    
                Write(0x2D);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.FRMCTR2);  // frame rate control - idle mode
    
                DataCommand.Write(Data);
    
                Write(0x01);  // frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
    
                Write(0x2C);
    
                Write(0x2D);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.FRMCTR3);  // frame rate control - partial mode
    
                DataCommand.Write(Data);
    
                Write(0x01); // dot inversion mode
    
                Write(0x2C);
    
                Write(0x2D);
    
                Write(0x01); // line inversion mode
    
                Write(0x2C);
    
                Write(0x2D);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.INVCTR);  // display inversion control
    
                DataCommand.Write(Data);
    
                Write(0x07);  // no inversion
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.PWCTR1);  // power control
    
                DataCommand.Write(Data);
    
                Write(0xA2);
    
                Write(0x02);      // -4.6V
    
                Write(0x84);      // AUTO mode
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.PWCTR2);  // power control
    
                DataCommand.Write(Data);
    
                Write(0xC5);      // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.PWCTR3);  // power control
    
                DataCommand.Write(Data);
    
                Write(0x0A);      // Opamp current small 
    
                Write(0x00);      // Boost frequency
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.PWCTR4);  // power control
    
                DataCommand.Write(Data);
    
                Write(0x8A);      // BCLK/2, Opamp current small & Medium low
    
                Write(0x2A);
    
    
    
                Write((byte)LcdCommand.PWCTR5);  // power control
    
                DataCommand.Write(Data);
    
                Write(0x8A);
    
                Write(0xEE);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.VMCTR1);  // power control
    
                DataCommand.Write(Data);
    
                Write(0x0E);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.INVOFF);    // don't invert display
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.MADCTL);  // memory access control (directions)
    
                DataCommand.Write(Data);
    
                Write(0xC8);  // row address/col address, bottom to top refresh
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.COLMOD);  // set color mode
    
                DataCommand.Write(Data);
    
                Write(0x05);        // 16-bit color
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.CASET);  // column addr set
    
                DataCommand.Write(Data);
    
                Write(0x00);
    
                Write(0x00);   // XSTART = 0
    
                Write(0x00);
    
                Write(0x7F);   // XEND = 127
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.RASET);  // row addr set
    
                DataCommand.Write(Data);
    
                Write(0x00);
    
                Write(0x00);    // XSTART = 0
    
                Write(0x00);
    
                Write(0x9F);    // XEND = 159
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.GMCTRP1);
    
                DataCommand.Write(Data);
    
                Write(0x02);
    
                Write(0x1c);
    
                Write(0x07);
    
                Write(0x12);
    
                Write(0x37);
    
                Write(0x32);
    
                Write(0x29);
    
                Write(0x2d);
    
                Write(0x29);
    
                Write(0x25);
    
                Write(0x2B);
    
                Write(0x39);
    
                Write(0x00);
    
                Write(0x01);
    
                Write(0x03);
    
                Write(0x10);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.GMCTRN1);
    
                DataCommand.Write(Data);
    
                Write(0x03);
    
                Write(0x1d);
    
                Write(0x07);
    
                Write(0x06);
    
                Write(0x2E);
    
                Write(0x2C);
    
                Write(0x29);
    
                Write(0x2D);
    
                Write(0x2E);
    
                Write(0x2E);
    
                Write(0x37);
    
                Write(0x3F);
    
                Write(0x00);
    
                Write(0x00);
    
                Write(0x02);
    
                Write(0x10);
    
    
    
    
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.NORON);  // normal display on
    
                Thread.Sleep(10);
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.DISPON);
    
                Thread.Sleep(100);
    
    
    
                //SetAddressWindow(0, 0, (byte)(Width - 1), (byte)(Height - 1));
    
                //SetAddressWindow(0, 0, Width - 1, Height - 1);
    
    
    
                DataCommand.Write(Data);
    
    
    
            }
    
    
    
        
    
    
    
            private ScreenOrientation _orientation = ScreenOrientation.Portrait;
    
    
    
            public ScreenOrientation Orientation
    
            {
    
                get
    
                {
    
                    return _orientation;
    
                }
    
                set
    
                {
    
                    _orientation = value;
    
                    DataCommand.Write(Command);
    
                    Write((byte)LcdCommand.MADCTL);
    
                    DataCommand.Write(Data);
    
                    Write((byte)_orientation);
    
    
    
                    if (_orientation == ScreenOrientation.Portrait)
    
                    {
    
                        Width = 128;
    
                        Height = 160;
    
                    }
    
                    else
    
                    {
    
                        Width = 160;
    
                        Height = 128;
    
                    }
    
    
    
                    SetAddressWindow(0, 0, (byte)(Width - 1), (byte)(Height - 1));
    
                }
    
            }
    
    
    
            private void SetAddressWindow(byte x0, byte y0, byte x1, byte y1)
    
            {
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.CASET);  // column addr set
    
                DataCommand.Write(Data);
    
                Write(0x00);
    
                Write((byte)(x0 + 1));   // XSTART 
    
                Write(0x00);
    
                Write((byte)(x1 + 1));   // XEND
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.RASET);  // row addr set
    
                DataCommand.Write(Data);
    
                Write(0x00);
    
                Write((byte)(y0 + 2));    // YSTART
    
                Write(0x00);
    
                Write((byte)(y1 + 2));    // YEND
    
    
    
                DataCommand.Write(Command);
    
                Write((byte)LcdCommand.RAMWR);  // write to RAM
    
    
    
                DataCommand.Write(Data);
    
            }
    
    
    
            private void SetPixel(int x, int y, ushort color)
    
            {
    
                if ((x < 0) || (x >= Width) || (y < 0) || (y >= Height)) return;
    
                var index = ((y * Width) + x) * sizeof(ushort);
    
                MemoryWriteFunction(index, (byte)(color >> 8));
    
                MemoryWriteFunction(++index, (byte)(color));
    
                //if ((x < 0) || (x >= Width) || (y < 0) || (y >= Height)) return;
    
                //var index = ((y * Width) + x) * sizeof(ushort);
    
                //SpiBuffer[index] = (byte)(color >> 8);
    
                //SpiBuffer[++index] = (byte)(color);
    
            }
    
    
    
            private const bool Data = true;
    
            private const bool Command = false;
    
    
    
            protected void Write(byte Byte)
    
            {
    
                SpiBOneByteBuffer[0] = Byte;
    
                Spi.Write(SpiBOneByteBuffer);
    
            }
    
    
    
            private void Swap(ref int a, ref int b)
    
            {
    
                var t = a; a = b; b = t;
    
            }
    
    
    
            protected void VirtualMemoryWrite(long address, byte data)
    
            {
    
                VM.WriteVM(address, data);
    
            }
    
    
    
            protected void SpiBufferWrite(long address, byte data)
    
            {
    
                SpiBuffer[address] = data;
    
            }
    
    
    
            public byte[] SpiBuffer;
    
            public VirtualMemory VM;
    
            protected readonly byte[] SpiBOneByteBuffer = new byte[1];
    
            protected OutputPort DataCommand;
    
            protected OutputPort Reset;
    
            protected SPI Spi;
    
            protected MemoryWrite MemoryWriteFunction;
    
    
    
            protected delegate void MemoryWrite(long address, byte data);
    
        }
    
        public enum ScreenOrientation
    
        {
    
            Portrait = 0xC8,
    
            Landscape = 0x68
    
        }
    
    }
    
    
    
    

     

     

  • VirtualMemory.cs

  • 用于将数据汇聚到虚拟内存中,统一写入

  •  

    using System;
    
    using System.IO;
    
    using Microsoft.SPOT;
    
    
    
    namespace ST7735TFT
    
    {
    
        public class VirtualMemory : IDisposable
    
        {
    
            public byte[] Buffer;
    
            public FileStream Stream;
    
            public bool IsReadOnly { get; set; }
    
    
    
            public VirtualMemory(long capacityInBytes, int segments, string path)
    
            {
    
                IsReadOnly = false;
    
                if (segments <= 0) throw new ArgumentOutOfRangeException("bufferSize");
    
                Buffer = new byte[capacityInBytes / segments];
    
                Stream = new FileStream(path, FileMode.OpenOrCreate);
    
                if (Stream.Length == 0)
    
                {
    
                    Stream.SetLength(capacityInBytes);
    
                }
    
            }
    
    
    
            public void WriteVM(long address, byte data, SeekOrigin origin = SeekOrigin.Begin)
    
            {
    
                if (IsReadOnly) throw new InvalidOperationException("readonly");
    
                if (address > Stream.Length) throw new ArgumentOutOfRangeException("address");
    
                Stream.Seek(address, origin);
    
                Stream.WriteByte(data);
    
            }
    
            public void WriteVM(long address, byte[] data, int byteCount = 0, SeekOrigin origin = SeekOrigin.Begin)
    
            {
    
                if (IsReadOnly) throw new InvalidOperationException("readonly");
    
                Stream.Seek(address, origin);
    
                if (byteCount == 0)
    
                {
    
                    if (address + data.Length > Stream.Length) throw new ArgumentOutOfRangeException("address");
    
                    Stream.Write(data, 0, data.Length);
    
                }
    
                else
    
                {
    
                    if (address + byteCount > Stream.Length) throw new ArgumentOutOfRangeException("address");
    
                    Stream.Write(data, 0, byteCount);
    
                }
    
            }
    
    
    
            public byte ReadVM(long address, SeekOrigin origin = SeekOrigin.Begin)
    
            {
    
                Stream.Seek(address, origin);
    
                return (byte)Stream.ReadByte();
    
            }
    
            public int ReadVM(long address, int offsetInbuffer, int readBytecount = 0, SeekOrigin origin = SeekOrigin.Begin)
    
            {
    
                Stream.Seek(address, origin);
    
                if (readBytecount == 0)
    
                {
    
                    return Stream.Read(Buffer, 0, Buffer.Length);
    
                }
    
                else
    
                {
    
                    if (readBytecount > Buffer.Length) throw new ArgumentOutOfRangeException("readBytecount");
    
                    return Stream.Read(Buffer, offsetInbuffer, readBytecount);
    
                }
    
            }
    
    
    
            public void FillFromBuffer()
    
            {
    
                if (IsReadOnly) throw new InvalidOperationException("readonly");
    
                var address = 0;
    
                while (address < Stream.Length)
    
                {
    
                    WriteVM(address, Buffer);
    
                    address += Buffer.Length;
    
                }
    
            }
    
    
    
            public void ConnectExistingStream(string path, bool readOnly = true)
    
            {
    
                Stream.Dispose();
    
                Stream = null;
    
                Debug.GC(true);
    
                Stream = new FileStream(path, FileMode.Open);
    
                IsReadOnly = readOnly;
    
            }
    
    
    
            public void RedefineBufferSize(int bufferSize)
    
            {
    
                Buffer = null;
    
                Debug.GC(true);
    
                Buffer = new byte[bufferSize];
    
            }
    
    
    
            public virtual void Copy(VirtualMemory source)
    
            {
    
                if (IsReadOnly) throw new InvalidOperationException("readonly");
    
                var address = 0;
    
                Stream.SetLength(source.Stream.Length);
    
                while (address < source.Stream.Length)
    
                {
    
                    var sourceBytesRead = source.ReadVM(address, 0);
    
                    WriteVM(address, source.Buffer, sourceBytesRead);
    
                    address += sourceBytesRead;
    
                }
    
            }
    
    
    
            public void Dispose()
    
            {
    
                Buffer = null;
    
                Stream.Close();
    
                Stream.Dispose();
    
                Stream = null;
    
                Debug.GC(true);
    
            }
    
        }
    
    }
    
    

     

     

  • Program.cs

  • 背光板接到GPIO_PIN_D1,初始需要设置为true,这样表示显示背光,为啥这样这是我调试的经验,原因未知

  • static OutputPort p1 = new OutputPort(Pins.GPIO_PIN_D1, true);

  • 文件里的代码如下:

  •  

    #define NETDUINO
    
    
    
    using System;
    
    using System.IO;
    
    using System.Threading;
    
    using Microsoft.SPOT.Hardware;
    
    using SecretLabs.NETMF.IO;
    
    using SecretLabs.NETMF.Hardware;
    
    using SecretLabs.NETMF.Hardware.Netduino;
    
    
    
    
    
    namespace ST7735TFT
    
    {
    
        public class Program
    
        {
    
            //public static ST7735TFT tft = new ST7735TFT(Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D7, Pins.GPIO_PIN_D8, speedKHz: 40000);
    
            static OutputPort p1 = new OutputPort(Pins.GPIO_PIN_D1, true);
    
            public static ST7735TFT tft = new ST7735TFT(Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D7, Pins.GPIO_PIN_D8, speedKHz: 40000);
    
            public static void Main()
    
            {
    
                //DisplayPicture();
    
                
    
                //tft.AutoRefreshScreen = true;
    
                //p1.Write(false);
    
                while (true)
    
                {
    
                    tft.ClearScreen();
    
                    //DisplayGradient();
    
                    tft.DrawCircle(70, 70, 30, (ushort)ST7735TFT.Colors.Red);
    
                    Thread.Sleep(500);
    
                    //DisplayCircles();
    
                    //DisplayColorFlow();
    
                    //tft.ClearScreen();
    
                    //DisplayLines();
    
                }
    
    
    
            }
    
    
    
            public static void DisplayColorFlow()
    
            {
    
    #if NETDUINO_MINI
    
                StorageDevice.MountSD("SD", SPI.SPI_module.SPI1, Pins.GPIO_PIN_13);
    
    #else
    
                StorageDevice.MountSD("SD", SPI.SPI_module.SPI1, Pins.GPIO_PIN_D10);
    
    #endif
    
                while (true)
    
                {
    
                    ReadPicture(@"SD\Pictures\ColorFlow1.bmp.24.bin", 0);
    
                    ReadPicture(@"SD\Pictures\ColorFlow2.bmp.24.bin", 0);
    
                    ReadPicture(@"SD\Pictures\ColorFlow3.bmp.24.bin", 0);
    
                    ReadPicture(@"SD\Pictures\ColorFlow4.bmp.24.bin", 0);
    
                }
    
            }
    
    
    
            public static void DisplayPicture()
    
            {
    
    #if NETDUINO_MINI
    
                StorageDevice.MountSD("SD", SPI.SPI_module.SPI1, Pins.GPIO_PIN_13);
    
    #else
    
                StorageDevice.MountSD("SD", SPI.SPI_module.SPI1, Pins.GPIO_PIN_D10);
    
    #endif
    
                ReadPicture(@"SD\Pictures\spaceneedle.bmp.24.bin");
    
                ReadPicture(@"SD\Pictures\spaceneedleclose.bmp.24.bin");
    
                ReadPicture(@"SD\Pictures\spaceneedlesunset.bmp.24.bin");
    
                ReadPicture(@"SD\Pictures\spaceneedleatnight.bmp.24.bin");
    
    
    
                StorageDevice.Unmount("SD");
    
            }
    
    
    
            public static void ReadPicture(string filename, int delay = 1000)
    
            {
    
                using (var filestream = new FileStream(filename, FileMode.Open))
    
                {
    
                    filestream.Read(tft.SpiBuffer, 0, tft.SpiBuffer.Length);
    
                    tft.Refresh();
    
                    Thread.Sleep(delay);
    
                }
    
            }
    
    
    
            public static void DisplayLines()
    
            {
    
                byte red = 20;
    
                byte green = 1;
    
                byte blue = 5;
    
                var y = 0;
    
    
    
                for (; y < tft.Height; y++)
    
                {
    
                    red += 2;
    
                    green++;
    
                    tft.DrawLine(0, 0, tft.Width, y, tft.GetRGBColor(red, green, blue));
    
                    tft.Refresh();
    
                }
    
    
    
                red = 20;
    
                green = 1;
    
                blue = 5;
    
                for (; y >= 0; y--)
    
                {
    
                    red += 2;
    
                    green++;
    
                    tft.DrawLine(tft.Width - 1, tft.Height - 1, 0, y, tft.GetRGBColor(red, green, blue));
    
                    tft.Refresh();
    
                }
    
            }
    
    
    
            public static void DisplayCircles()
    
            {
    
                var xHalf = tft.Width / 2;
    
                var yHalf = tft.Height / 2;
    
                byte red = 1;
    
                byte green = 1;
    
                byte blue = 1;
    
    
    
                for (var r = 1; r < xHalf; r += 2)
    
                {
    
                    var color = tft.GetRGBColor(red, green, blue);
    
                    tft.DrawCircle(xHalf, yHalf, r, color);
    
                    red += 3;
    
                    green += 2;
    
                    blue += 1;
    
                    tft.Refresh();
    
                }
    
    
    
                Thread.Sleep(1000);
    
    
    
                for (var I = 0; I < 2; I++)
    
                {
    
                    var r = 1;
    
                    for (; r < xHalf; r += 2)
    
                    {
    
                        tft.DrawCircle(xHalf, yHalf, r, (ushort)ST7735TFT.Colors.White);
    
                        tft.Refresh();
    
                        tft.DrawCircle(xHalf, yHalf, r, (ushort)ST7735TFT.Colors.Black);
    
                    }
    
                    for (; r > 1; r -= 2)
    
                    {
    
                        tft.DrawCircle(xHalf, yHalf, r, (ushort)ST7735TFT.Colors.White);
    
                        tft.Refresh();
    
                        tft.DrawCircle(xHalf, yHalf, r, (ushort)ST7735TFT.Colors.Black);
    
                    }
    
                }
    
    
    
                Thread.Sleep(1000);
    
            }
    
    
    
            public static void DisplayGradient()
    
            {
    
                var x = 0;
    
                var y = 0;
    
    
    
                while (y < tft.Height)
    
                {
    
                    byte red = 1;
    
                    for (; red < 32; red += 3)
    
                    {
    
                        byte green = 1;
    
                        for (; green < 33; green += 2)
    
                        {
    
                            byte blue = 1;
    
                            for (; blue < 32; blue += 2)
    
                            {
    
                                var color = tft.GetRGBColor(red, green, blue);
    
    
    
                                tft.DrawPixel(x++, y, color);
    
    
    
                                if (x >= tft.Width)
    
                                {
    
                                    x = 0;
    
                                    y++;
    
                                }
    
                            }
    
                        }
    
                    }
    
                    tft.Refresh();
    
                }
    
            }
    
            public static void draw()
    
            {
    
                tft.DrawLine(0, 0,22, 50, tft.GetRGBColor(1, 255, 36));
    
                tft.Refresh();
    
            }
    
        }
    
    }
    
    


     

     

 

你可能感兴趣的:(net)