好久没写关于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();
    }
    }
    }

TFT ST7735的Netduino驱动的更多相关文章

  1. 今天2.4寸tft触摸屏到手--刷屏驱动小结

    2010-04-29 21:28:00 根据给的51程序改成了iccavr,结果改错了2处.导致我找原因找了n久.不过也是一件好事,让我对80i更加熟悉了. 通过protues的逻辑分析仪,找到了问题 ...

  2. ST7735和ST7789驱动

    /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __LCD_H #de ...

  3. 联盛德 HLK-W806 (四): 软件SPI和硬件SPI驱动ST7735液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  4. esp8266驱动液晶屏

    ESP8266 + 1.44 TFT LCD https://www.joaquim.org/esp8266-wifi-scan/ LCD ILI9341 (320×240). Source Code ...

  5. LCD驱动应该怎么写?–基于stm32F407 [复制链接]

    够用的硬件能用的代码使用的教程 (拷贝过来的代码有点乱,请下载附件查看文档) 资料下载地址:https://pan.baidu.com/s/1bHUVe6X6tymktUHk_z91cA 网络上配套S ...

  6. [转载]AMOLED结构详解,BOE专家给你分析驱动补偿

    关键词: AMOLED, 驱动补偿 有机发光显示二极管(OLED)作为一种电流型发光器件已越来越多地被应用于高性能显示中.由于它自发光的特性,与LCD相比,AMOLED具有高对比度.超轻薄.可弯曲等诸 ...

  7. 【iCore3双核心板】【4.3寸液晶驱动板爆照!】

     [源代码完全开源,过几天连同硬件一起发布] 花了好久的时间,我们的fpga工程师才完成这液晶模块的驱动代码,其核心价值如下: 1.完全基于fpga驱动,sdram当做缓存: 2.内建双缓冲机制:方便 ...

  8. (四)esp8266 MDNS域名服务

    (实例一)ESP8266 TFT(ST7735)彩屏-web刷图 https://www.arduino.cn/thread-42247-1-1.html (实例二) 自己当AP时建立MDNS域名 h ...

  9. 使用Arduino驱动基于ST7533芯片的TFT屏

    在合宙通信买了一个1.8寸的TFT屏,驱动芯片是ST7533,本来打算使用Air800直接驱动,但由于其他原因,放弃了.于是尝试使用arduino驱动,为了屏幕刷新速度更快,采用硬件SPI. 硬件连接 ...

随机推荐

  1. Linux vsftpd服务配置具体解释

    [背景] 近日.一朋友dominoserver要进行升级.迁移,搭建了linux測试系统,也开启vsftpd服务,但是配置的ftp账号,程序无法正常下载附件. [问题跟踪] 通过ftpclient连接 ...

  2. UVA 10312 - Expression Bracketing(数论+Catalan数)

    题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=1253">10312 - Exp ...

  3. Chrome插件Visual Event查看Dom元素绑定事件的利器

    找这工具找了好久,统一找着了,开发人员不可多得的好东东,收藏做一下分享. 用Chrome插件Visual Event查看Dom绑定的事件 Visual Event简介 Visual Event是一个开 ...

  4. Linux下Apache服务器并发优化

     Linux/UnixLinux系统下Apache 并发数的优化 Apache Http服务器采用prefork或者是worker两种并发控制模式. preforkMPM 使用多个子进程,每个子进程只 ...

  5. The Power of Reading——英语学习小技巧之七

    This method is "The Power of Reading" and it comes from an article by Dr.Stephen Krashen. ...

  6. json格式字符串与java.util.Map的互转(借助于jackson.jar)

    package com.test.javaAPI.json; /** * json工具类 * * @author Wei * @time 2016年10月2日 下午4:25:25 */ public ...

  7. 如何在Eclipse中配置Tomcat(免安装版)

    如何在Eclipse中配置Tomcat(免安装版) 2013-10-09 23:19wgelgrsh | 分类:JAVA相关 | 浏览642次 分享到:   2013-10-10 17:10提问者采纳 ...

  8. BZOJ 1614: [Usaco2007 Jan]Telephone Lines架设电话线

    题目 1614: [Usaco2007 Jan]Telephone Lines架设电话线 Time Limit: 5 Sec  Memory Limit: 64 MB Description Farm ...

  9. UI常用控件的一些属性

    UILable 1 //设置文本信息 2 nameLable.text = @"用户名:"; 3 //对齐方式(居中 居左 局右); 4 nameLable.textAlignme ...

  10. STL vector使用方法介绍

    介绍 这篇文章的目的是为了介绍std::vector,怎样恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...