找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2941|回复: 5
收起左侧

LCD1602使用PCF8574ATLLC的单片机驱动 求指导

[复制链接]
ID:202803 发表于 2018-5-23 16:56 | 显示全部楼层 |阅读模式
          已经写了两天了,也借鉴了网上的例子,但是还是没成功,以前用16根线的时候还是蛮好弄的!,请教各位大佬,帮忙看一下我的程序是哪里有问题,也麻烦知道一下,谢谢了!
  1. #include <STC12C5A60S2.H>
  2. #include "sys.h"
  3. #define         LCD_ADD                0x3F


  4. void IIC_Start(void);
  5. void IIC_Stop(void);
  6. void IIC_Ask(void);
  7. void IIC_NAsk(void);
  8. bit IIC_Wait_Ack(void);        
  9. void IIC_Send_Byte(uint8_t dat);
  10. uint8_t IIC_Read_Byte(bit ack);
  11. void Enable_LCD_write(void);
  12. bit LCD_Write_CMD(uint8_t cmd);
  13. bit LCD_Write_Data(uint8_t value);
  14. void Show_string(unsigned char x,unsigned char y,unsigned char *s);



  15. sbit SCL = P1^0;
  16. sbit SDA = P1^1;
  17. sbit LED = P1^2;


  18. //开始
  19. void IIC_Start(void)
  20. {
  21.         SDA = 1;
  22.         SCL = 1;
  23.         Delay2us();
  24.         SDA = 0;
  25.         Delay5us();
  26.         SCL = 0;
  27. }


  28. //停止
  29. void IIC_Stop(void)
  30. {        
  31.         SCL = 0;
  32.         SDA = 0;
  33.         Delay5us();
  34.         SCL = 1;
  35.         SDA = 1;
  36.         Delay2us();
  37.         SCL = 0;
  38.         
  39. }

  40. //答应
  41. void IIC_Ack(void)
  42. {
  43.         SCL = 0;
  44.         SDA = 0;
  45.         Delay5us();
  46.         SCL = 1;
  47.         Delay5us();
  48.         SCL = 0;
  49. }

  50. //不答应
  51. void IIC_NAck(void)
  52. {
  53.         SCL = 0;
  54.         SDA = 1;
  55.         Delay5us();
  56.         SCL = 1;
  57.         Delay5us();
  58.         SCL = 0;
  59. }

  60. //等待答应
  61. bit IIC_Wait_Ack(void)
  62. {
  63.         uint8_t temp = 0;
  64.         SDA = 1;
  65.         Delay2us();
  66.         SCL = 1;
  67.         Delay5us();
  68.         while(SDA)
  69.         {
  70.                 temp++;
  71.                 if(temp>250)
  72.                 {
  73.                         IIC_Stop();
  74.                         return 1;                //没有答应返回1
  75.                 }
  76.         }
  77.         SCL = 0;
  78.         return 0;                        //有答应,返回0
  79. }

  80. //发动1个字节
  81. void IIC_Send_Byte(uint8_t dat)
  82. {
  83.         uint8_t t;
  84.         SCL = 0;
  85.         for(t=0;t<8;t++)
  86.         {
  87.                 SDA = (dat&0x80)>>7;
  88.                 dat=dat<<1;
  89.                 SCL = 1;
  90.                 Delay2us();
  91.                 SCL= 0;
  92.                 Delay2us();
  93.         }
  94. }

  95. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  96. uint8_t IIC_Read_Byte(bit ack)
  97. {
  98.         uint8_t i,receive = 0;
  99.         for(i=0;i<8;i++)
  100.         {
  101.                 SCL = 0;
  102.                 Delay2us();
  103.                 SCL = 1;
  104.                 receive<<=1;
  105.                 if(SDA)
  106.                 {
  107.                         receive++;
  108.                 }
  109.                 Delay2us();
  110.         }
  111.         if(!ack)
  112.         {
  113.                 IIC_NAck();
  114.         }
  115.         else
  116.         {
  117.                 IIC_Ack();
  118.         }
  119.         return receive;
  120. }


  121. //*************************液晶写命令************************
  122. bit LCD_Write_CMD(uint8_t cmd)
  123. {
  124.         uint8_t LCD_cmd = 0x0C;
  125.         uint8_t LCD_EN;
  126.         uint8_t        Cmd_Temp;
  127.         Cmd_Temp = cmd;
  128.         cmd=cmd<<4;                 //低四位移到高四位
  129.         cmd = cmd|LCD_cmd;
  130.         
  131.         IIC_Start();   //启动总线
  132.         IIC_Send_Byte(LCD_ADD<<1|0); //发送器件地址
  133.     if(IIC_Wait_Ack())
  134.         {
  135.                 IIC_Stop();
  136.                 LED = 0;
  137.                 return 1;
  138.         }
  139.         
  140.         IIC_Send_Byte(cmd);                //发送低四位数据
  141.     if(IIC_Wait_Ack())
  142.         {
  143.                 IIC_Stop();
  144.                 return 1;
  145.         }
  146.         Delay1s();
  147.         
  148.         cmd = Cmd_Temp|LCD_cmd;
  149.         IIC_Send_Byte(cmd);                //发送高四位数据
  150.     if(IIC_Wait_Ack())
  151.         {
  152.                 IIC_Stop();
  153.                 return 1;
  154.         }
  155.         Delay1s();
  156.         
  157.         LCD_EN |=(1<<(3-1));                //E = 1
  158.         IIC_Send_Byte(LCD_EN);                //发送使能数据
  159.         Delay2us();
  160.         LCD_EN &=~(1<<(3-1));                //E = 0
  161.         IIC_Send_Byte(LCD_EN);                //发送使能数据
  162.         Delay2us();
  163.         
  164.         IIC_Stop(); //结束总线
  165.         return 0;
  166. }

  167. //*************写数据****************************
  168. bit LCD_Write_Data(uint8_t dat)
  169. {
  170.         uint8_t LCD_dat = 0x09;
  171.         uint8_t LCD_EN;
  172.         uint8_t        Dat_Temp;
  173.         dat = Dat_Temp;
  174.         dat=dat<<4;                 //低四位移到高四位
  175.         dat = dat|LCD_dat;

  176.         IIC_Start();   //启动总线
  177.         IIC_Send_Byte(LCD_ADD<<1|0); //发送器件地址
  178.     if(IIC_Wait_Ack())
  179.         {
  180.                 IIC_Stop();
  181.                 LED = 0;
  182.                 return 1;
  183.         }
  184.         
  185.         IIC_Send_Byte(dat);                //发送低四位数据
  186.     if(IIC_Wait_Ack())
  187.         {
  188.                 IIC_Stop();
  189.                 return 1;
  190.         }
  191.         Delay1s();

  192.         dat = Dat_Temp|LCD_dat;
  193.         IIC_Send_Byte(dat);                //发送高四位数据
  194.     if(IIC_Wait_Ack())
  195.         {
  196.                 IIC_Stop();
  197.                 return 1;
  198.         }
  199.         Delay1s();
  200.         
  201.         LCD_EN |=(1<<(3-1));                //E = 1
  202.         IIC_Send_Byte(LCD_EN);                //发送使能数据
  203.         Delay2us();
  204.         LCD_EN &=~(1<<(3-1));                //E = 0
  205.         IIC_Send_Byte(LCD_EN);                //发送使能数据
  206.         Delay2us();
  207.         
  208.         
  209.         IIC_Stop(); //结束总线
  210.     return        0;
  211. }


  212. //**********************显示字符串*****************************
  213. void Show_string(unsigned char x,unsigned char y,unsigned char *s)
  214. {
  215.         unsigned char position;
  216.         
  217.         if (y == 0)
  218.         {
  219.                 position = 0x80 + x;
  220.         }
  221.         
  222.         else
  223.         {
  224.                 position = 0xc0 + x;
  225.         }
  226.                
  227.     LCD_Write_CMD(position);
  228.         while (*s)
  229.          {     
  230.                 LCD_Write_Data(*s);     
  231.                 s++;     
  232.          }
  233. }

  234. int main(void)
  235. {
  236.         Delay1s();
  237.         LCD_Write_CMD(0x28);
  238.         LCD_Write_CMD(0x28);
  239.         Delay1s();

  240.         LCD_Write_CMD(0x0C);        
  241.         LCD_Write_CMD(0x0C);
  242.         Delay1s();
  243.         LCD_Write_CMD(0x01);
  244.         LCD_Write_CMD(0x01);
  245.         Delay1s();
  246.         while(1)
  247.         {
  248.                
  249.         }
  250. }
复制代码
以上就是我的全部程序了,本想将IIC和1602的程序单独写的,但是那样报错所以就没那样写了!只是在SYS.h里面定义了数据类型和延时函数!请各位大佬帮忙解答一下,谢谢了!
回复

使用道具 举报

ID:151348 发表于 2018-5-23 21:28 | 显示全部楼层
这个程序用11.0592MHz晶振,查查你这个PCF芯片的地址是多少,不同后缀的地址不同
回复

使用道具 举报

ID:71233 发表于 2019-3-4 15:10 | 显示全部楼层
你没有写入命令到8574的IO口。上楼的朋友说对了,要清楚芯片的地址。
回复

使用道具 举报

ID:94031 发表于 2019-3-4 17:45 | 显示全部楼层
先要 LCD_Init();初始化,再调用子程序显示字符,我看你就没有初始化。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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