[新手园地] 【3P】 lesson3-LCD1602

[复制链接]
 楼主| zhoubojay 发表于 2011-10-26 22:13 | 显示全部楼层 |阅读模式
  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /* */
  3. /* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
  4. /* */
  5. /*---------------------------------------------------------------------------------------------------------*/
  6. #include <stdio.h>
  7. #include "NUC1xx.h"
  8. #include "Driver\DrvGPIO.h"
  9. #include "Driver\DrvSYS.h"
  10. #include "LCD1602.h"


  11. int main(void)
  12. {
  13. UNLOCKREG(); // 芯片注册解锁
  14. SYSCLK->PWRCON.XTL12M_EN = 1; // 设定12M外部晶振

  15. DrvSYS_Delay(5000); // 等待时钟就绪
  16. LOCKREG();
  17. LCD1602_Init();

  18. LCD1602_WriteString(1,0,"hotpower-LOVE");

  19. LCD1602_WriteString(0,1,"cortex-m0-10-26");


  20. // DrvGPIO_ClrBit(E_GPA,2);
  21. // DrvGPIO_ClrBit(E_GPA,3);
  22. // DrvGPIO_ClrBit(E_GPA,4);
  23. // DrvGPIO_ClrBit(E_GPA,5);
  24. while(1);

  25. }
  1. /**********************************************


  2. *****************************************/
  3. #include "LCD1602.H"
  4. #include "NUC1xx.h"
  5. #include "DrvGPIO.h"

  6. /*******************************************************************************
  7. // 引脚定义 // (使用者根据实际更改)
  8. ******************************************************************************/
  9. #define LCD_DB_Port E_GPA

  10. //#define LCD_Ctr_Port E_PORT1
  11. //#define LCD_PW_GND E_GPE,5,E_IO_OUTPUT //接LCD1602 VSSPin,需要强制输出0,做GND用

  12. #define LCD_RS E_GPC,15
  13. #define LCD_RW E_GPC,6
  14. #define LCD_EN E_GPC,7

  15. #define LCD_POWER_ON DrvGPIO_ClrBit(E_GPE,5); //接LCD1602 VSSPin,需要强制输出0,做GND用
  16. #define LCD_VO_Adj DrvGPIO_ClrBit(E_GPC,14); //对比度调节

  17. #define LCD_RS_Data DrvGPIO_SetBit(LCD_RS); // 数据寄存器
  18. #define LCD_RS_Reg DrvGPIO_ClrBit(LCD_RS); // 指令寄存器

  19. #define LCD_RW_Read DrvGPIO_SetBit(LCD_RW); // 读
  20. #define LCD_RW_Write DrvGPIO_ClrBit(LCD_RW); // 写

  21. #define LCD_EN_Set DrvGPIO_SetBit(E_GPC,7); // 高
  22. #define LCD_EN_Clr DrvGPIO_ClrBit(E_GPC,7); // 低

  23. //sbit LCD_RS = P1^0; //寄存器选择:1 数据;0 指令
  24. //sbit LCD_RW = P1^1; //读写选择:1 读;0 写
  25. //sbit LCD_EN = P1^2; //使能,读时为高电平,写时为高脉冲
  26. //sbit LCD_Bsy= P0^7; //LCD DB7为忙检测端,1为忙,0为空闲
  27. /*******************************************************************************
  28. // 定义LCD1602指令集 // (详细请见技术手册)
  29. ******************************************************************************/
  30. #define CMD_clear 0x01 // 清除屏幕
  31. #define CMD_back 0x02 // DDRAM回零位
  32. #define CMD_dec1 0x04 // 读入后AC(指针)减1,向左写
  33. #define CMD_add1 0x06 // 读入后AC(指针)加1,向右写
  34. #define CMD_dis_gb1 0x0f // 开显示_开光标_开光标闪烁
  35. #define CMD_dis_gb2 0x0e // 开显示_开光标_关光标闪烁
  36. #define CMD_dis_gb3 0x0c // 开显示_关光标_关光标闪烁
  37. #define CMD_OFF_dis 0x08 // 关显示_关光标_关光标闪烁
  38. #define CMD_set82 0x38 // 8位总线_2行显示

  39. /*============================================================
  40. 液晶指令说明:
  41. 0x01-------------->清除屏幕,置AC为0,光标回位。
  42. 0x02-------------->DDRAM 地址为0,显示回原位,DDRAM内容不变.
  43. 0x03-------------->DDRAM 地址为0,显示回原位,DDRAM内容不变.
  44. **********MODE指令************
  45. 0x04-------------->设置光标移动方向减量方式,并指定显示不移动。
  46. 0x05-------------->设置光标移动方向减量方式,并指定显示移动。
  47. 0x06-------------->设置光标移动方向增量方式,并指定显示不移动。
  48. 0x07-------------->设置光标移动方向增量方式,并指定显示移动。
  49. **********DSPOFF指令************
  50. 0x08-------------->设置显示关、光标关、光标所在字符不闪烁.
  51. **********DSPON指令************
  52. 0x0c-------------->显示开
  53. 0x0e-------------->显示开,光标开
  54. 0x0f-------------->显示开,光标开,光标闪烁
  55. 0x10-------------->光标移位,左移
  56. 0x14-------------->光标移位,右移
  57. 0x18-------------->显示移位,左移
  58. 0x1c-------------->显示移位,右移
  59. **********INIT指令************
  60. 0x20-------------->4BIT模式,显示一行,5x7字体
  61. 0x24-------------->4BIT模式,显示一行,5x10字体
  62. 0x28-------------->4BIT模式,显示两行,5x7字体
  63. 0x2c-------------->4BIT模式,显示两行,5x10字体
  64. 0x30-------------->8BIT模式,显示一行,5x7字体
  65. 0x34-------------->8BIT模式,显示一行,5x10字体
  66. 0x38-------------->8BIT模式,显示两行,5x7字体
  67. 0x3c-------------->8BIT模式,显示两行,5x10字体
  68. ============================================================*/



  69. unsigned char Table[] = {0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00 // 日
  70. };
  71. static void LCD_GPIO_Init()
  72. {
  73. //DrvGPIO_Open(LCD_PW_GND); // 1602上电
  74. LCD_POWER_ON;
  75. LCD_VO_Adj;
  76. }

  77. void delaynms(unsigned char n)
  78. {
  79. unsigned char i,j;
  80. unsigned int k;
  81. i=2; //主频多少i就多少
  82. //延时用这个很无奈,不同的系统有不同的方法
  83. //好在只有初始化时使用,对系统影响不大
  84. for(;i>0;i--)
  85. {
  86. for(j=0;j<n;j++)
  87. {
  88. for(k=0;k<980;k++);
  89. }
  90. }
  91. }

  92. /**********************************************************************
  93. 延时
  94. **********************************************************************/
  95. void delay_nus(unsigned int t)
  96. {
  97. unsigned int i=0;
  98. while(t--)
  99. {
  100. for(i=0;i<1;i++);
  101. }
  102. }

  103. /*******************************************************************************
  104. 描 述:忙检测 ,直到空闲时退出
  105. 参 数:无
  106. 返回值:无
  107. 备 注:LCD1602 DB7为1是,LCD1602忙,否则空闲。
  108. ******************************************************************************/
  109. static void Checkbsy()
  110. {
  111. unsigned char temp;
  112. do{
  113. temp = ReadRegister(Com_Reg);
  114. }while(temp & 0x80);

  115. // LCD_RS = Com_Reg;
  116. // LCD_RW = READ;
  117. // LCD_DB = 0xff; //通过往端口写1,使单片机进入读模式
  118. // LCD_EN = 1;
  119. // while(LCD_Bsy); //等到LCD1602空闲时退出
  120. // LCD_EN = 0;
  121. }
  122. /*******************************************************************************
  123. 描 述:写寄存器
  124. 参 数:_Register 要操作的寄存器(Com_reg 指令寄存器,Data_Reg 数据寄存器)
  125. _Data 要写入的数据
  126. 返回值:无
  127. 备 注:
  128. ******************************************************************************/
  129. static void WriteRegister(unsigned char _Register,int32_t _Data)
  130. {
  131. Checkbsy();

  132. if(_Register != Data_Reg){
  133. LCD_RS_Reg;
  134. }else{
  135. LCD_RS_Data;
  136. }
  137. // delay_nus(2);
  138. LCD_RW_Write;
  139. // delay_nus(2);
  140. // LCD_RS = _Register;
  141. // LCD_RW = WRITE;
  142. // LCD_EN = 1;

  143. DrvGPIO_SetPortBits(LCD_DB_Port,_Data<<2);
  144. LCD_EN_Set;
  145. //delay_nus(2);
  146. // delay_nus(2);
  147. //LCD_DB = _Data; //送数据
  148. //LCD_EN = 0;
  149. LCD_EN_Clr;
  150. }

  151. /*******************************************************************************
  152. 描 述:写CGROM
  153. 参 数:_len 要写入crgrom区的数据长度,_len最大为64
  154. 返回值:无
  155. 备 注:将预先定义好的字模写入cgram
  156. ******************************************************************************/
  157. void CgramWrite(unsigned char _len)
  158. {
  159. unsigned char i;
  160. WriteRegister(Com_Reg,0x06); // 设置cgrom地址自动加1
  161. WriteRegister(Com_Reg,0x40); // cgrom 起始地址
  162. for(i=0;i<_len;i++)
  163. {
  164. WriteRegister(Data_Reg,Table[i]); // 按数组写入数据
  165. }
  166. }

  167. /*******************************************************************************
  168. 描 述:初始化LCD1602
  169. 参 数:
  170. 返回值:
  171. 备 注:8位2行显示,显示光标,闪烁
  172. *******************************************************************************/
  173. void LCD1602_Init(void)
  174. {
  175. LCD_GPIO_Init();
  176. delaynms(15);
  177. WriteRegister(Com_Reg,CMD_set82);//8位点阵模式
  178. //delaynms(150);
  179. WriteRegister(Com_Reg,CMD_set82);
  180. //delaynms(150);
  181. WriteRegister(Com_Reg,CMD_set82);//8位点阵模式
  182. //delaynms(150);
  183. WriteRegister(Com_Reg,CMD_set82);//8位点阵模式
  184. WriteRegister(Com_Reg,CMD_clear);// 清屏
  185. delaynms(15);
  186. WriteRegister(Com_Reg,CMD_dis_gb1);// 开显示,显示光标,闪烁
  187. CgramWrite(8);
  188. WriteRegister(Com_Reg,CMD_clear);// 清屏
  189. delaynms(15);
  190. }

  191. /*******************************************************************************
  192. 描 述:设置显示位置
  193. 参 数:x 列, y 行
  194. 返回值:
  195. 备 注:x和y均从0开始,y最大为1
  196. *******************************************************************************/
  197. static void LCD1602_SetXY(unsigned char x,unsigned char y)
  198. {
  199. if(y == 0)
  200. {
  201. WriteRegister(Com_Reg,0x80+x); // 第一行
  202. }else{
  203. WriteRegister(Com_Reg,0xC0+x); // 第二行
  204. }
  205. }

  206. /*******************************************************************************
  207. 描 述:在指定位置显示一个字符
  208. 参 数:x 列, y 行 ,Data为要显示的字符
  209. 返回值:
  210. 备 注:x和y均从0开始,y最大为1
  211. *******************************************************************************/
  212. void LCD1602_WriteByte(unsigned char x,unsigned char y,unsigned char Data)
  213. {
  214. LCD1602_SetXY(x,y); // 设置地址
  215. WriteRegister(Data_Reg,Data); // 将要显示的字符写入数据寄存器
  216. }

  217. /*******************************************************************************
  218. 描 述:从指定位置开始显示字符串
  219. 参 数:x 列, y 行 ,*String为要显示的字符串
  220. 返回值:
  221. 备 注:x和y均从0开始,y最大为1
  222. *******************************************************************************/
  223. void LCD1602_WriteString(unsigned char x,unsigned char y,unsigned char *String)
  224. {
  225. LCD1602_SetXY(x,y);
  226. while(*String) // 判断是否已经写完
  227. {
  228. WriteRegister(Data_Reg,*String++); // 写入当前指向的字符,并将指针指向下一个字符
  229. }
  230. }

  231. /*******************************************************************************
  232. 描 述:读寄存器
  233. 参 数:_Register 要操作的寄存器(Com_reg 指令寄存器,Data_Reg 数据寄存器)
  234. 返回值:数据寄存器或指令寄存器的内容
  235. 备 注:
  236. ******************************************************************************/
  237. unsigned char ReadRegister(unsigned char _Register)
  238. {
  239. int32_t Data; //声明一个变量,用来保存从lcd1602读取到的值
  240. int32_t temp;
  241. if(_Register != Data_Reg){
  242. LCD_RS_Reg;
  243. }else{
  244. LCD_RS_Data;
  245. }
  246. //delay_nus(2);
  247. LCD_RW_Read;
  248. delay_nus(2);
  249. // LCD_RS = _Register;
  250. // LCD_RW = READ;
  251. //DrvGPIO_SetPortBits(LCD_DB_Port,0xff);
  252. //LCD_DB = 0xff; //通过往端口写1,使单片机进入读模式
  253. //LCD_EN = 1;
  254. LCD_EN_Set;
  255. delay_nus(2);
  256. Data = DrvGPIO_GetPortBits(LCD_DB_Port);
  257. //delay_nus(2);
  258. LCD_EN_Clr;
  259. //delay_nus(2);
  260. temp=Data>>2;
  261. return (int8_t)(Data>>2); //返回到的值
  262. }
  1. /***********************************************


  2. *****************************************/

  3. #ifndef _LCD1602_H_
  4. #define _LCD1602_H_

  5. /*******************************************************************************
  6. // 基本宏定义
  7. ******************************************************************************/
  8. #define WRITE 0
  9. #define READ 1
  10. #define Com_Reg 0
  11. #define Data_Reg 1

  12. extern void LCD1602_Init(void);
  13. extern void LCD1602_WriteByte(unsigned char x,unsigned char y,unsigned char Data);
  14. extern void LCD1602_WriteString(unsigned char x,unsigned char y,unsigned char *String);
  15. extern unsigned char ReadRegister(unsigned char _Register);

  16. #endif
1602程序也是参照论坛里的示例,今天10月26号第三届选美,特来向大叔示爱

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
weshiluwei6 发表于 2011-10-27 07:57 | 显示全部楼层
不错 支持支持啊
dong_abc 发表于 2011-10-29 15:32 | 显示全部楼层
楼主要努力赚钱买相机哈:lol
Cortex-M0 发表于 2012-1-21 10:36 | 显示全部楼层
不错, 支持
neo_bright 发表于 2012-3-4 23:40 | 显示全部楼层
:handshake
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

595

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部