矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 4003|回复: 4

分享一段I2C_lcd1602液晶屏驱动程序

[复制链接]
     
发表于 2018-2-1 19:25:58 | 显示全部楼层 |阅读模式
本帖最后由 gxg0000 于 2018-2-1 21:08 编辑

带有PCF8574模块板的lcd1602液晶显示屏,价格便宜,该显示模块通过4线连接单片机(其中2根串行数据接口,2根正负电源),能够大大简化电路连接,感兴趣的朋友不妨移植到含有I2C总线接口的单片机上。
本驱动程序已通过proteus仿真和测试板。
Image 1.png
  1. #include<avr/io.h>
  2. #include <util/delay.h>
  3. /************************************************************************
  4. *                                                        PCF8574单向写
  5. *************************************************************************/
  6. //TWI状态定义
  7. #define MT_SLA_ACK                0x18        //SLA+W 已发送,接收到ACK(SLA从机地址)
  8. #define MT_DATA_ACK                0x28        //数据已发送,接收到ACK
  9. #define WD_DEVICE_ADDR        0x4e        //PCF8574地址,高七位是从机I2C地址,第0位是传输方向                       
  10. //常用TWI操作(主模式写)
  11. #define Start()                                (TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
  12. #define Stop()                                (TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
  13. #define Wait()                                {while (!(TWCR & (1<<TWINT)));}
  14. #define TestAck()                        (TWSR & 0xf8)
  15. #define SetAck()                        (TWCR |= (1<<TWEA))
  16. #define SetNoAck()                        (TWCR &=~ (1<<TWEA))
  17. #define Write8Bit(x)                {TWDR =(x);TWCR=(1<<TWINT)|(1<<TWEN);}
  18. /************************************************************************
  19. *                                                        TWI总线初始化函数
  20. *************************************************************************/
  21. void I2C_init(void)
  22. {
  23.         TWCR=0x0;       
  24.         TWBR=0x20;           //设置波特率
  25.         TWSR=0x0;           //设置预分频=1
  26.         TWCR=0x04;           //使能总线激活
  27. }
  28. /************************************************************************
  29. *                                                        向I2C写1字节函数
  30. *************************************************************************/
  31. unsigned char I2C_Write(unsigned char data)
  32. {
  33.         Start();                                                                //启动
  34.         Wait();                                                                        //等待
  35.         //TestAck()!=START) return 1;                        //有错误返回1
  36.         Write8Bit(WD_DEVICE_ADDR);                                //从机I2C地址,写PCF8574地址(0x27)
  37.         Wait();       
  38.         //TestAck()!=MT_SLA_ACK) return 1;                //有错误返回1
  39.         Write8Bit(data);                                                   //写命令/数据
  40.         Wait();       
  41.         //TestAck()!=MT_DATA_ACK) return 1;                //有错误返回1
  42.         Stop();
  43.         return 0;
  44. }
  45. /************************************************************************
  46. *                                                        1602写指令或写数据
  47. *************************************************************************/
  48. void write_ComData(unsigned char rs,unsigned char dat)        //LCD1602写指令或写数据函数(rs=0写命令,re=1写数据)
  49. {
  50.         unsigned char port=0;        //PCF8574 I/O映射
  51.         if(rs==0)
  52.         {
  53.                 port=0x0;
  54.                 I2C_Write(port);        //写命令
  55.         }
  56.         else
  57.         {
  58.                 port=0x1;
  59.                 I2C_Write(port);        //写数据
  60.         }
  61.         port &= 0x0f;                        //清4位数据总线
  62.         port |= (dat&0xf0);                //合成高4位
  63.         I2C_Write(port);                //输出
  64.         port |=(1<<2);
  65.         I2C_Write(port);                //E=1
  66.         _delay_us(1);       
  67.         port &=~(1<<2);
  68.         I2C_Write(port);                //E=0

  69.         port &= 0x0f;
  70.         port |= (dat<<4);                //合成低4位
  71.         I2C_Write(port);                //输出
  72.         port |=(1<<2);
  73.         I2C_Write(port);                //E=1       
  74.         _delay_us(1);       
  75.         port &=~(1<<2);
  76.         I2C_Write(port);                //E=0       

  77.         _delay_ms(1);
  78. }
  79. /************************************************************************
  80. *                                                                1602初始化
  81. *************************************************************************/
  82. void init(void)       
  83. {       
  84.         //设置数据总线8位(CPU复位操作,先退出液晶显示器处在4位总线模式,然后重新设置数据总线4位)
  85.         _delay_ms(15);                        //延时15ms
  86.         write_ComData(0,0x38);        //设置数据总线8位
  87.         _delay_ms(15);                        //延时5ms
  88.         //转到4位总线方式
  89.         I2C_Write(0x0);
  90.         _delay_us(1);
  91.         I2C_Write(0x20);
  92.         _delay_us(1);
  93.         I2C_Write(0x24);                //E=1       
  94.         _delay_us(1);       
  95.         I2C_Write(0x20);                //E=0       
  96.         _delay_ms(15);
  97.         write_ComData(0,0x28);        //重新设置数据总线4位,2行,5*7点阵字符
  98.         write_ComData(0,0x0c);        //整体显示,关光标
  99.         write_ComData(0,0x01);        //清屏
  100.         _delay_ms(2);
  101. }
  102. /************************************************************************
  103. *                                                                主函数
  104. *************************************************************************/
  105. int main(void)
  106. {       
  107.         unsigned char table1[] = {"gxg000@hotmail.c"};
  108.         unsigned char table2[] = {"I2C_LCD1602  ok!"};               
  109.         I2C_init();
  110.         init();       
  111.         while(1)
  112.         {
  113.                 for(unsigned char i=0;i<16;i++)
  114.                 {
  115.                         write_ComData(0,0x80+i);                        //置第1行首地址       
  116.                         write_ComData(1,table1[i]);                        //显示"gxg000@hotmail.c"
  117.                 }        
  118.                 for(unsigned char i=0;i<16;i++)
  119.                 {
  120.                          write_ComData(0,0xc0+i);                        //置第2行首地址
  121.                         write_ComData(1,table2[i]);                        //显示"I2C_LCD1602  ok!"
  122.                 }
  123.                 _delay_ms(700);                 
  124.         }                        
  125. }
复制代码
     
发表于 2018-2-2 11:42:21 | 显示全部楼层
1602不能出汉字吧?
回复 支持 反对

使用道具 举报

     
发表于 2018-2-3 15:01:42 | 显示全部楼层
感谢楼主分享~~~
回复 支持 反对

使用道具 举报

     
发表于 2018-2-3 21:24:04 来自手机 | 显示全部楼层
记得1602有几个内存可以自定义,可以定义间笔字
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2018-2-8 12:59:53 | 显示全部楼层
zystbbs 发表于 2018-2-2 11:42
1602不能出汉字吧?

1602液晶屏可以显示8个自定义字符(5*8点阵),看样子显示汉字有点困难
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-30 10:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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