#include <reg51.h>
#include <intrins.h>
#include <lcd1602.h>
#define uint unsigned int
#define uchar unsigned char
#define NOP4() {_nop_();_nop_();_nop_();_nop_();} //等待4个机器周期
uchar code LCDTable[8]={0x57,0x65,0x6c,0x63,0x6f,0x6d,0x65}; //英文字welcome的LCD编码
uchar code LCDNum[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //数字0~9的LCD编码
uchar code chip[8]={0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae}; //8片24c02的写地址编码
uchar code CITYNAME[8][10]={ //城市名字编码
{'B','e','i','J','i','n','g',' ',' ',' '},
{'G','u','a','n','g','Z','h','o','u',' '},
{'S','h','a','n','g','H','a','i',' ',' '},
{'S','h','e','n','Z','h','e','n',' ',' '},
{'X','i',' ','A','n',' ',' ',' ',' ',' '},
{'W','u','H','a','n',' ',' ',' ',' ',' '},
{'C','h','e','n','g','D','u',' ',' ',' '},
{'C','h','a','n','g','C','h','u','n',' '}};
uchar code Temperature[50]={0,1,2,3,4,5,6,7,8,9, //城市温度编码
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40,41,42,43,44,45,46,47,48,49,};
uchar chipdatanum[8]={0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,}; //记录每片24c02内有多少个数据,名字数据不计算在内,
//模拟初始化时有10个数据
sbit SCL=P1^6; //I2C时钟引脚
sbit SDA=P1^7; //I2C数据引脚
sbit UP=P1^3; //显示屏上翻查询
sbit DOWN=P1^4; //显示屏下翻查询
uchar rea; //读数据的临时变量
uchar P1state; //P1口状态,用于检测外来数据输入哪个rom
uchar avgtem[8]; //记录8个城市平均温度
uchar avgtemshow[8][2]; //转换成lcd显示格式
uchar temp[5]; //临时变量数组
uint sum; //温度和
uchar chipnum; //rom编号
uchar inputchipnum; //外来数据输入的rom编号
uchar PCFDATA[10]; //外来数据记录数组
uchar string1[16]; //用于送LCD数据的数组1
uchar string2[16]; //用于送LCD数据的数组2
void DelayMS(uint ms);
void Start() //I2C开始,SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号
{
SDA=1;
SCL=1;
NOP4();
SDA=0;
NOP4();
SCL=0;
}
void Stop() //I2C停止,SCL线为高电平期间,SDA线由低电平向高电平的变化表示停止信号
{
SDA=0;
SCL=0;
NOP4();
SCL=1;
NOP4();
SDA=1;
}
bit Check_ACK() //检查从机的应答信号,1为有应答,0为无应答
{
bit ack;
SDA=1;
NOP4();
SCL=1;
NOP4();
SCL=0;
ack=SDA;
return !ack;
}
void Read_ACK() //读取应答,传完一个字节后等待从机应答
{
SDA=1;
NOP4();
SCL=1;
NOP4();
SCL=0;
}
void ACK() //发送应答信号
{
SDA=0;
_nop_();
_nop_();
SCL=1;
NOP4();
SCL=0;
}
void NO_ACK() //发送非应答信号
{
SDA=1;
_nop_();
SCL=1;
NOP4();
SCL=0;
SDA=0;
}
void Write_A_Byte(uchar b) // 向24C16 中写一字节数据
{
uchar i;
for(i=0;i<8;i++)
{
b<<=1;
SDA=CY;
_nop_();
SCL=1;
NOP4();
SCL=0;
}
Read_ACK();
}
//向第chip片24c02的片内addr地址写数据,写入的数据位pointor数组的第location开始的num个字符
void Write_I2C(uchar chip,uchar addr,uchar* pointor,uchar location,uchar num) // 向指定地址写数据
{
uchar i;
Start();
Write_A_Byte(chip); //1010 0000 发出写数据指令,0xa0 前7 位是地址,第8位0是主机发送数据
Write_A_Byte(addr); //先选择地址
for(i=0;i<num;i++)
{
Write_A_Byte(pointor[location]);
location++;
}
Stop();
DelayMS(10);
}
void Read_A_Byte() // 从SDA 中读一字节数据,存入变量rea中
{
uchar temp;
uchar i;
rea=0x00;
for(i=0;i<8;i++)
{
SDA=1;
NOP4();
SCL=1;
NOP4();
temp=SDA; //读数据
rea=rea|temp;
if(i<7)
rea<<=1;
SCL=0;
}
}
void Read_I2C(uchar chip,uchar address,uchar num,uchar* pointor) // 向第chip个24c02的片内address地址读num个字符,
//存入单片机的pointor数组
{
uchar k;
Start();
Write_A_Byte(chip); //1010 0000 发出读数据指令,0xa0 前7 位是地址,第8位0是主发送数据
Write_A_Byte(address); //发送片内地址
Start();
Write_A_Byte(chip+0x01); //1010 0000 发出读数据指令,0xa0 前7 位是地址,第8位0是主发送数据
for(k=0;k<num;k++)
{
Read_A_Byte();
pointor[k]=rea;
if(k<num-1)
ACK();
}
NO_ACK(); //发送非应答信号
Stop();
DelayMS(10);
}
void PCFRead_I2C(uchar chip) // 向PCF8574读一个字节
{
Start();
Write_A_Byte(chip+0x01); //1010 0000 发出读数据指令,0xa0 前7 位是地址,第8位0是主发送数据
Read_A_Byte();
PCFDATA[0]=rea;
NO_ACK(); //发送非应答信号
Stop();
DelayMS(10);
}
void Getavgtem(uchar chipnum,uchar address,uchar num) //从相应的rom中调出数据计算平均温度
{
uchar k;
sum=0x0000;
num=chipdatanum[chipnum];
Start();
Write_A_Byte(chip[chipnum]); //1010 0000 发出读数据指令,0xa0 前7 位是地址,第8位0是主发送数据
Write_A_Byte(address); //发送片内地址
Start();
Write_A_Byte(chip[chipnum]+0x01); //1010 0000 发出读数据指令,0xa0 前7 位是地址,第8位0是主发送数据
for(k=0;k<num;k++)
{
Read_A_Byte();
sum=sum+rea;
if(k<num-1)
ACK();
}
NO_ACK(); //发送非应答信号
Stop();
DelayMS(10);
avgtem[chipnum]=sum/num;
}
void DelayMS(uint ms) //延时
{
uchar i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
void NEWIN()interrupt 0 //外部0中断,运用第一组寄存器,PCF8574拓展IO,外部数据输入中断
{
P1state=P1;
inputchipnum=P1state&0x07; //检测rom编号
PCFRead_I2C(0x40); //读外来数据到单片机中
Write_I2C(chip[inputchipnum],0x10+chipdatanum[inputchipnum],PCFDATA,0,1); //把外来数据存入相应rom中
chipdatanum[inputchipnum]=chipdatanum[inputchipnum]+1;
DelayMS(100);
}
void main()
{
uchar p;
EA=1; //系统开中断
EX0=1; //允许外部中断
IT0=0; //外部中断0为电平触发方式
chipnum=0;
Write_I2C(0xa0,0x00,CITYNAME[0],0,10); // 向24C04 第1片写入beijing
Write_I2C(0xa0,0x10,Temperature,7,10); // 向24C04 第1片写入温度
Write_I2C(0xa2,0x00,CITYNAME[1],0,10); // 向24C04 第1片写入guangzhou
Write_I2C(0xa2,0x10,Temperature,20,10); // 向24C04 第1片写入温度
Write_I2C(0xa4,0x00,CITYNAME[2],0,10); // 向24C04 第1片写入shanghai
Write_I2C(0xa4,0x10,Temperature,15,10); // 向24C04 第1片写入温度
Write_I2C(0xa6,0x00,CITYNAME[3],0,10); // 向24C04 第1片写入shenzhen
Write_I2C(0xa6,0x10,Temperature,23,10); // 向24C04 第1片写入温度
Write_I2C(0xa8,0x00,CITYNAME[4],0,10); // 向24C04 第1片写入xi an
Write_I2C(0xa8,0x10,Temperature,20,10); // 向24C04 第1片写入温度
Write_I2C(0xaa,0x00,CITYNAME[5],0,10); // 向24C04 第1片写入wuhan
Write_I2C(0xaa,0x10,Temperature,26,10); // 向24C04 第1片写入温度
Write_I2C(0xac,0x00,CITYNAME[6],0,10); // 向24C04 第1片写入chengdu
Write_I2C(0xac,0x10,Temperature,23,10); // 向24C04 第1片写入温度
Write_I2C(0xae,0x00,CITYNAME[7],0,10); // 向24C04 第1片写入changchun
Write_I2C(0xae,0x10,Temperature,5,10); // 向24C04 第1片写入温度
LcdInitiate(); //调用LCD初始化函数
Read_I2C(chip[chipnum],0x00,10,string1);
WriteAddress(0x05); //将显示地址指定为第1行第8列
for(p=0;p<10;p++)
WriteData(string1[p]); //显示城市名字
Getavgtem(chipnum,0x10,chipdatanum[c
I2C.rar_I2C proteus_keil i2c仿真_proteus I2C_proteus I2C使用_单片机I2C仿
版权申诉
172 浏览量
2022-09-23
13:02:15
上传
评论
收藏 64KB RAR 举报
weixin_42653672
- 粉丝: 93
- 资源: 1万+
最新资源
- 基于串口通信的光通信上位机,包括运动控制和通信协议
- 串口与以太网文件传送协议(或自定义控制协议)
- Qt开发windows系统安装教程与代码实例.txt
- QT6实现的附带文件传输协议的串口终端
- 一个串口通讯类和调用Demo 通过设置串口、设置串口自定义协议,可方便对串口发送数据与接收数据
- 华为OD模拟题及参考答案.仅供学习和模拟考试使用
- stm32f103c8t6基于modbus协议和使用串口读取温湿度
- 英雄联盟LOL金克斯4K电脑壁纸
- Microbrain道闸产品上位机,以MahApps库为基础搭建界面,集成了串口(UART)、CAN、WIFI通信,十六进制协议
- Android串口通讯, 支持发送数据回调, 支持并发处理, 自定义协议, CRC校验, 自动粘包, 自动去除冗余的干扰数据
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈