找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

自学AVR单片机二十七(Nokia33105110液晶显示)

[复制链接]
慧龙 发表于 2010-5-7 11:36:01 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

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

×
一、电路实现
本实例的电路图如下:
145a6e0476361a8174da9fc04c6afdc2.jpg
二、Nokia3310/5110液晶介绍
        Nokia3310/5110液晶的驱动控制器为PCD8544,它可以驱动48行*84列的图形显示,3310液晶的工作电压为2.7-3.3V,所以在上面的电路图中我们使用了3.3V的稳压管。另外由于单片机系统采用的是5V工作电压,并且LCD与单片机之间的连线都串接了电阻,整个系统上电后,测量电阻两端电压,会发现电阻两端有压降,这是因为单片机I/O口出来的是5V电压信号,而LCD上只能接受3.3V电压,所以电阻上产生压降。
        3310液晶模块有8个引脚,由于购买厂家不同,引脚的排列也有差别,8个引脚等别是:
电源正;电源地;背景灯正;背景灯负;复位脚;时钟线;数据线;使能线;数据/命令选择线。
      3310液晶支持SPI功能,可以直接使用AVR单片机的SPI来驱动3310液晶显示。本实例中我们采用模拟SPI功能实现。

三、程序代码
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3. #include "LCD5110.h"
  4. //函数声明
  5. void Delayus(unsigned int lus); //us延时函数
  6. void Delayms(unsigned int lms); //ms延时函数

  7. int main(void)
  8. {
  9. PORTB &= ~(RESET | DC | SCLK | SDIN);
  10. DDRB |= RESET | DC | SCLK | SDIN; //设置单片机的4个LCD引脚输出0
  11. while(1)
  12. {
  13. lcd_init(); //lcd初始化
  14. lcd_cls(); //清屏,光标回位
  15. lcd_gotoxy(16,2); //光标定位到第16列,第1行(最上面是0行)
  16. lcd_putsf("NOKIA5110",9); //显示Flash里面的字符串,共9个
  17. lcd_gotoxy(38,4);
  18. lcd_putchar('O'); //显示英文字母大写O
  19. lcd_putchar(75); //数字75的的ASCII字符是英文字母大写K
  20. Delayms(1000);
  21. }
  22. }
  23. //us级别的延时函数
  24. void Delayus(unsigned int lus)
  25. {
  26. while(lus--)
  27. {
  28. _delay_loop_2(3); //_delay_loop_2(1)是延时4个时钟周期,参数为3则延时12
  29. //个时钟周期,本实验用12M晶体,则12个时钟周期为12/12=1us
  30. }
  31. }
  32. //ms级别的延时函数
  33. void Delayms(unsigned int lms)
  34. {
  35. while(lms--)
  36. {
  37. Delayus(1000); //延时1ms
  38. }
  39. }


  40. 5110.h程序文件
  41. /*******************************************
  42. lcd5110.h
  43. *******************************************/
  44. /*************************************************************
  45. 5110LCD与单片机的连接如下
  46. RESET PB4
  47. D/C PB2
  48. SDIN PB1
  49. SCLK PB0
  50. SCE GND
  51. 英文字库,5*8点阵,每一个字符占用5个字节,共94个可显示字符数据**/

  52. #define RESET (1 << PB4) //RESET=0时,LCD复位
  53. #define DC (1 << PB2) //DC=0_指令,DC=1_数据
  54. #define SDIN (1 << PB1)
  55. #define SCLK (1 << PB0)
  56. #define SET_RESET (PORTB |= RESET)
  57. #define CLR_RESET (PORTB &= ~RESET)
  58. #define SET_DC (PORTB |= DC)
  59. #define CLR_DC (PORTB &= ~DC)
  60. #define SET_SDIN (PORTB |= SDIN)
  61. #define CLR_SDIN (PORTB &= ~SDIN)
  62. #define SET_SCLK (PORTB |= SCLK)
  63. #define CLR_SCLK (PORTB &= ~SCLK)
  64. unsigned char data[]={
  65. 0x00, 0x00, 0x00, 0x00, 0x00, // sp
  66. 0x00, 0x00, 0x2f, 0x00, 0x00, // !
  67. 0x00, 0x07, 0x00, 0x07, 0x00, // "
  68. 0x14, 0x7f, 0x14, 0x7f, 0x14, // #
  69. 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $
  70. 0x62, 0x64, 0x08, 0x13, 0x23, // %
  71. 0x36, 0x49, 0x55, 0x22, 0x50, // &
  72. 0x00, 0x05, 0x03, 0x00, 0x00, // ’
  73. 0x00, 0x1c, 0x22, 0x41, 0x00, // (
  74. 0x00, 0x41, 0x22, 0x1c, 0x00, // )
  75. 0x14, 0x08, 0x3E, 0x08, 0x14, // *
  76. 0x08, 0x08, 0x3E, 0x08, 0x08, // +
  77. 0x00, 0x00, 0xA0, 0x60, 0x00, // ,
  78. 0x08, 0x08, 0x08, 0x08, 0x08, // -
  79. 0x00, 0x60, 0x60, 0x00, 0x00, // .
  80. 0x20, 0x10, 0x08, 0x04, 0x02, // /
  81. 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
  82. 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
  83. 0x42, 0x61, 0x51, 0x49, 0x46, // 2
  84. 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
  85. 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
  86. 0x27, 0x45, 0x45, 0x45, 0x39, // 5
  87. 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
  88. 0x01, 0x71, 0x09, 0x05, 0x03, // 7
  89. 0x36, 0x49, 0x49, 0x49, 0x36, // 8
  90. 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
  91. 0x00, 0x36, 0x36, 0x00, 0x00, // :
  92. 0x00, 0x56, 0x36, 0x00, 0x00, // ;
  93. 0x08, 0x14, 0x22, 0x41, 0x00, // <
  94. 0x14, 0x14, 0x14, 0x14, 0x14, // =
  95. 0x00, 0x41, 0x22, 0x14, 0x08, // >
  96. 0x02, 0x01, 0x51, 0x09, 0x06, // ?
  97. 0x32, 0x49, 0x59, 0x51, 0x3E, // @
  98. 0x7C, 0x12, 0x11, 0x12, 0x7C, // A
  99. 0x7F, 0x49, 0x49, 0x49, 0x36, // B
  100. 0x3E, 0x41, 0x41, 0x41, 0x22, // C
  101. 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
  102. 0x7F, 0x49, 0x49, 0x49, 0x41, // E
  103. 0x7F, 0x09, 0x09, 0x09, 0x01, // F
  104. 0x3E, 0x41, 0x49, 0x49, 0x7A, // G
  105. 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
  106. 0x00, 0x41, 0x7F, 0x41, 0x00, // I
  107. 0x20, 0x40, 0x41, 0x3F, 0x01, // J
  108. 0x7F, 0x08, 0x14, 0x22, 0x41, // K
  109. 0x7F, 0x40, 0x40, 0x40, 0x40, // L
  110. 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
  111. 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
  112. 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
  113. 0x7F, 0x09, 0x09, 0x09, 0x06, // P
  114. 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
  115. 0x7F, 0x09, 0x19, 0x29, 0x46, // R
  116. 0x46, 0x49, 0x49, 0x49, 0x31, // S
  117. 0x01, 0x01, 0x7F, 0x01, 0x01, // T
  118. 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
  119. 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
  120. 0x3F, 0x40, 0x38, 0x40, 0x3F, // W
  121. 0x63, 0x14, 0x08, 0x14, 0x63, // X
  122. 0x07, 0x08, 0x70, 0x08, 0x07, // Y
  123. 0x61, 0x51, 0x49, 0x45, 0x43, // Z
  124. 0x00, 0x7F, 0x41, 0x41, 0x00, // [
  125. 0x55, 0x2A, 0x55, 0x2A, 0x55, // 55
  126. 0x00, 0x41, 0x41, 0x7F, 0x00, // ]
  127. 0x04, 0x02, 0x01, 0x02, 0x04, // ^
  128. 0x40, 0x40, 0x40, 0x40, 0x40, // _
  129. 0x00, 0x01, 0x02, 0x04, 0x00, // ’
  130. 0x20, 0x54, 0x54, 0x54, 0x78, // a
  131. 0x7F, 0x48, 0x44, 0x44, 0x38, // b
  132. 0x38, 0x44, 0x44, 0x44, 0x20, // c
  133. 0x38, 0x44, 0x44, 0x48, 0x7F, // d
  134. 0x38, 0x54, 0x54, 0x54, 0x18, // e
  135. 0x08, 0x7E, 0x09, 0x01, 0x02, // f
  136. 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
  137. 0x7F, 0x08, 0x04, 0x04, 0x78, // h
  138. 0x00, 0x44, 0x7D, 0x40, 0x00, // i
  139. 0x40, 0x80, 0x84, 0x7D, 0x00, // j
  140. 0x7F, 0x10, 0x28, 0x44, 0x00, // k
  141. 0x00, 0x41, 0x7F, 0x40, 0x00, // l
  142. 0x7C, 0x04, 0x18, 0x04, 0x78, // m
  143. 0x7C, 0x08, 0x04, 0x04, 0x78, // n
  144. 0x38, 0x44, 0x44, 0x44, 0x38, // o
  145. 0xFC, 0x24, 0x24, 0x24, 0x18, // p
  146. 0x18, 0x24, 0x24, 0x18, 0xFC, // q
  147. 0x7C, 0x08, 0x04, 0x04, 0x08, // r
  148. 0x48, 0x54, 0x54, 0x54, 0x20, // s
  149. 0x04, 0x3F, 0x44, 0x40, 0x20, // t
  150. 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
  151. 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
  152. 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
  153. 0x44, 0x28, 0x10, 0x28, 0x44, // x
  154. 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y
  155. 0x44, 0x64, 0x54, 0x4C, 0x44, // z
  156. 0x00, 0x08, 0x36, 0x41, 0x00, // {
  157. 0x00, 0x00, 0x7F, 0x00, 0x00, // |
  158. 0x00, 0x41, 0x36, 0x08, 0x00, // }
  159. 0x08, 0x10, 0x08, 0x04, 0x08 // ~
  160. };
  161. //=======================================================================================
  162. void lcd_write(unsigned char byte) //写LCD函数,模拟SPI通信
  163. {
  164. unsigned char i;

  165. for(i = 128;i > 0;i >>=1)
  166. {
  167. if(byte & i)
  168. {
  169. SET_SDIN;
  170. }
  171. else
  172. {
  173. CLR_SDIN;
  174. }
  175. CLR_SCLK;
  176. SET_SCLK;
  177. }

  178. /*unsigned char i; //先写数据的高位,后写低位
  179. for(i=128;i>0;i>>=1)
  180. {
  181. if( byte & i ) SDIN=1; else SDIN=0;
  182. SCLK=0; SCLK=1;
  183. } */
  184. }
  185. /*上面的是模拟SPI发送数据函数,下面的是硬件SPI发送数据函数
  186. void lcd_write(unsigned char data)
  187. {
  188. SPCR=80;
  189. SPDR=data; //开始发送数据
  190. while((SPSR>>7)==0); //等待发送接收结束
  191. } */
  192. //=======================================================================================
  193. void lcd_cls(void) //nokia3310清屏,光标复位
  194. {
  195. unsigned int i=0;
  196. CLR_DC;
  197. //DC=0;
  198. lcd_write(128); //光标回到0列
  199. lcd_write(64); //光标回到0行
  200. SET_DC;
  201. //DC=1; //准备写数据
  202. for(i=0;i<504;i++) //写504个0数据,就是清屏
  203. lcd_write(0);
  204. }
  205. //=======================================================================================

  206. void lcd_init(void) //nokia3310初始化函数
  207. {
  208. CLR_RESET;
  209. SET_RESET;
  210. CLR_DC;
  211. //RESET=0;
  212. //RESET=1; //复位结束
  213. // DC=0; //准备写指令
  214. lcd_write(32+1); //进入扩展指令
  215. lcd_write(128+38); //设置Vop,相当于亮度
  216. lcd_write(4+3); //设置温度系数,相当于对比度
  217. lcd_write(16+3); //设置偏置,这句要与不要的实际效果好像一样
  218. lcd_write(32+0); //进入基本指令
  219. lcd_write(12); //使能芯片活动/垂直寻址
  220. }
  221. //=======================================================================================
  222. //光标定位,x(0-83)是列地址,y(0-5)是行地址
  223. void lcd_gotoxy(unsigned char x,unsigned char y)
  224. {
  225. CLR_DC;
  226. //DC=0;
  227. lcd_write(x+128);
  228. lcd_write(y+64);
  229. }
  230. //=======================================================================================

  231. void lcd_putchar(unsigned char character) //显示ASCII值的字符
  232. {
  233. unsigned char i=0;
  234. unsigned int No;
  235. No=character-32; //字模数据是由空格开始,空格字符的ASCII的值就是32
  236. No=No*5; //每个字符的字模是5个字节
  237. SET_DC;
  238. //DC=1;
  239. while(i<5) //一个字符的字模是5个字节,就是5*8点阵
  240. {
  241. lcd_write(data[No]);
  242. i++;
  243. No++;
  244. }
  245. lcd_write(0); //每个字符之间空一列
  246. }
  247. //=====================================================================================
  248. void lcd_putsf(unsigned char *string , unsigned char n) //显示FLASH里面的字符串
  249. {
  250. unsigned char i=0;
  251. while(i<n)
  252. {
  253. lcd_putchar(string); //顺序显示字符
  254. i++;
  255. }
  256. }
复制代码
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-12-23 13:05 , Processed in 0.056427 second(s), 11 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表