lcd.c
void lcd_init() {
GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE );//PORTA时钟使能 RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );//SPI1时钟使能 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_8|GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_8|GPIO_Pin_15); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_3); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA GPIO_SetBits(GPIOA,GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7); //PB13/14/15上拉 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPI1, ENABLE); //使能SPI外设 // lcd_read_write_byte(0xff);//启动传输 lcd_rst=1; delay_ms(120); lcd_rst=0; delay_ms(120); lcd_rst=1; delay_ms(120); /* Sleep Out */ lcd_write_cmd(0x11); /* wait for power stability */ delay_ms(120); lcd_write_cmd(0x36); lcd_write_data(0x00); lcd_write_cmd(0x3a); lcd_write_data(0x05); //--------------------------------ST7789V Frame rate setting----------------------------------// lcd_write_cmd(0xb2); lcd_write_data(0x0c); lcd_write_data(0x0c); lcd_write_data(0x00); lcd_write_data(0x33); lcd_write_data(0x33); lcd_write_cmd(0xb7); lcd_write_data(0x35); //---------------------------------ST7789V Power setting--------------------------------------// lcd_write_cmd(0xbb); lcd_write_data(0x1c); lcd_write_cmd(0xc0); lcd_write_data(0x2c); lcd_write_cmd(0xc2); lcd_write_data(0x01); lcd_write_cmd(0xc3); lcd_write_data(0x0b); lcd_write_cmd(0xc4); lcd_write_data(0x20); lcd_write_cmd(0xc6); lcd_write_data(0x0f); lcd_write_cmd(0xd0); lcd_write_data(0xa4); lcd_write_data(0xa1); //--------------------------------ST7789V gamma setting---------------------------------------// lcd_write_cmd(0xe0); lcd_write_data(0xd0); lcd_write_data(0x00); lcd_write_data(0x03); lcd_write_data(0x09); lcd_write_data(0x13); lcd_write_data(0x1c); lcd_write_data(0x3a); lcd_write_data(0x55); lcd_write_data(0x48); lcd_write_data(0x18); lcd_write_data(0x12); lcd_write_data(0x0e); lcd_write_data(0x19); lcd_write_data(0x1e); lcd_write_cmd(0xe1); lcd_write_data(0xd0); lcd_write_data(0x00); lcd_write_data(0x03); lcd_write_data(0x09); lcd_write_data(0x05); lcd_write_data(0x25); lcd_write_data(0x3a); lcd_write_data(0x55); lcd_write_data(0x50); lcd_write_data(0x3d); lcd_write_data(0x1c); lcd_write_data(0x1d); lcd_write_data(0x1d); lcd_write_data(0x1e); lcd_write_cmd(0x29); lcd_address_set(0, 0, LCD_Width - 1, LCD_Height - 1); lcd_set_speed(SPI_BaudRatePrescaler_2); open_lcd(); } //SPI 速度设置函数 //SpeedSet: //SPI_BaudRatePrescaler_2 2分频 //SPI_BaudRatePrescaler_8 8分频 //SPI_BaudRatePrescaler_16 16分频 //SPI_BaudRatePrescaler_256 256分频 void lcd_set_speed(u8 SPI_BaudRatePrescaler) {
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); SPI1->CR1&=0XFFC7; SPI1->CR1|=SPI_BaudRatePrescaler; //设置SPI1速度 SPI_Cmd(SPI1,ENABLE); } //SPIx 读写一个字节 //TxData:要写入的字节 //返回值:读取到的字节 u8 lcd_read_write_byte(u8 TxData) {
u8 retry=0; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位 {
retry++; if(retry>200)return 0; } SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据 retry=0; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位 {
retry++; if(retry>200)return 0; } return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据 } / * @brief 写命令到LCD * * @param cmd 需要发送的命令 * * @return void */ void lcd_write_cmd(u8 cmd) {
lcd_dc=0; lcd_cs=0; lcd_read_write_byte(cmd); lcd_cs=1; } / * @brief 写数据到LCD * * @param cmd 需要发送的数据 * * @return void */ void lcd_write_data(u8 data) {
lcd_dc=1; lcd_cs=0; lcd_read_write_byte(data); lcd_cs=1; } / * @brief 写半个字的数据到LCD * * @param cmd 需要发送的数据 * * @return void */ void lcd_write_halfword(const u16 da) {
u8 data[2] = {
0},i=0; data[0] = da >> 8; data[1] = da; lcd_dc=1; lcd_cs=0; for(i=0;i<2;i++) {
lcd_read_write_byte(data[i]); } lcd_cs=1; } / * 设置数据写入LCD缓存区域 * * @param x1,y1 起点坐标 * @param x2,y2 终点坐标 * * @return void */ void lcd_address_set(u16 x1, u16 y1, u16 x2, u16 y2) {
lcd_write_cmd(0x2a); lcd_write_data(x1 >> 8); lcd_write_data(x1); lcd_write_data(x2 >> 8); lcd_write_data(x2); lcd_write_cmd(0x2b); lcd_write_data(y1 >> 8); lcd_write_data(y1); lcd_write_data(y2 >> 8); lcd_write_data(y2); lcd_write_cmd(0x2C); } / * 以一种颜色清空LCD屏 * * @param color 清屏颜色 * * @return void */ void lcd_clear(u16 color) {
unsigned int i; u8 data[2] = {
0}; data[0] = color >> 8; data[1] = color; lcd_address_set(0, 0, LCD_Width - 1, LCD_Height - 1); lcd_dc=1; lcd_cs=0; for(i = 0; i < (LCD_Width*LCD_Height); i++) {
lcd_read_write_byte(data[0]); lcd_read_write_byte(data[1]); } lcd_cs=0; } / * 画点函数 * * @param x,y 画点坐标 * * @return void */ void lcd_draw_point(u16 x, u16 y,u16 pointColor) {
lcd_address_set(x, y, x, y); lcd_write_halfword(pointColor); } / * @brief 画一个圆 * * @param x0,y0 圆心坐标 * @param r 圆半径 * * @return void */ void lcd_draw_circle(u16 x0, u16 y0, u8 r,u16 pointColor) {
int a, b; int di; a = 0; b = r; di = 3 - (r << 1); while(a <= b) {
lcd_draw_point(x0 - b, y0 - a,pointColor); lcd_draw_point(x0 + b, y0 - a,pointColor); lcd_draw_point(x0 - a, y0 + b,pointColor); lcd_draw_point(x0 - b, y0 - a,pointColor); lcd_draw_point(x0 - a, y0 - b,pointColor); lcd_draw_point(x0 + b, y0 + a,pointColor); lcd_draw_point(x0 + a, y0 - b,pointColor); lcd_draw_point(x0 + a, y0 + b,pointColor); lcd_draw_point(x0 - b, y0 + a,pointColor); a++; if(di < 0)di += 4 * a + 6; else {
di += 10 + 4 * (a - b); b--; } lcd_draw_point(x0 + a, y0 + b,pointColor); } } / * @brief 显示一个ASCII码字符 * * @param x,y 显示起始坐标 * @param chr 需要显示的字符 * @param size 字体大小(支持16/24/32号字体) * * @return void */ void lcd_show_char(u16 x, u16 y, char chr, u8 size,u16 pointColor,u16 backColor) {
u8 temp, t1, t; u8 csize; //得到字体一个字符对应点阵集所占的字节数 u16 colortemp; u8 sta; chr = chr - ' '; //得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库) if((x > (LCD_Width - size / 2)) || (y > (LCD_Height - size))) return; lcd_address_set(x, y, x + size / 2 - 1, y + size - 1);//(x,y,x+8-1,y+16-1) if((size == 16) || (size == 32) ) //16和32号字体 {
csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); for(t = 0; t < csize; t++) {
if(size == 16)temp = asc2_1608[chr][t]; //调用1608字体 else if(size == 32)temp = asc2_3216[chr][t]; //调用3216字体 else return; //没有的字库 for(t1 = 0; t1 < 8; t1++) {
if(temp & 0x80) colortemp = pointColor; else colortemp = backColor; lcd_write_halfword(colortemp); temp <<= 1; } } } else if (size == 12) //12号字体 {
csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); for(t = 0; t < csize; t++) {
temp = asc2_1206[chr][t]; for(t1 = 0; t1 < 6; t1++) {
if(temp & 0x80) colortemp = pointColor; else colortemp = backColor; lcd_write_halfword(colortemp); temp <<= 1; } } } else if(size == 24) //24号字体 {
csize = (size * 16) / 8; for(t = 0; t < csize; t++) {
temp = asc2_2412[chr][t]; if(t % 2 == 0)sta = 8; else sta = 4; for(t1 = 0; t1 < sta; t1++) {
if(temp & 0x80) colortemp = pointColor; else colortemp = backColor; lcd_write_halfword(colortemp); temp <<= 1; } } } } / * @brief 显示字符串 * * @param x,y 起点坐标 * @param width 字符显示区域宽度 * @param height 字符显示区域高度 * @param size 字体大小 * @param p 字符串起始地址 * * @return void */ void lcd_show_string(u16 x, u16 y, u16 width, u16 height, u8 size, char *p,u16 pointColor,u16 backColor) {
u8 x0 = x; width += x; height += y; while((*p <= '~') && (*p >= ' ')) //判断是不是非法字符! {
if(x >= width) {
x = x0; y += size; } if(y >= height)break; //退出 lcd_show_char(x, y, *p, size,pointColor,backColor); x += size / 2; p++; } } / * @brief 显示图片 * * @remark Image2Lcd取模方式: C语言数据/水平扫描/16位真彩色(RGB565)/高位在前 其他的不要选 * * @param x,y 起点坐标 * @param width 图片宽度 * @param height 图片高度 * @param p 图片缓存数据起始地址 * * @return void */ void lcd_show_image(u16 x, u16 y, u16 width, u16 height, const u8 *p) {
u16 i; if(x + width > LCD_Width || y + height > LCD_Height) {
return; } lcd_address_set(x, y, x + width - 1, y + height - 1); lcd_dc=1; for(i=0;i<width * height * 2;i++) {
lcd_read_write_byte(p[i]); } }
讯享网
lcd.h
讯享网#define lcd_cs PAout(4) #define lcd_dc PAout(8) #define lcd_rst PAout(15) #define lcd_background PBout(3) #define open_lcd() lcd_background=1 #define close_lcd() lcd_background=0 //LCD的宽和高定义 #define LCD_Width 240 #define LCD_Height 320 //画笔颜色 #define WHITE 0xFFFF #define BLACK 0x0000 #define BLUE 0x001F #define BRED 0XF81F #define GRED 0XFFE0 #define GBLUE 0X07FF #define RED 0xF800 #define MAGENTA 0xF81F #define GREEN 0x07E0 #define CYAN 0x7FFF #define YELLOW 0xFFE0 #define BROWN 0XBC40 //棕色 #define BRRED 0XFC07 //棕红色 #define GRAY 0X8430 //灰色 //GUI颜色 #define DARKBLUE 0X01CF //深蓝色 #define LIGHTBLUE 0X7D7C //浅蓝色 #define GRAYBLUE 0X5458 //灰蓝色 //以上三色为PANEL的颜色 #define LIGHTGREEN 0X841F //浅绿色 //#define LIGHTGRAY 0XEF5B //浅灰色(PANNEL) #define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色 #define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色) #define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色) void lcd_init(void); void lcd_set_speed(u8 SPI_BaudRatePrescaler); u8 lcd_read_write_byte(u8 TxData); void lcd_clear(u16 color); u16 lcd_read_id(void); void lcd_draw_point(u16 x, u16 y,u16 pointColor); void lcd_show_image(u16 x, u16 y, u16 width, u16 height, const u8 *p); void lcd_show_string(u16 x, u16 y, u16 width, u16 height, u8 size, char *p,u16 pointColor,u16 backColor); void lcd_show_char(u16 x, u16 y, char chr, u8 size,u16 pointColor,u16 backColor); void lcd_draw_circle(u16 x0, u16 y0, u8 r,u16 pointColor); void lcd_address_set(u16 x1, u16 y1, u16 x2, u16 y2); void lcd_write_data(u8 data); void lcd_write_cmd(u8 cmd);
源代码链接

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/59399.html