drive_lcd1602.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*
  2. **************************************************************************************************
  3. * 小浩电子科技
  4. * 文件名:stm32驱动1602程序源文件
  5. * 描 述:
  6. * 版本号:V2.0
  7. * 备 注:
  8. * 程序员:电子极客迷
  9. * 日 期:2018-04-22
  10. ***************************************************************************************************
  11. */
  12. #include "drive_lcd1602.h"
  13. #include "delay.h"
  14. #include "stm32f10x.h"
  15. #include "stm32f10x_gpio.h"
  16. #include "stm32f10x_rcc.h"
  17. #include <stdarg.h> // 标准头文件
  18. #include "stdio.h"
  19. #ifdef LCD602_Bin //
  20. /*以下为并口驱动程序*/
  21. ///********************************硬件接口定义*********************************/
  22. #define RS GPIO_Pin_7
  23. #define RW GPIO_Pin_6
  24. #define EN GPIO_Pin_5
  25. #define Control_GPIO GPIOA
  26. /********************************宏定义*********************************/
  27. #define LCD1602_RS(x) x ? GPIO_SetBits(Control_GPIO, RS): GPIO_ResetBits(Control_GPIO, RS)
  28. #define LCD1602_RW(x) x ? GPIO_SetBits(Control_GPIO, RW): GPIO_ResetBits(Control_GPIO, RW)
  29. #define LCD1602_EN(x) x ? GPIO_SetBits(Control_GPIO, EN): GPIO_ResetBits(Control_GPIO, EN)
  30. void LCDGPIO_Configuration(void);
  31. /*********************************************************************
  32. *名 称:LcdWaitReady()
  33. *描 述:等待液晶准备好
  34. *入口参数:无
  35. *出口参数:result
  36. *********************************************************************/
  37. u8 LcdWaitReady(void)
  38. { // 测试LCD忙碌状态
  39. u8 result;
  40. LCD1602_RS(0); //0;
  41. LCD1602_RW(1); //1;
  42. LCD1602_EN(1); //1;
  43. delay_us(50);
  44. result = (GPIO_ReadInputData(GPIOB) & 0x8000)>>8;
  45. LCD1602_EN(0); // 0;
  46. return result;
  47. }
  48. /*********************************************************************
  49. *名 称: LcdWriteCmd(u8 cmd)
  50. *描 述:写指令到LCD1602,指令数据占一个字节
  51. *入口参数:cmd,待写入指令
  52. *出口参数:无
  53. *********************************************************************/
  54. void LCD1602_Write_Cmd(unsigned char cmd)
  55. { // 写入指令数据到LCD
  56. //while(LcdWaitReady());
  57. delay_us(500);
  58. LCD1602_RS(0); // 0;
  59. LCD1602_RW(0); // 0;
  60. LCD1602_EN(0); // 0;
  61. delay_us(50);
  62. GPIOB->BSRR = cmd<<8 & 0xff00; //将数据送到P0口
  63. GPIOB->BRR = ((~cmd)<<8) & 0xff00;
  64. delay_us(50);
  65. LCD1602_EN(1); // 1;
  66. delay_us(50);
  67. LCD1602_EN(0); // 0;
  68. }
  69. /*********************************************************************
  70. *名 称: LcdWriteCmd(u8 cmd)
  71. *描 述:写数据到LCD1602,数据占一个字节
  72. *入口参数:dat,待写入数据
  73. *出口参数:无
  74. *********************************************************************/
  75. void LCD1602_Write_Dat(unsigned char dat)
  76. { //写入字符显示数据到LCD
  77. //while(LcdWaitReady());
  78. delay_us(500);
  79. LCD1602_RS(1); //= 1;
  80. LCD1602_RW(0); //= 0;
  81. LCD1602_EN(0); //= 0;
  82. GPIOB->BSRR = dat<<8 & 0xff00; ////P0 = dat
  83. GPIOB->BRR = ((~dat)<<8) & 0xff00;
  84. delay_us(50);
  85. LCD1602_EN(1);// = 1;
  86. delay_us(50);
  87. LCD1602_EN(0);// = 0;
  88. delay_us(50);
  89. }
  90. /*********************************************************************
  91. *名 称:InitLcd1602()
  92. *描 述:初始化1602液晶
  93. *入口参数:无
  94. *出口参数:无
  95. *********************************************************************/
  96. void Init_Lcd1602(void)
  97. {
  98. //LCD初始化设定
  99. LCDGPIO_Configuration();
  100. delay_ms(100);
  101. LCD1602_Write_Cmd(0x38); //16*2显示,5*7点阵,8位数据
  102. delay_ms(30);
  103. LCD1602_Write_Cmd(0x0c); //显示开,关光标
  104. delay_ms(30);
  105. LCD1602_Write_Cmd(0x06); //移动光标
  106. delay_ms(30);
  107. LCD1602_Write_Cmd(0x01); //清除LCD的显示内容
  108. delay_ms(30);
  109. }
  110. /*********************************************************************
  111. *名 称:LcdClearScreen()
  112. *描 述:清屏
  113. *入口参数:无
  114. *出口参数:无
  115. *********************************************************************/
  116. void LcdClearScreen(void)
  117. {
  118. LCD1602_Write_Cmd(0x01);
  119. }
  120. /*********************************************************************
  121. *名 称:LcdOpenCursor()
  122. *描 述:打开光标的闪烁效果
  123. *入口参数:无
  124. *出口参数:无
  125. *********************************************************************/
  126. void LcdOpenCursor(void)
  127. {
  128. LCD1602_Write_Cmd(0x0F);
  129. }
  130. /*********************************************************************
  131. *名 称:LcdCloseCursor()
  132. *描 述: 关闭光标显示
  133. *入口参数:无
  134. *出口参数:无
  135. *********************************************************************/
  136. void LcdCloseCursor(void)
  137. {
  138. LCD1602_Write_Cmd(0x0C);
  139. }
  140. void LCDGPIO_Configuration(void)
  141. {
  142. GPIO_InitTypeDef GPIO_InitStructure;
  143. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  144. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//RS RW EN 控制脚 时钟
  145. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  146. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  147. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  148. GPIO_Init(GPIOB,&GPIO_InitStructure);
  149. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  150. //所有GPIO为同一类型端口
  151. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
  152. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //输出的最大频率为50HZ
  153. GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB端口
  154. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5;
  155. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  156. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  157. GPIO_Init(Control_GPIO,&GPIO_InitStructure);
  158. }
  159. #else
  160. //1602指令/数据 引脚 rs
  161. #define LCD_RS_Set() GPIO_SetBits(GPIOB, GPIO_Pin_7)
  162. #define LCD_RS_Clr() GPIO_ResetBits(GPIOB, GPIO_Pin_7)
  163. //1602读写引脚 rw可以不用 直接接地
  164. #define LCD_RW_Set() GPIO_SetBits(GPIOB, GPIO_Pin_6)
  165. #define LCD_RW_Clr() GPIO_ResetBits(GPIOB, GPIO_Pin_6)
  166. //1602使能引脚 en
  167. #define LCD_EN_Set() GPIO_SetBits(GPIOB, GPIO_Pin_6)
  168. #define LCD_EN_Clr() GPIO_ResetBits(GPIOB, GPIO_Pin_6)
  169. //1602数据端口 PD4~7 //采用操作一组io写方法使用 不建议用
  170. #define DATAOUT(x) GPIO_Write(LCD_DATA_PORT, x)
  171. #define LCD_DATA_PORT GPIOB
  172. void LCDGPIO_Configuration(void)
  173. {
  174. GPIO_InitTypeDef GPIO_InitStructure;
  175. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE);//打开时钟
  176. //dataIO GPIOA4~7 初始化
  177. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
  178. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  179. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  180. GPIO_Init(LCD_DATA_PORT, &GPIO_InitStructure);
  181. // RS RW E IO初始化
  182. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5; //rw rs en
  183. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  184. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  185. GPIO_Init(GPIOB, &GPIO_InitStructure);
  186. }
  187. /* 检测液晶忙不忙 */
  188. void LCD1602_Wait_Ready(void)
  189. {
  190. int8_t sta;
  191. DATAOUT(0xff); //PA端口全部置1
  192. LCD_RS_Clr(); //RS 0
  193. LCD_RW_Set(); //RW 1
  194. do
  195. {
  196. LCD_EN_Set(); //EN 1
  197. delay_ms(5); //延时5MS
  198. sta = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15);//读取状态字
  199. LCD_EN_Clr(); //EN 0
  200. }while(sta & 0x80);//bit7等于1表示忙,重复检测到其为0停止
  201. }
  202. /*
  203. 向1602写入一字节命令,cmd-待写入命令
  204. //写入指令 RS-0 RW-0
  205. */
  206. void LCD1602_Write_Cmd(unsigned char cmd)
  207. {
  208. char ik=0;
  209. delay_ms(10); //不判忙信号 必须加入延时
  210. //LCD1602_Wait_Ready(); //判断忙不忙
  211. LCD_RS_Clr();
  212. for(ik=0;ik<2;ik++) //操作一位一位的写数据进去 建议用这种写法 不影响其他位
  213. {
  214. LCD_EN_Set();
  215. GPIO_ResetBits(GPIOB,GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);//数据口全部写低
  216. if(cmd&0x80) GPIO_SetBits(GPIOB,GPIO_Pin_15);
  217. if(cmd&0x40) GPIO_SetBits(GPIOB,GPIO_Pin_14);
  218. if(cmd&0x20) GPIO_SetBits(GPIOB,GPIO_Pin_13);
  219. if(cmd&0x10) GPIO_SetBits(GPIOB,GPIO_Pin_12);
  220. LCD_EN_Clr();
  221. cmd=cmd<<4;
  222. }
  223. }
  224. /* 向1602写入一字节数据*/
  225. void LCD1602_Write_Dat(unsigned char dat)
  226. {
  227. char ik=0;
  228. delay_ms(10); //不判忙信号 必须加入延时
  229. LCD_RS_Set(); //1
  230. for(ik=0;ik<2;ik++)
  231. {
  232. LCD_EN_Set();
  233. GPIO_ResetBits(GPIOB,GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
  234. if(dat&0x80) GPIO_SetBits(GPIOB,GPIO_Pin_15);
  235. if(dat&0x40) GPIO_SetBits(GPIOB,GPIO_Pin_14);
  236. if(dat&0x20) GPIO_SetBits(GPIOB,GPIO_Pin_13);
  237. if(dat&0x10) GPIO_SetBits(GPIOB,GPIO_Pin_12);
  238. LCD_EN_Clr();
  239. dat=dat<<4;
  240. }
  241. }
  242. /* 初始化液晶*/
  243. void Init_Lcd1602(void)
  244. {
  245. LCDGPIO_Configuration();//IO配置初始化
  246. LCD1602_Write_Cmd(0x28); //16*2显示,5*7点阵,4位数据口
  247. LCD1602_Write_Cmd(0x0C); //开显示,光标关闭
  248. LCD1602_Write_Cmd(0x06); //文字不动,地址自动+1
  249. LCD1602_Write_Cmd(0x01); //清屏
  250. }
  251. #endif
  252. /************ 写字符数据函数 *****************
  253. //功能:在lcd1602指定位置上显示字符;
  254. //参数
  255. //p: 指向待显示数据指针
  256. //x: X坐标
  257. //y: Y坐标
  258. */
  259. void WriteLcd1602_String(char x,char y,char *p)
  260. {
  261. if(y == 0)
  262. {
  263. LCD1602_Write_Cmd(0x80 + x);
  264. }
  265. else
  266. {
  267. LCD1602_Write_Cmd(0xC0 + x);
  268. }
  269. while(*p != 0)
  270. {
  271. LCD1602_Write_Dat(*p);
  272. p++;
  273. }
  274. }
  275. void L1602_printf(char x,char y,char *p,...)
  276. {
  277. char Lcdbuf[16];
  278. va_list ap;
  279. va_start(ap,p);
  280. vsprintf(Lcdbuf,p,ap);
  281. va_end(ap);
  282. WriteLcd1602_String(x,y,Lcdbuf);
  283. }