xzy610030

一起探讨,一起进步,一起分享!

stm32F4----驱动12864(八)

1
阅读(2006)

上一篇中,键盘扫描,还存在几个问题,

(1)等待释放的死循环,这样处理肯定不妥,如果别人按着不放了,其他的事不用做了;

(2)消抖20ms,浪费了时间;

(3)没有实现长按,连击等功能。

后面在改善这几个问题。


今天搞了一天的LCD12864,费了一天。犯了些低级错误,不过在睡觉前搞定了。

关于那些命令和协议就不贴出来了,大把的资料讲这些。

直接上代码吧。

lcd12864.h如下:

#ifndef _LCD12864_H_ #define _LCD12864_H_ #ifdef _cplusplus extern "C" { #endif #include "stm32f4xx.h" //*******RS PB8*********** #define LCD_RS_PIN GPIO_Pin_8 #define LCD_RS_PORT GPIOB #define LCD_RS_CLK RCC_AHB1Periph_GPIOB //*******RW PC6*********** #define LCD_RW_PIN GPIO_Pin_6 #define LCD_RW_PORT GPIOC #define LCD_RW_CLK RCC_AHB1Periph_GPIOC //*******EN PB9*********** #define LCD_EN_PIN GPIO_Pin_9 #define LCD_EN_PORT GPIOB #define LCD_EN_CLK RCC_AHB1Periph_GPIOB //*******DB0 PA5*********** #define LCD_DB0_PIN GPIO_Pin_5 #define LCD_DB0_PORT GPIOA #define LCD_DB0_CLK RCC_AHB1Periph_GPIOA //*******DB1 PA12*********** #define LCD_DB1_PIN GPIO_Pin_12 #define LCD_DB1_PORT GPIOA #define LCD_DB1_CLK RCC_AHB1Periph_GPIOA //*******DB2 PA6*********** #define LCD_DB2_PIN GPIO_Pin_6 #define LCD_DB2_PORT GPIOA #define LCD_DB2_CLK RCC_AHB1Periph_GPIOA //*******DB3 PA11*********** #define LCD_DB3_PIN GPIO_Pin_11 #define LCD_DB3_PORT GPIOA #define LCD_DB3_CLK RCC_AHB1Periph_GPIOA //*******DB4 PA7*********** #define LCD_DB4_PIN GPIO_Pin_7 #define LCD_DB4_PORT GPIOA #define LCD_DB4_CLK RCC_AHB1Periph_GPIOA //*******DB5 PB12*********** #define LCD_DB5_PIN GPIO_Pin_12 #define LCD_DB5_PORT GPIOB #define LCD_DB5_CLK RCC_AHB1Periph_GPIOB //*******DB6 PB6*********** #define LCD_DB6_PIN GPIO_Pin_6 #define LCD_DB6_PORT GPIOB #define LCD_DB6_CLK RCC_AHB1Periph_GPIOB //*******DB7 PB11*********** #define LCD_DB7_PIN GPIO_Pin_11 #define LCD_DB7_PORT GPIOB #define LCD_DB7_CLK RCC_AHB1Periph_GPIOB //*******PSB PC7************ #define LCD_PSB_PIN GPIO_Pin_7 #define LCD_PSB_PORT GPIOC #define LCD_PSB_CLK RCC_AHB1Periph_GPIOC #define LCD_RST_PIN GPIO_Pin_9 #define LCD_RST_PORT GPIOA #define LCD_RST_CLK RCC_AHB1Periph_GPIOA #define LCD_RS(x) x ? GPIO_SetBits(LCD_RS_PORT,LCD_RS_PIN): GPIO_ResetBits(LCD_RS_PORT,LCD_RS_PIN) #define LCD_RW(x) x ? GPIO_SetBits(LCD_RW_PORT,LCD_RW_PIN): GPIO_ResetBits(LCD_RW_PORT,LCD_RW_PIN) #define LCD_EN(x) x ? GPIO_SetBits(LCD_EN_PORT,LCD_EN_PIN): GPIO_ResetBits(LCD_EN_PORT,LCD_EN_PIN) //#define LCD_PSB(x) x ? GPIO_SetBits(LCD12864_GPIO,PSB): GPIO_ResetBits(LCD12864_GPIO,PSB) #define LCD_RST(x) x ? GPIO_SetBits(LCD_RST_PORT,LCD_RST_PIN): GPIO_ResetBits(LCD_RST_PORT,LCD_RST_PIN) #define LcdData(x) GPIOB->ODR=(GPIOB->ODR&0x0000)|(x&0xFFFF); extern void lcd12864_init(void); extern void lcd_12864_print(uint8_t x, uint8_t y, unsigned char *str); extern void lcd_12864_clear_screen(void); #ifdef _cplusplus } #endif #endif

RST这个引脚可以不使用......


lcd12864.c如下:

#include "lcd12864.h" #include "delay.h" static void lcd_data_in(void) { GPIO_InitTypeDef GPIO_InitStructure; // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB |RCC_AHB1Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = LCD_DB0_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(LCD_DB0_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB1_PIN; GPIO_Init(LCD_DB1_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB2_PIN; GPIO_Init(LCD_DB2_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB3_PIN; GPIO_Init(LCD_DB3_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB4_PIN; GPIO_Init(LCD_DB4_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB5_PIN; GPIO_Init(LCD_DB5_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB6_PIN; GPIO_Init(LCD_DB6_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB7_PIN; GPIO_Init(LCD_DB7_PORT,&GPIO_InitStructure); } static void lcd_data_out(void) { GPIO_InitTypeDef GPIO_InitStructure; // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB |RCC_AHB1Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = LCD_DB0_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(LCD_DB0_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB1_PIN; GPIO_Init(LCD_DB1_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB2_PIN; GPIO_Init(LCD_DB2_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB3_PIN; GPIO_Init(LCD_DB3_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB4_PIN; GPIO_Init(LCD_DB4_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB5_PIN; GPIO_Init(LCD_DB5_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB6_PIN; GPIO_Init(LCD_DB6_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_DB7_PIN; GPIO_Init(LCD_DB7_PORT,&GPIO_InitStructure); } static void lcd_data_high(void) { GPIO_SetBits(LCD_DB0_PORT,LCD_DB0_PIN); // 1 GPIO_SetBits(LCD_DB1_PORT,LCD_DB1_PIN); // 1 GPIO_SetBits(LCD_DB2_PORT,LCD_DB2_PIN); // 1 GPIO_SetBits(LCD_DB3_PORT,LCD_DB3_PIN); // 1 GPIO_SetBits(LCD_DB4_PORT,LCD_DB4_PIN); // 1 GPIO_SetBits(LCD_DB5_PORT,LCD_DB5_PIN); // 1 GPIO_SetBits(LCD_DB6_PORT,LCD_DB6_PIN); // 1 GPIO_SetBits(LCD_DB7_PORT,LCD_DB7_PIN); // 1 } static void lcd_gpio_config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB |RCC_AHB1Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = LCD_RS_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(LCD_RS_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_RW_PIN; GPIO_Init(LCD_RW_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_EN_PIN; GPIO_Init(LCD_EN_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_PSB_PIN; GPIO_Init(LCD_PSB_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_RST_PIN; GPIO_Init(LCD_RST_PORT,&GPIO_InitStructure); // lcd_data_out(); // lcd_data_high(); GPIO_SetBits(LCD_PSB_PORT,LCD_PSB_PIN);//并口 } static void lcd_busy() { // lcd_data_out(); //DB口设置为输出 // lcd_data_high(); //输出为1 lcd_data_in(); //DB切换成设置为输入 // Delay_ms(5); //Delay_us(10); LCD_RS(0); LCD_RW(1); LCD_EN(1); // Delay_us(10); // Delay_ms(5); // Delay_us(100); while(GPIO_ReadInputDataBit(LCD_DB7_PORT ,LCD_DB7_PIN)); LCD_EN(0); } static void lcd_data_analysis(uint8_t cmd) { lcd_data_out(); if(cmd & 0x80) GPIO_SetBits(LCD_DB7_PORT,LCD_DB7_PIN); else GPIO_ResetBits(LCD_DB7_PORT,LCD_DB7_PIN); if(cmd & 0x40) GPIO_SetBits(LCD_DB6_PORT,LCD_DB6_PIN); else GPIO_ResetBits(LCD_DB6_PORT,LCD_DB6_PIN); if(cmd & 0x20) GPIO_SetBits(LCD_DB5_PORT,LCD_DB5_PIN); else GPIO_ResetBits(LCD_DB5_PORT,LCD_DB5_PIN); if(cmd & 0x10) GPIO_SetBits(LCD_DB4_PORT,LCD_DB4_PIN); else GPIO_ResetBits(LCD_DB4_PORT,LCD_DB4_PIN); if(cmd & 0x08) GPIO_SetBits(LCD_DB3_PORT,LCD_DB3_PIN); else GPIO_ResetBits(LCD_DB3_PORT,LCD_DB3_PIN); if(cmd & 0x04) GPIO_SetBits(LCD_DB2_PORT,LCD_DB2_PIN); else GPIO_ResetBits(LCD_DB2_PORT,LCD_DB2_PIN); if(cmd & 0x02) GPIO_SetBits(LCD_DB1_PORT,LCD_DB1_PIN); else GPIO_ResetBits(LCD_DB1_PORT,LCD_DB1_PIN); if(cmd & 0x01) GPIO_SetBits(LCD_DB0_PORT,LCD_DB0_PIN); else GPIO_ResetBits(LCD_DB0_PORT,LCD_DB0_PIN); } static void writeCmd(uint8_t cmd) { lcd_busy(); LCD_RS(0); LCD_RW(0); LCD_EN(0); // Delay_us(2); lcd_data_analysis(cmd); // Delay_us(1); LCD_EN(1); // Delay_us(1); LCD_EN(0); } static void writeData(uint8_t data) { lcd_busy(); LCD_RS(1); LCD_RW(0); LCD_EN(0); // Delay_us(2); lcd_data_analysis(data); // Delay_us(1); LCD_EN(1); // Delay_us(1); LCD_EN(0); } static void set_position(uint8_t x, uint8_t y) { uint8_t p; switch ( x % 4 ) { case 0 : p = 0x80; break; /* 第一行开始地址 */ case 1 : p = 0x90; break; /* 第二行 */ case 2 : p = 0x88; break; /* 第三行 */ case 3 : p = 0x98; break; /* 第四行 */ } p += y; writeCmd(p); } void lcd12864_init(void) { lcd_gpio_config(); // LCD_RST(0); // Delay_ms(30); // LCD_RST(1); // Delay_ms(100); writeCmd(0x30); // Delay_ms(1); writeCmd(0x0c); // Delay_ms(1); writeCmd(0x01); // writeCmd(0x06); //writeCmd(0x7f); // Delay_ms(1); writeCmd(0x06); // Delay_ms(1); // writeCmd(0x80); // Delay_ms(1); // writeData(0x48); // Delay_ms(1); // writeData(0x32); Delay_ms(1); } void lcd_12864_print(uint8_t x, uint8_t y, unsigned char *str) { uint8_t i = 0; /* 首先设置位置 */ set_position(x, y); /* 写入数据 */ while ( str[i] != '\0' ) { writeData(str[i++]); /* 最大应该只支持 16 个字符 */ if ( i >= 16 ) { break; } } Delay_ms(50); } void lcd_12864_clear_screen(void) { writeCmd(0x01); }

这里我想问问,我的DB【7:0】引脚,在不同组的GPIO,我的赋值采用了这种方法,

if(cmd & 0x80) GPIO_SetBits(LCD_DB7_PORT,LCD_DB7_PIN); else GPIO_ResetBits(LCD_DB7_PORT,LCD_DB7_PIN); if(cmd & 0x40) GPIO_SetBits(LCD_DB6_PORT,LCD_DB6_PIN); else GPIO_ResetBits(LCD_DB6_PORT,LCD_DB6_PIN); if(cmd & 0x20) GPIO_SetBits(LCD_DB5_PORT,LCD_DB5_PIN); else GPIO_ResetBits(LCD_DB5_PORT,LCD_DB5_PIN); if(cmd & 0x10) GPIO_SetBits(LCD_DB4_PORT,LCD_DB4_PIN); else GPIO_ResetBits(LCD_DB4_PORT,LCD_DB4_PIN); if(cmd & 0x08) GPIO_SetBits(LCD_DB3_PORT,LCD_DB3_PIN); else GPIO_ResetBits(LCD_DB3_PORT,LCD_DB3_PIN); if(cmd & 0x04) GPIO_SetBits(LCD_DB2_PORT,LCD_DB2_PIN); else GPIO_ResetBits(LCD_DB2_PORT,LCD_DB2_PIN); if(cmd & 0x02) GPIO_SetBits(LCD_DB1_PORT,LCD_DB1_PIN); else GPIO_ResetBits(LCD_DB1_PORT,LCD_DB1_PIN); if(cmd & 0x01) GPIO_SetBits(LCD_DB0_PORT,LCD_DB0_PIN); else GPIO_ResetBits(LCD_DB0_PORT,LCD_DB0_PIN);

感觉非常笨,请问有更方便的方法没??


main函数主要就是调用了

unsigned char xiaozy1[] = "hello,AET";

unsigned char xiaozy2[] = "xzy610030";


lcd_12864_print(0, 2, xiaozy1);

lcd_12864_print(2, 2, xiaozy2);


值得说一下的是,显示数据RAM提供64x2个字节的空间, 最多可以控制416字(64个字) 的中文字型显示,地址如下:

blob.png

上图:

blob.png


blob.png


调了一天,主要是初始化的时候没弄完,另外,在怀疑lcd坏了的时候,直接用FPGA驱动了一下,发现是好的,于是只是检查代码,发现了问题,而且之前怀疑了各种延迟,在后续看了,delay都是可以不用的,从上面的代码中也可以看到后面我把延迟都注释掉了。结果正常。


至今已经对stm32的开发有了初步的了解,继续~~~~另外,真的不得不赞一下,图片粘贴的功能啊,太棒了。

Baidu
map