网站建设要用到的技术有哪些,做外贸没网站可以吗,企业办公自动化管理系统,如何建立自己的手机网站老五家2.8寸屏#xff0c;3线SPI驱动 前言 要知道屏幕的驱动芯片都小的惊人#xff0c;想必是不会打上丝印的。从几百个引脚中判断哪个是哪个#xff0c;想想就晕。 大佬们都太厉害了#xff0c;看看PFC就知道屏幕的接线定义。一直好奇这种神技是怎么练成的。也尝试自己来… 老五家2.8寸屏3线SPI驱动 前言 要知道屏幕的驱动芯片都小的惊人想必是不会打上丝印的。从几百个引脚中判断哪个是哪个想想就晕。 大佬们都太厉害了看看PFC就知道屏幕的接线定义。一直好奇这种神技是怎么练成的。也尝试自己来猜定义但发现实在太难还是拿来主义等着引脚定义比较靠谱。 本文用的屏是2.8寸TFT屏驱动芯片是HX8347定义早被大佬识破 定义有了。但不巧[IM3~0]1100只能支持3线SPIRGB。RGB屏不是单片机的强项。好像STM32F7XX和ESP32 S3是支持RGB但也只是好像这两都价格不菲手头也没有。 还是想办法用3线SPI来驱动吧。 一、源码
HX8347.h
#ifndef USER_HX8347_H_
#define USER_HX8347_H_#define X_MAX_PIXEL 240
#define Y_MAX_PIXEL 320#define RED 0xf800
#define GREEN 0x07e0
#define BLUE 0x001f
#define WHITE 0xffff
#define BLACK 0x0000
#define YELLOW 0xFFE0
#define GRAY0 0xEF7D //灰色0 3165 00110 001011 00101
#define GRAY1 0x8410 //灰色1 00000 000000 00000
#define GRAY2 0x4208 //灰色2 1111111111011111#define LCD_CS GPIO_Pin_0 // CS:PA0
#define LCD_SDA GPIO_Pin_1 // SDA:PA1
#define LCD_SCL GPIO_Pin_3 // SCL:PA3
#define LCD_RST GPIO_Pin_4 // RST:PA4#define LCD_SCL_SET GPIO_WriteBit(GPIOA, LCD_SCL,Bit_SET)
#define LCD_SDA_SET GPIO_WriteBit(GPIOA, LCD_SDA,Bit_SET)
#define LCD_CS_SET GPIO_WriteBit(GPIOA, LCD_CS,Bit_SET)
#define LCD_RST_SET GPIO_WriteBit(GPIOA, LCD_RST,Bit_SET)#define LCD_SCL_CLR GPIO_WriteBit(GPIOA, LCD_SCL,Bit_RESET)
#define LCD_SDA_CLR GPIO_WriteBit(GPIOA, LCD_SDA,Bit_RESET)
#define LCD_CS_CLR GPIO_WriteBit(GPIOA, LCD_CS,Bit_RESET)
#define LCD_RST_CLR GPIO_WriteBit(GPIOA, LCD_RST,Bit_RESET)void LCD_GPIO_Init(void);
void Lcd_WriteIndex(unsigned char Index);
void Lcd_WriteData(unsigned char Data);
void LCD_WriteData_16Bit(unsigned int Data);
void Lcd_Write_REG(unsigned char Index,unsigned char Data);
void LCD_Init(void);
void Lcd_Clear(unsigned int Color);
void FillRect(u16 x1, u16 y1, u16 x2, u16 y2, u16 color);#endif /* USER_HX8347_H_ */HX8347.c
#include debug.h
#include HX8347.hvoid LCD_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure {0};RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin LCD_SCL|LCD_SDA|LCD_CS|LCD_RST;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure);
}//向SPI总线传输一个8位数据
void SPI_WriteData(unsigned char Data)
{unsigned char i0;for(i8;i0;i--){if(Data0x80)LCD_SDA_SET; //输出数据else LCD_SDA_CLR;LCD_SCL_CLR;LCD_SCL_SET;Data1;}
}//向液晶屏写一个8位指令
void Lcd_WriteIndex(unsigned char Index)
{//SPI 写命令时序开始LCD_CS_CLR;SPI_WriteData(0x70);SPI_WriteData(Index);LCD_CS_SET;
}//向液晶屏写一个8位数据
void Lcd_WriteData(unsigned char Data)
{LCD_CS_CLR;SPI_WriteData(0x72);SPI_WriteData(Data);LCD_CS_SET;
}//向液晶屏写一个16位数据
void LCD_WriteData_16Bit(unsigned int Data)
{LCD_CS_CLR;SPI_WriteData(0x72);SPI_WriteData(Data8);SPI_WriteData(Data);LCD_CS_SET;
}void Lcd_Write_REG(unsigned char Index,unsigned char Data)
{Lcd_WriteIndex(Index);Lcd_WriteData(Data);
}void Lcd_Reset(void)
{unsigned int i;LCD_RST_CLR;for(i0;i6000;i);LCD_RST_SET;for(i0;i6000;i);
}// set region to paint
void LCD_SetWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{//SCLcd_Write_REG(0x02,x18); // Column address start2Lcd_Write_REG(0x03,(u8)x1); // Column address start1//ECLcd_Write_REG(0x04,x28); // Column address end2Lcd_Write_REG(0x05,(u8)x2); // Column address end1//SPLcd_Write_REG(0x06,y18); // Row address start2Lcd_Write_REG(0x07,(u8)y1); // Row address start1//EPLcd_Write_REG(0x08,y28); // Row address end2Lcd_Write_REG(0x09,(u8)y2); // Row address end1//写0x22到index register那么下次send data就会直接被写到graphic ramLcd_WriteIndex(0x22);
}void FillRect(u16 x1, u16 y1, u16 x2, u16 y2, u16 color)
{LCD_SetWindow(x1, y1,x2,y2);x2 x2 - x1 1;y2 y2 - y1 1;for(x1 x2; x1 ! 0 ; x1--){for (y1 y2;y1 ! 0 ;y1--){LCD_WriteData_16Bit(color);}}
}void LCD_Init(void)
{LCD_GPIO_Init();Lcd_Reset();Lcd_Write_REG(0x18,0x88); //UADJ 75HzLcd_Write_REG(0x19,0x01); //OSC_EN1, start Osc//Power Voltage SettingLcd_Write_REG(0x1B,0x1E); //VRH4.60VLcd_Write_REG(0x1C,0x07); //AP Crosstalk 04Lcd_Write_REG(0x1A,0x01); //BT (VGH~15V,VGL~-10V,DDVDH~5V)Lcd_Write_REG(0x24,0x38); //VMH 27Lcd_Write_REG(0x25,0x5F); //VML//VCOM offsetLcd_Write_REG(0x23,0x8C); //for Flicker adjustLcd_Write_REG(0x1F,0x88);// GAS1, VOMG00, PON0, DK1, XDK0, DVDH_TRI0, STB0Delay_Ms(5);Lcd_Write_REG(0x1F,0x80);// GAS1, VOMG00, PON0, DK0, XDK0, DVDH_TRI0, STB0Delay_Ms(5);Lcd_Write_REG(0x1F,0x90);// GAS1, VOMG00, PON1, DK0, XDK0, DVDH_TRI0, STB0Delay_Ms(5);Lcd_Write_REG(0x1F,0xD0);// GAS1, VOMG10, PON1, DK0, XDK0, DDVDH_TRI0, STB0Delay_Ms(5);//Display ON SettingLcd_Write_REG(0x28,0x38); //GON1, DTE1, D1000Delay_Ms(40);Lcd_Write_REG(0x28,0x3C); //GON1, DTE1, D1100Lcd_Write_REG(0x36,0x09); //REV, BGRLcd_Write_REG(0x17,0x05); //16BIT/PIXEL//Gamma 2.2 SettingLcd_Write_REG(0x40,0x00); //Lcd_Write_REG(0x41,0x00); //Lcd_Write_REG(0x42,0x00); //Lcd_Write_REG(0x43,0x11); //Lcd_Write_REG(0x44,0x0e); //Lcd_Write_REG(0x45,0x23); //Lcd_Write_REG(0x46,0x08); //Lcd_Write_REG(0x47,0x53); //Lcd_Write_REG(0x48,0x03); //Lcd_Write_REG(0x49,0x11); //Lcd_Write_REG(0x4A,0x18); //Lcd_Write_REG(0x4B,0x1a); //Lcd_Write_REG(0x4C,0x16); //Lcd_Write_REG(0x50,0x1c); //Lcd_Write_REG(0x51,0x31); //Lcd_Write_REG(0x52,0x2e); //Lcd_Write_REG(0x53,0x3f); //Lcd_Write_REG(0x54,0x3f); //Lcd_Write_REG(0x55,0x3f); //Lcd_Write_REG(0x56,0x2c); //Lcd_Write_REG(0x57,0x77); //Lcd_Write_REG(0x58,0x09); //Lcd_Write_REG(0x59,0x05); //Lcd_Write_REG(0x5A,0x07); //Lcd_Write_REG(0x5B,0x0e); //Lcd_Write_REG(0x5C,0x1c); //Lcd_Write_REG(0x5D,0x88); //Delay_Ms(100);FillRect(0, 160, 239, 239, 0xf800 );
}二、说明 1、LCD初始化是从GITHUB上拷的一段程序具体是啥意思我也不清楚。试过官方数据手册里的初始化程序一直不能成功。
2、写寄存器的程序 void Lcd_WriteIndex(unsigned char Index) { LCD_CS_CLR; SPI_WriteData(0x70); SPI_WriteData(Index); LCD_CS_SET; } 3、写数据的程序 void Lcd_WriteData(unsigned char Data) { LCD_CS_CLR; SPI_WriteData(0x72); SPI_WriteData(Data); LCD_CS_SET; } 上面程序中出现SPI_WriteData(0x70); SPI_WriteData(0x72);统一解释下: 因为是3线SPI所以缺少CD(或RS)引线解决的办法一般是SPI发送数据时第一个bit的值代表CD。这样因为多出了1bit就需要处理9bit的数据。UC1601就是这样但是HX8347不是这样。 下面栽自HX8347的数据手册 大概意思就是在发数据前需要发“01110”[ID][RS][RW]一共是8bit。 这里ID应该取0。RS取0是写寄存器取1是写数据。RW取0表示写。 所以写寄存器就是:011100000x70写数据就是011100100x72。也因此就有了 SPI_WriteData(0x70); SPI_WriteData(0x72);
三、总结
1、主控是沁恒家申请的CH32V307的评估板开发工具是mountriver。不得不说评估板和开发工具都很完美。评估板留有arduino接口可以和arduino扩展板链接。mountriver编译很快下载烧录更快基本都零点几秒。
2、本源码可以添加到CH32V307的demo中CH32V307EVT\EVT\EXAM\GPIO\GPIO_Toggle例程中运行。 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); SystemCoreClockUpdate(); Delay_Init(); LCD_Init(); while(1) { Delay_Ms(1000); FillRect(0, 0, 239, 319, 0x07c0 ); Delay_Ms(1000); FillRect(0, 0, 239, 319, 0x0030 ); Delay_Ms(1000); FillRect(0, 0, 239, 319, 0x0000 ); Delay_Ms(1000); FillRect(0, 0, 239, 319, 0xf800 ); } } 3、如果屏幕没有任何显示可能需要按下评估板的RESET键。
4、用的是软件模拟3线SPI所以帧数很低。以后考虑硬件SPI或再加DMA但DMA需要SRAM太大。 演示用视频