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 inversionDataCommand.Write(Command);
Write((byte)LcdCommand.PWCTR1); // power control
DataCommand.Write(Data);
Write(0xA2);
Write(0x02); // -4.6V
Write(0x84); // AUTO modeDataCommand.Write(Command);
Write((byte)LcdCommand.PWCTR2); // power control
DataCommand.Write(Data);
Write(0xC5); // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDDDataCommand.Write(Command);
Write((byte)LcdCommand.PWCTR3); // power control
DataCommand.Write(Data);
Write(0x0A); // Opamp current small
Write(0x00); // Boost frequencyDataCommand.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 displayDataCommand.Write(Command);
Write((byte)LcdCommand.MADCTL); // memory access control (directions)
DataCommand.Write(Data);
Write(0xC8); // row address/col address, bottom to top refreshDataCommand.Write(Command);
Write((byte)LcdCommand.COLMOD); // set color mode
DataCommand.Write(Data);
Write(0x05); // 16-bit colorDataCommand.Write(Command);
Write((byte)LcdCommand.CASET); // column addr set
DataCommand.Write(Data);
Write(0x00);
Write(0x00); // XSTART = 0
Write(0x00);
Write(0x7F); // XEND = 127DataCommand.Write(Command);
Write((byte)LcdCommand.RASET); // row addr set
DataCommand.Write(Data);
Write(0x00);
Write(0x00); // XSTART = 0
Write(0x00);
Write(0x9F); // XEND = 159DataCommand.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驱动的更多相关文章
- 今天2.4寸tft触摸屏到手--刷屏驱动小结
2010-04-29 21:28:00 根据给的51程序改成了iccavr,结果改错了2处.导致我找原因找了n久.不过也是一件好事,让我对80i更加熟悉了. 通过protues的逻辑分析仪,找到了问题 ...
- ST7735和ST7789驱动
/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __LCD_H #de ...
- 联盛德 HLK-W806 (四): 软件SPI和硬件SPI驱动ST7735液晶LCD
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- esp8266驱动液晶屏
ESP8266 + 1.44 TFT LCD https://www.joaquim.org/esp8266-wifi-scan/ LCD ILI9341 (320×240). Source Code ...
- LCD驱动应该怎么写?–基于stm32F407 [复制链接]
够用的硬件能用的代码使用的教程 (拷贝过来的代码有点乱,请下载附件查看文档) 资料下载地址:https://pan.baidu.com/s/1bHUVe6X6tymktUHk_z91cA 网络上配套S ...
- [转载]AMOLED结构详解,BOE专家给你分析驱动补偿
关键词: AMOLED, 驱动补偿 有机发光显示二极管(OLED)作为一种电流型发光器件已越来越多地被应用于高性能显示中.由于它自发光的特性,与LCD相比,AMOLED具有高对比度.超轻薄.可弯曲等诸 ...
- 【iCore3双核心板】【4.3寸液晶驱动板爆照!】
[源代码完全开源,过几天连同硬件一起发布] 花了好久的时间,我们的fpga工程师才完成这液晶模块的驱动代码,其核心价值如下: 1.完全基于fpga驱动,sdram当做缓存: 2.内建双缓冲机制:方便 ...
- (四)esp8266 MDNS域名服务
(实例一)ESP8266 TFT(ST7735)彩屏-web刷图 https://www.arduino.cn/thread-42247-1-1.html (实例二) 自己当AP时建立MDNS域名 h ...
- 使用Arduino驱动基于ST7533芯片的TFT屏
在合宙通信买了一个1.8寸的TFT屏,驱动芯片是ST7533,本来打算使用Air800直接驱动,但由于其他原因,放弃了.于是尝试使用arduino驱动,为了屏幕刷新速度更快,采用硬件SPI. 硬件连接 ...
随机推荐
- CSS一些设置用法
今天就简单写点的知识点 1. CSS字体样式小结 1) text-indent :值 实现段落首行缩进功能 (在起初我们编写段落时为了实现首行缩进两个字符时用的是HTML的标签元素&nb ...
- 「C」关键字、标识符、注释、内存分析、数据、常量、变量
一.关键字 C语言提供的有特殊含义的符号,共32个. 一般在Xcode中关键字全部显示紫褐色,关键字全部都为小写.如int.return等. 二.标识符 标识符是程序员在程序中自定义的一些符号和名称. ...
- [LeetCode]题解(python):008-String to Integer (atoi)
题目来源: https://leetcode.com/problems/string-to-integer-atoi/ 题意分析: 这道题也是简单题,题目意思是要将字符串转化成int.比如‘123’转 ...
- struts jsp传值到action,乱码的解决方案
使用了Struts框架,前台写好了编码为utf-8 <%@ page language="java" contentType="text/html; charset ...
- vagrant 入门2
创建第一个Vagrant虚拟环境以及工程: (1)创建工程目录, 并且执行vagrant init命令,该命令会产生最初的 Vagrantfile $ mkdir vagrant_guide $ cd ...
- poj 1905 Expanding Rods 二分
/** 题解晚上写 **/ #include <iostream> #include <math.h> #include <algorithm> #include ...
- ioctl函数详细说明
本函数影响由fd 参数引用的一个打开的文件. #include<unistd.h> int ioctl( int fd, int request, .../* void *arg */ ) ...
- 转:按需加载html 图片 css js
按需加载是前端性能优化中的一项重要措施,按需加载是如何定义的呢?顾名思义,指的是当用户触发了动作时才加载对应的功能.触发的动作,是要看具体的业务场景而言,包括但不限于以下几个情况:鼠标点击.输入文字. ...
- vs2010 调试 调用堆栈 窗口
msdn 如何使用call stack窗口: http://msdn.microsoft.com/zh-cn/library/a3694ts5(v=vs.90).aspx 使用“调用堆栈”窗口可以查看 ...
- STL vector使用方法介绍
介绍 这篇文章的目的是为了介绍std::vector,怎样恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...