2017-04-23 1556
从51到STM32F4学习这么久了,总算找到点头绪了,目前学习了GPIO,中断,定时器,看门狗的基本使用,所以想试着看看能不能做个什么东西,就是想复习一下最近学习的知识。正好上学期单片机课程设计做过一个可以蓝牙、按键校准、带温度显示的时钟,所以我想看能不能将程序移植到STM32上呢?说做就做,经过三天的时间,几次的程序修改和调试,终于成功了!
单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》
由于STM32内部定时器的精度还是很高的(一小时慢1s),所以就没有使用DS1302时钟芯片(关键是手里没有),显示上和课程设计做的有些不一样,没有增加日期和星期显示,就时间、闹钟和温度的显示。
工业字符型液晶,能够同时显示16x02即32个字符。1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。市面上字符液晶大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
可见用STM32的3.3v电平驱动显示完全没问题,看到这我就放心了,代码经过多次的修改后,终于成功显示了,所以还是要多看看数据手册。
#define LCD_RS PAout(1) #define LCD_RW PAout(4) #define LCD_EN PAout(6) #define LCD_DB GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15
void LCD_GPIO_Config(void) { GPIO_InitTypeDef IO_Init; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE,ENABLE); /*控制线初始化 : */ IO_Init.GPIO_Mode=GPIO_Mode_OUT; //输出 IO_Init.GPIO_OType=GPIO_OType_PP; //推挽模式 IO_Init.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_6; IO_Init.GPIO_PuPd=GPIO_PuPd_UP; // IO_Init.GPIO_Speed=GPIO_Speed_2MHz; //GPIO_Speed_2MHz GPIO_Init(GPIOA,&IO_Init); /*数据线初始化*/ IO_Init.GPIO_Mode=GPIO_Mode_OUT; IO_Init.GPIO_OType=GPIO_OType_OD; //开漏输出可双向 IO_Init.GPIO_Pin=LCD_DB; IO_Init.GPIO_PuPd=GPIO_PuPd_UP; //上拉 IO_Init.GPIO_Speed=GPIO_Speed_2MHz; GPIO_Init(GPIOE,&IO_Init); /*测试 : 高电平3.3v LCD_RS=1; LCD_RW=1; LCD_EN=1; GPIO_SetBits(GPIOE,LCD_DB); */ }
void GPIO_OutData(u8 Dat) { u16 tmp; tmp = 0; tmp =Dat; tmp <<= 8; //数据左移到高8位 GPIO_Write(GPIOE,tmp); //数据写入到GPIOE高8位 }
void LCD_CheckBusy(void) { u8 sta; GPIO_OutData(0xff); LCD_RS=0; LCD_RW=1; do{ LCD_EN=1; delay_ms(5); sta = GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_15); LCD_EN =0; }while(sta & 0x80); }
/* LCD_RS = 1, LCD_RW = 0 */ void LCD_WriteData(u8 Dat) { LCD_CheckBusy(); //忙则等待 LCD_RS=1; LCD_RW=0; GPIO_OutData(Dat); LCD_EN=1; delay_ms(1); LCD_EN = 0; }
/*LCD_RS = 0, LCD_RW = 0*/ void LCD_WriteCmd(u8 Cmd) { LCD_CheckBusy(); //忙则等待 LCD_RS = 0; LCD_RW = 0; GPIO_OutData(Cmd); LCD_EN = 1; delay_ms(1); LCD_EN = 0; }
void LCD_Init(void) { LCD_WriteCmd(0x38); LCD_WriteCmd(0x0C); LCD_WriteCmd(0x06); /*显示光标移动设置*/ delay_ms(1); LCD_WriteCmd(0x01); /*显示清屏*/ }
void LCD_ClearScrren(void) { LCD_WriteCmd(0x01); }
void LCD_SetCursor(u8 x, u8 y) { u8 addr; if (y == 0) addr = 0x00 + x; else addr = 0x40 + x; LCD_WriteCmd(addr | 0x80); }
void LCD_DisChar(u8 x,u8 y,u8 ch) { LCD_SetCursor(x,y); //字符显示位置设定 LCD_WriteData(ch); }
void LCD_DisNumber(u8 x,u8 y,u8 Num) { LCD_SetCursor(x,y); LCD_WriteData(0x30+Num/10); LCD_SetCursor(x+1,y); LCD_WriteData(0x30+Num%10); }
void LCD_DisString(u8 x,u8 y,u8 *str) { LCD_SetCursor(x, y); while(*str != '\0') { LCD_WriteData(*str++); } }
int main(void) { delay_init(168); LED_Init(); LCD_GPIO_Config(); LCD_Init(); LCD_ClearScrren(); while(1) { delay_ms(500); LED1_ON; LCD_DisString(0,0,"abcdefghijklmnop"); delay_ms(500); LED1_OFF; LCD_DisNumber(0,1,56); LCD_DisChar(2,1,'a'); LCD_DisString(3,1," Hello World!"); } }
显示非常完美,和51驱动没有什么区别
微信扫码关注我的公众号
不定期更新个人学习笔记和技术总结,欢迎大家互相学习交流!
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。