模拟I2C读写24C256、PCF8563

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

模拟I2C读写24C256、PCF8563
#include stdio.h//包含文件
#include reg52.h
#include intrins.h
#includeserial.h
#include“i2c.h"
#define Byte unsigned char//宏定义
#define uint unsigned int
#define uchar unsigned char
#define device_16bit_Waddress 0xa0//器件写数据地址24c256
#define device_16bit_Raddress 0xa1//器件读数据地址24c256
#define device_8bit_Waddress 0xa2 //定义*****的写数据地址
#define device_8bit_Raddress 0xa3 //定义*****的读数据地址
#define debug 0
/*sbit SCL= P3^5;
sbit SDA =P3^4;*/
/*sbit SCL= P1^5;
sbit SDA =P1^6;*/
sbit SCL= P3^4;
sbit SDA =P3^3;
/*延时子程序,大概10ms左右*/
void delay()
{
uint i,j;
for(i=0;ii++)
{
for(j=0;j1000;j++)
{
;
}
}
}
/*开始I2C数据发送或接收*/
void Start_I2C()//在时钟线为高,数据线从高电平跳到低电平时,开始传送
{
SDA=1; //数据先
_nop_(); //延时一段时间
_nop_();
SCL=1; //时钟线为高,等数据线下降才开始
_nop_();
_nop_();
_nop_();
_nop_();
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
SDA=0; //数据线下降拉,启动了
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*结束数据传送*/
void Stop_I2C()
{
SDA=0; //时钟线为高时,数据线上升沿为结束信号
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*发送字节子程序,入口参数为要发送的数据,无返回变量,分8位进行发送*/
void Sent_Byte(Byte Data)
{
Byte BitCount; //定义发送的位数
for(BitCount=0;BitCountBitCount++)
{
_nop_();
if((DataBitCount)0x80) SDA=1;//移位判断发送的数据是1还是0
else SDA=0;
_nop_();
_nop_();
SCL=1; //置位SCL,通知从器件开始接收数据,SCL上升沿发数据
_nop_(); //SCL为1,数据线电平不能变
_nop_();
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
_nop_();
_nop_();
SCL=0; //钳住总线,等下次接收
}
}
/*应答子程序,无入口参数,返回值是应答位*/
bit Ack_Check()
{
SDA=1; //先置时钟线为高,第九位数据过来会强行把数据线拉低
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
F0=SDA; //将数据线上的该位保存到F0中
SCL=0;
if(F0==1)
return 1;//没有应答,返回1,否则返回0
else return 0;
}
/*接收字节子函数,先接收高位,再接收低位无入口参数,返回值是一个无符号型的一个8位的数*/
Byte Rec_Byte()
{
Byte BitCount, RecData=0;
for(BitCount=0;BitCountBitCount++)
{
SDA=1; //数据线先给1的话,如果从器件发0给主器件
_nop_(); //SDA会拉低,那主器件接收到的为0,否则不拉低,接收到的为1
_nop_(); //这相当释放数据总线一样
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
F0=SDA; //用F0来保存当前数据线上的值SCL=0;
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
if(F0)
{
RecData=RecData1;
RecData=RecData|0x01;
}
else RecData=RecData1;
}
return(RecData);
}
/*发送数据子函数,入口参数是16位的器件地址和要发送的数据,无返回值*/
Sent_Data16(uint address,Byte Data)
{
bit ack_temp; //响应寄存位
uchar addr_H,addr_L;
addr_H=(uchar)(address8);
addr_L=(uchar)(address0x00ff) ;
Start_I2C(); //启动传送
Sent_Byte(device_16bit_Waddress);//先发送器件地址
ack_temp=Ack_Check(); //接收应答位
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n");
}
}
Sent_Byte(addr_H); //再发送内存地址高八位
ack_temp=Ack_Check(); //接收应答位
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n");
}
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
Sent_Byte(addr_L); //再发送内存地低八位
ack_temp=Ack_Check(); //接收应答位
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n"); }
}
Sent_Byte(Data); //发送数据
ack_temp=Ack_Check(); //接收应答位if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n"); }
Stop_I2C(); //停止
}
/*接收数据子程序,入口参数是从器件的16位内存地址,返回值是读到的值*/
Byte Rec_Data16(uint address)
{
Byte RecByte; //定义接收到的数
bit ack_temp; //响应位
uchar addr_H,addr_L;
addr_H=(uchar)(address8);
addr_L=(uchar)(address0x00ff) ;
Start_I2C(); //开化信号
Sent_Byte( device_16bit_Waddress);//先进行一次伪写操作ack_temp=Ack_Check(); //接收应答位
if(debug==1)
{
if(ack_temp==0)
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
SendCommString("ACK OK\r\n");
else
{
SendCommString("ACK ERROR\r\n"); }
}
Sent_Byte(addr_H); //再发送内存地址ack_temp=Ack_Check();
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n"); }
}
Sent_Byte(addr_L); //再发送内存地址ack_temp=Ack_Check();
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n");
}
}
Start_I2C(); //再一次启动信号
Sent_Byte( device_16bit_Raddress);//发送器件读地址ack_temp=Ack_Check();
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
SendCommString("ACK ERROR\r\n");
}
}
RecByte=Rec_Byte(); //接收数据
/*ack_temp=Ack_Check();//一个字节一个字节读不需要应答if(ack_temp==1)
{
SendCommString("ACK OK\r\n");
}
else {
SendCommString("ACK ERROR\r\n");
}*/
Stop_I2C(); //停止信号
return(RecByte);
}
/*发送数据子函数,入口参数是8位器件地址和要发送的数据,无返回值*/
Sent_Data8(Byte address,Byte Data)
{
bit ack_temp; //响应寄存位
Start_I2C(); //启动传送
Sent_Byte(device_8bit_Waddress);//先发送器件地址ack_temp=Ack_Check(); //接收应答位
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n");
}
}
Sent_Byte(address); //再发送内存地址
ack_temp=Ack_Check(); //接收应答位
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
SendCommString("ACK ERROR\r\n");
}
}
Sent_Byte(Data); //发送数据
ack_temp=Ack_Check(); //接收应答位
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n");
}
Stop_I2C(); //停止
}
/*接收数据子程序,入口参数是8位从器件的内存地址,返回值是读到的值*/
Byte Rec_Data8(address)
{
Byte RecByte; //定义接收到的数
bit ack_temp; //响应位
Start_I2C(); //开化信号
Sent_Byte(device_8bit_Waddress);//先进行一次伪写操作
ack_temp=Ack_Check(); //接收应答位
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n");
}
Sent_Byte(address); //再发送内存地址
ack_temp=Ack_Check();
if(debug==1)
{
if(ack_temp==0)
{
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n");
}
}
Start_I2C(); //再一次启动信号
Sent_Byte(device_8bit_Raddress );//发送器件读地址
ack_temp=Ack_Check();
if(debug==1)
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n"); }
}
RecByte=Rec_Byte(); //接收数据
ack_temp=Ack_Check();
if(debug==1)
{
if(ack_temp==0)
{
SendCommString("ACK OK\r\n");
}
else
{
SendCommString("ACK ERROR\r\n");
}
Stop_I2C(); //停止信号
return(RecByte);
}
main()
{
Byte xdata i, m;
serial_init();
T0_init();
if(debug==1)
{
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
SendCommString("serial ok\r\n");
}
Sent_Data16(0x0020,13);//向从器件地址发四个数据
delay();
Sent_Data16(0x0021,14);
delay();
Sent_Data16(0x0022,15);
delay();
Sent_Data16(0x0023,16);
delay();
m=Rec_Data16(0x0020);//将接收到的数据保存在一个数组中
m=Rec_Data16(0x0021);
m=Rec_Data16(0x0022);
m=Rec_Data16(0x0023);
ES=0;
TI=0;
for(i=0;ii++) //通过串行口对接收到的数显示
{
SBUF=m[i];
while(!TI); //串行发送
TI=0;
}
ES=1;
/*Sent_Data8(0x00,1);//向从器件地址发四个数据
delay();
Sent_Data8(0x01,2);
delay();
Sent_Data8(0x02,3);
delay();
Sent_Data8(0x03,4);
delay();
m=Rec_Data8(0x00);//将接收到的数据保存在一个数组中
m=Rec_Data8(0x01);
m=Rec_Data8(0x02);
m=Rec_Data8(0x03);
ES=0;
TI=0;
for(i=0;ii++) //通过串行口对接收到的数显示
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
{
SBUF=m[i];
while(!TI); //串行发送
TI=0;
}
ES=1;*/
while(1); //等待
}
串口部分:
#include "reg52.h"
#include "intrins.h"
#include "serial.h"
#define uchar unsigned char
#define uint unsigned int
uchar rec_data;//上位机传来的命令数据长度为:4(STAR)+4(TEST等)+3(010长度等)+data+2(CRC)+3(END),16+data,数据长度暂时定为30 uchar xdata send_data;//由于上传数据时data比较长,有数字通道数据和模拟通道数据还有开关量通道数据
uchar rec_over_flag;//接收串行口0和串行口1一帧数据结束标志
uchar xdata send_num,send_length;//232需要发送的数据的长度和还需要发送的长度uchar rec_tail;//接受232数据时保存是接受第几个数据的变量
/*发送一帧232数据子程序*/
void SendCommString(unsigned char *base)
{
if (base==0) return;
for (;;)
{
if (base[send_length]==0) break;
send_data[send_length]=base[send_length];
send_length++;
}
SBUF=send_data;
send_num=send_length;
while(send_length!=0);
}
/*串行口初始化函数*/
void serial_init()//初始化串行口函数,设置串行口波特率为9600,8位数据位,一位停止位,无校验位
{ //使用T1做波特率发生器
SCON|=0x50;//8位异步收发,允许串行口接收数据,TI和RI 初始化为0
PCON=0x80; // SMOD = 1;
SCON = 0x50; // Mode 1, 8-bit UART, enable receiption ***** TH1=0xfd;
TL1=0xfd;
模拟I2C总线读写24C256和*****,扩展成读写一切I2C总线的设备
TR1=1;
TMOD|=0x20;//8Bit
ES=1;
EA=1;
}
/*定时器0初始化*/
void T0_init(void)
{
TMOD|=0x01;//初始化定时器0包括T0的工作方式为1,初值为定时10ms,开中断TH0=(*****-*****)/256;
TL0=(*****-*****)%256;
ET0=1;
}
/*定时器0中断服务函数*/
void t0_isp(void) interrupt 1
{
TF0=0;//定时器0中断标志清零
TR0=0;//关闭计数器
rec_over_flag=1;//10ms没有新数据,需要将接收到得数据打包
rec_data[rec_tail]=0;//结束标志
rec_tail=0;
}
/*串行口中断服务函数*/
void serial_isp(void )interrupt 4//串行口中断服务函数,接收上位机的命令或下位机的数据{
if(RI)//接收到了新数据
{
TH0=(*****-*****)/256;
TL0=(*****-*****)%256;
TR0=1;
RI=0;
rec_data[rec_tail]=SBUF;
rec_tail++;
}
if(TI)
{
TI=0;
send_length=send_length-1;
if(send_length!=0)
{
SBUF=send_data[send_num-send_length];。

相关文档
最新文档