找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4901|回复: 2
打印 上一主题 下一主题
收起左侧

发一个PCF8574A I2C接口的1602程序.欢迎各路大侠指点

[复制链接]
跳转到指定楼层
楼主
ID:105672 发表于 2016-2-18 14:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
拆了一台点钞机,主控板是用STC的12C5A16AD,正好手有块I2C的LCD1602.无聊就搞搞实验,用定时器做了个时钟.
  1. #include <STC15F104E.H>
  2. #include <intrins.h>
  3. sbit SDA=P0^2;       
  4. sbit SCL=P0^1;

  5. bit ack,blk;         //I2C 应答位  LCD背光开关

  6. #define uchar unsigned char                                                                 
  7.                                                                                                                                                                        
  8.                                                                                                                                                                        
  9. uchar num[]={"0123456789"},sec,min,hou;
  10. unsigned int us,ms;





  11. #define WriteAdd        0x7e                //写PCF8574A地址 0111 A2 A2 A0 W
  12. #define ReadAdd        0x7f                  //读PCF8574A地址 0111 A2 A2 A0 R
  13.                                                                                                                                                 //                   背光   CS/EN  R/W  RS
  14.                                    //P7 P6 P5 P4 P3 P2     P1   P0  PCF8574A引脚
  15. //#define WriteCom                          8                                        //DB7  DB6  DB5  DB4  1      0            0   0        RW=0写   RS=0指令  BLK背光
  16. //#define WriteData                         9                                  //DB7  DB6  DB5  DB4  1      0            0   1        RW=0写   RS=1数据
  17. //#define WriteComEn                  0x0c                          //DB7  DB6  DB5  DB4  1      1            0   0        RW=0写   RS=0
  18. //#define WriteDataEn                 0x0d                         //DB7  DB6  DB5  DB4  1      1            0   1        RW=0写   RS=1数据

  19. /*========================  PCF8574A  P3 = 0 关背光   ====================================*/

  20. //#define WriteCom                          0                                        //DB7  DB6  DB5  DB4  0      0            0   0        RW=0写   RS=0指令  BLK背光
  21. //#define WriteData                         1                                   //DB7  DB6  DB5  DB4  0      0            0   1        RW=0写   RS=1数据
  22. //#define WriteComEn                  4                            //DB7  DB6  DB5  DB4  0      1            0   0        RW=0写   RS=0
  23. //#define WriteDataEn                 5                             //DB7  DB6  DB5  DB4  0      1            0   1        RW=0写   RS=1数据

  24. uchar WriteCom=8,WriteData=9,WriteComEn=0x0c,WriteDataEn=0x0d;

  25. void LcdBlk()                                                                //LCD背光控制 blk=1亮,blk=0灭
  26.         {
  27.                 if (blk) {WriteCom=8,WriteData=9,WriteComEn=0x0c,WriteDataEn=0x0d;}
  28.                                 else {WriteCom=0,WriteData=1,WriteComEn=4,WriteDataEn=5;}
  29.         }

  30. void Delayms()                //@22.1184MHz 1MS
  31. {
  32.         unsigned char i, j;

  33.         i = 22;
  34.         j = 128;
  35.         do
  36.         {
  37.                 while (--j);
  38.         } while (--i);
  39. }
  40. void Timer0Init(void)                //10微秒@22.1184MHz     定时器做时钟
  41. {
  42.         AUXR |= 0x80;                //定时器时钟1T模式
  43.         TMOD &= 0xF0;                //设置定时器模式
  44.         TMOD |= 0x02;                //设置定时器模式
  45.         TL0 = 0x23;                //设置定时初值
  46.         TH0 = 0x23;                //设置定时重载值
  47.         TF0 = 0;                //清除TF0标志
  48.         TR0 = 1;                //定时器0开始计时
  49.         ET0=1;EA=1;
  50. }

  51. void Delay5us()                //@22.1184MHz
  52. {
  53.         unsigned char i;

  54.         _nop_();
  55.         _nop_();
  56.         _nop_();
  57.         i = 24;
  58.         while (--i);
  59. }
  60. void i2cStart()                                //I2C 起始信号
  61. {
  62.     SDA=1; _nop_();  SCL=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_();    SDA=0; _nop_(); _nop_(); _nop_();_nop_(); _nop_();SCL=0;Delay5us();       
  63. }

  64. void i2cStop()                                //I2C 停止信号
  65. {
  66.   SDA=0; _nop_();  SCL=1;  _nop_();  _nop_();  _nop_();  _nop_();  _nop_();  SDA=1;  _nop_();  _nop_();  _nop_();  _nop_();
  67. }

  68. void i2cAck(bit a)   //I2C应答信号
  69. {
  70. if(a==0)SDA=0;                         //在此发出应答或非应答信号
  71. else SDA=1;
  72. _nop_();
  73. _nop_();
  74. _nop_();
  75. SCL=1;
  76. Delay5us();
  77. SCL=0;                                                 //清时钟线,钳住I2C 总线以便继续接收
  78. Delay5us();
  79. }

  80. void i2cWriteByte(uchar temp)                                //I2C写一字节
  81. {
  82.     uchar i;
  83.   for(i=0;i<8;i++)
  84.   {
  85.                          SDA=(bit)(temp & 0x80) ;
  86.                          temp <<=1; Delay5us();       
  87.                          SCL=1;        Delay5us();        Delay5us();                       
  88.             SCL=0;//Delay5us();
  89.         }
  90.                                 _nop_();
  91.                                 SDA=1;        _nop_();Delay5us();
  92.                                 SCL=1;Delay5us();_nop_();_nop_();
  93.                                 if(SDA==1)ack=0;
  94.                                 else ack=1;                                         //判断是否接收到应答信号
  95.                                 SCL=0;
  96.                          
  97.                                                
  98. }

  99. void LcdCom(uchar com)                                                                  //LCD1602写指令
  100. {
  101.         i2cStart();                                                                                                                                        //I2C起始信号
  102.         i2cWriteByte(WriteAdd);                                                                                        //PCF8574A写地址
  103.         i2cWriteByte((com&0xf0)|WriteCom);                                  //先写LCD1602高4位指令+控制位
  104.         i2cWriteByte((com&0xf0)|WriteComEn);                                //LCD1602  CS/EN拉高送入
  105.         i2cWriteByte((com&0xf0)|WriteCom);                                        //LCD1602  CS/EN拉低准备写入
  106.         com<<=4;                                                                                                                                                //指令低4位左移到高4位
  107.         i2cWriteByte((com&0xf0)|WriteCom);                                        //写入剩下的4位指令+控制位
  108.         i2cWriteByte((com&0xf0)|WriteComEn);
  109.         i2cWriteByte((com&0xf0)|WriteCom);
  110.         i2cStop();Delay5us();                                                                                                //写完成,I2C停止信号
  111. }
  112. void LcdIni()                                                                                                                                        //1602初始化
  113.         {
  114.                         LcdCom(0x33);
  115.                         LcdCom(0x32);
  116.                         LcdCom(0x28);
  117.                         LcdCom(0x0c);
  118.                         LcdCom(0x01);
  119.                         LcdCom(0x80);
  120.         }
  121. void LcdData(uchar com)                                                                                                //LCD1602写数据
  122. {
  123.         i2cStart();                                                                                                                                        //I2C起始信号
  124.         i2cWriteByte(WriteAdd);                                                                                        //PCF8574A写地址
  125.         i2cWriteByte((com&0xf0)|WriteData);                                        //Delay5us();//先写LCD1602高4位指令+控制位
  126.         i2cWriteByte((com&0xf0)|WriteDataEn);                                //Delayms();//LCD1602  CS/EN接高送入
  127.         i2cWriteByte((com&0xf0)|WriteData);                                        //LCD1602  CS/EN拉低准备写入
  128.         com<<=4;                                                                                                                                                //Delay5us();//数据低4位左移到高4位
  129.         i2cWriteByte((com&0xf0)|WriteDataEn);                                //Delayms();//写入剩下的4位数据+控制位
  130.         i2cWriteByte((com&0xf0)|WriteData);                                        //写完成,I2C停止信号
  131.         i2cStop();Delay5us();
  132. }
  133. void LcdDisplay(uchar x,uchar *s)                                                        //1602显示字符串  //x=1显示在第一行,x=2显示在第二行
  134. {
  135.                 if(x==1)                //第一行
  136.                                 {                       
  137.                                         LcdCom(0x80);                                                                                                //第一行起始位置地址
  138.                                         while(*s)
  139.                                         {
  140.                                                 LcdData(*s);s++;
  141.                                         }
  142.                                 }
  143.                 if(x==2)                //第二行
  144.                                 {                       
  145.                                         LcdCom(0xc0);                                                                                                //第二行起始位置地址
  146.                                         while(*s)
  147.                                         {
  148.                                                 LcdData(*s);s++;
  149.                                         }
  150.                                 }
  151. }

  152. void main()
  153. {
  154.         Timer0Init();
  155.         LcdIni();

  156.        
  157. //        LcdDisplay(1,"  I LOVE YOU!");LcdDisplay(2," Do U Love Me?");
  158.        
  159.         while(1)
  160.                
  161.         {

  162.                 LcdCom(0x80);       
  163.                 if(hou>=24) {hou=0;}       
  164.                 if(sec>=60) {sec=0;min++;blk=~blk;}
  165.                 LcdBlk();
  166.         if(min>=60) {min=0;hou++;}
  167.                         LcdData(num[hou/10]);LcdData(num[hou%10]);        LcdData(':');
  168.                         LcdData(num[min/10]);LcdData(num[min%10]);LcdData(':');
  169.                         LcdData(num[sec/10]);LcdData(num[sec%10]);

  170.         }


  171.                
  172. }
  173. void InterruptT0 () interrupt 1
  174. {
  175.         us++;
  176.         if (us>=100)
  177.                 {
  178.                         us=0;
  179.                         ms++;
  180.                 }       
  181.         if(ms>=1000)
  182.                 {
  183.                         ms=0;
  184.                         sec++;
  185.                 }


  186.        
  187. }
复制代码



评分

参与人数 3黑币 +120 收起 理由
perfect123 + 15 赞一个!
ssfc + 5 赞一个!
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:112693 发表于 2017-4-25 23:03 | 只看该作者
程序是不是有问题??

Build target '目标 1'
linking...
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?DELAYMS?1602
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?I2CACK?1602
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_LCDDISPLAY?1602
Program Size: data=32.3 xdata=0 code=778
creating hex file from "1602"...
"1602" - 0 Error(s), 3 Warning(s).
回复

使用道具 举报

板凳
ID:749957 发表于 2020-5-12 16:14 | 只看该作者
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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