当前位置: 代码迷 >> 综合 >> Proteus IIC协议(PCF8574芯片) 仿真 LCD1602 C51 代码
  详细解决方案

Proteus IIC协议(PCF8574芯片) 仿真 LCD1602 C51 代码

热度:8   发布时间:2023-12-26 18:02:37.0

阅读以下代码,需具备以下条件:
1. Keil与Proteus联调。

单一主程序如下,不需其他头、库文件。

#include <reg51.h>
#include <intrins.h>sbit SCL = P3^3;
sbit SDA = P3^4;/*
void Delay()        //5us,标准51单片机适用,@12.000MHz
{_nop_();_nop_();_nop_();_nop_();_nop_();
}
void Delay6ms()        //标准51单片机适用,@12.000MHz
{unsigned char i, j;i = 12;j = 169;do{while (--j);} while (--i);
}
*/void Delay()        //5微秒,STC15W单片机适用,@12.000MHz
{unsigned char i;_nop_();_nop_();i = 12;while (--i);
}
void Delay6ms()        //STC15W 单片机适用@12.000MHz
{unsigned char i, j;i = 71;    //71j = 6;do{while (--j);} while (--i);
}void IIC_Start()
{SDA=1;SCL=1;Delay();SDA=0;Delay();SCL=0;
}
bit IIC_Get_Ack()
{bit ackOK;SDA=1;//释放总线SCL=1;Delay();ackOK=!SDA;SCL=0;return ackOK;
}
void IIC_Stop()
{SDA=0;SCL=1;Delay();SDA=1;Delay();
}void IIC_Write_Byte(unsigned char dat)
{unsigned char i; for(i=0;i<8;i++){SDA=dat&(0x80>>i);         //先写入高位SCL=1;Delay();SCL=0;}
}void LcdWriteCmd(unsigned char com)                //写命令函数
{unsigned char com1,com2;com1=com|0x0f;com2=com<<4;com2=com2|0x0f;IIC_Start();IIC_Write_Byte(0x4e); //bin(0x27<<1) 0x4e 8574 芯片IIC_Get_Ack();IIC_Write_Byte(com1&0xfc);IIC_Get_Ack();IIC_Write_Byte(com1&0xf8);IIC_Get_Ack();IIC_Write_Byte(com2&0xfc);IIC_Get_Ack();IIC_Write_Byte(com2&0xf8);IIC_Get_Ack();IIC_Stop();   
}void LcdWriteDat(unsigned char dat)                //写数据函数
{unsigned char date1,date2;date1=dat|0x0f;date2=dat<<4;date2=date2|0x0f;IIC_Start();IIC_Write_Byte(0x4e); //bin(0x27<<1) 0x4e 8574 芯片IIC_Get_Ack();IIC_Write_Byte(date1&0xfd);IIC_Get_Ack();IIC_Write_Byte(date1&0xf9);IIC_Get_Ack();IIC_Write_Byte(date2&0xfd);IIC_Get_Ack();IIC_Write_Byte(date2&0xf9);IIC_Get_Ack();IIC_Stop();             
}void InitLcd()
{LcdWriteCmd(0x33);Delay6ms(); LcdWriteCmd(0x32);Delay6ms(); LcdWriteCmd(0x28); //16*2 显示,5*7 点阵,4 位数据接口Delay6ms(); LcdWriteCmd(0x0C); Delay6ms();LcdWriteCmd(0x0E); //文字不动,地址自动+1Delay6ms();LcdWriteCmd(0x01); //清屏Delay6ms();
}// 设置显示 RAM 起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 
void LcdSetCursor(unsigned char x, unsigned char y)
{unsigned char addr;if (y == 0){ //由输入的屏幕坐标计算显示 RAM 的地址addr = 0x00 + x; //第一行字符地址从 0x00 起始}else{addr = 0x40 + x; //第二行字符地址从 0x40 起始}LcdWriteCmd(addr | 0x80); //设置 RAM 地址
}
// 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针  void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{LcdSetCursor(x, y); //设置起始地址while (*str != '\0'){ //连续写入字符串数据,直到检测到结束符LcdWriteDat(*str++); //先取 str 指向的数据,然后 str 自加 1}
}void main()
{unsigned char mystr[]="Hello World!";InitLcd();LcdShowStr(0,0,mystr);LcdShowStr(3,1,mystr);while(1);
}

???????

  相关解决方案