/*****************************************************************/
/* */
/*名称: 24C02读写程序 */
/*功能: 接收串口发来的数据,写到24C02里面 */
/* 再从24C02里读出刚写进的数据,由串口发出 */
/*难度等级: 高 */
/* 作者: 51kaifa */
/* 版权: http://www.51kaifa.com */
/*编写日期: 2006.05.21 */
/*****************************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCL=P1^0;//I2C时钟线
sbit SDA=P1^1;//I2C数据线
bit receive;//接收标志
bit re_finish;//接收一串字符完成标志
sbit LED = P1^2;//LED指示灯
uchar i,buffer[8];//串口缓冲区
uchar sbuffer,number;//发送字符个数
uchar sendFINS ;//发送完成标志
uchar copyOK , cmd_numb ;//发送缓冲区填充完成
extern void Start_I2c();
extern void Stop_I2c();
extern uchar RcvB();
void send(void);
void vGet_Send(void);
extern void Ack_I2c(bit a);
extern void SendB(uchar c);
extern void delay(unsigned int loop);
/*******************************系统初始化***********************/
void initial()
{ unsigned char j;
SCON=0x50; //串口工作方式1,允许接收
PCON=0x80; //波特率翻倍
TCON=0;
TMOD=0x26; //T1用于串口波特率控制
TL1=0xfa; //初始化T1,波特率为9600(晶振11.0592M)
TH1=0xfa;
TR1=1; //开定时器
EA=1; //开总中断
ES=1; //开串口中断
copyOK = 0; //缓冲区准备好标志清零
receive = 0; //接收标志清零
re_finish = 0; //接受完成标志清零
cmd_numb = 0; //接受计数器清零
for(j=0; j<8; j++) //串口缓冲区清空
buffer[i] = 0xff; //table[18]为空显示
}
/******************************主函数**************************/
main()
{
initial();
while(1){
if(re_finish){//接收一串字符完成
re_finish = 0;
vGet_Send();
}
}
}
/*****************************保存和串口发送**************************/
void vGet_Send(void)
{ uchar i;
Start_I2c();
SendB(0xa0);
SendB(0x10); //数据存放初始地址为0x06
for(i=0;i<6;i++)
{SendB(buffer[i]); //向24C02写6个数据
delay(2); }
Stop_I2c();
delay(1000);
for(i=0;i<8;i++)
buffer[i] = 0xff; //用0xff填充发送缓冲区
for(i=0;i<6;i++){
Start_I2c();
SendB(0xa0); //从24C02读取刚才写入的数据
SendB(0x10+i); //数据存放地址为0x06+i
Start_I2c();
SendB(0xa1);
buffer[i]=RcvB(); //读取的值送串口缓冲区
Ack_I2c(1);
Stop_I2c();
}
copyOK = 1; //置准备好标志
send(); //向串口发送
}
/*****************************串口发送***************************/
void send(void)//向串口发送字符串
{
if(copyOK) //串口准备好且缓冲区准备好
{
i = 0;
REN = 0; //发送过程中禁止接收数据
copyOK = 0; //清缓冲区准备好标志
SBUF = buffer[i++]; //发送字符串首字符
number = 7; //置发送计数器
}
else
return; //没准备好则返回
}
/***************************串口中断响应*************************/
void serial(void) interrupt 4//串口中断响应
{
if(RI)//为接收中断
{
RI=0; //清接收中断标志
LED = ~LED; //闪串口指示LED
sbuffer = SBUF; //读取串口缓冲区数据
if((sbuffer == 's') && (receive == 0)) //判断是否为数据头 ,是数据头则准备接收
{
receive = 1; //开始接收标志
cmd_numb = 0; //清接收计数器
re_finish = 0; //清接收完成标志
}
else if(sbuffer == 'e') //判断数据尾
{
re_finish = 1; //置接收完成标志
receive =0; //清接收标志
}
else if(receive){ //判断当前是否处于接收状态
buffer[cmd_numb++] = sbuffer-'0'; //当前字符送缓冲区
}
else //无效命令则返回
return;
}
else{
TI=0; //为单个字符发送完中断
if(!number) //字符串发送完
{ REN = 1; //允许接收
}
else{ //字符串未发送完
SBUF = buffer[i++]; //发送下一字符
number--; //发送字符数减一
}
}
}
/*****************************延时函数**************************/
void delay(unsigned int loop)
{ unsigned int i ; //loop 为执行空指令的次数,改变它可一改变延时时长
for(i=0;i<loop;i++);//循环执行空指令loop次,达到延时目的
}
/*******************************I2C开始*****************************/
void Start_I2c()
{
SDA=1;
delay(1);
SCL=1;
delay(3);
SDA=0;
delay(3);
SCL=0;
delay(1);
}
/*********************************I2C结束*****************************/
void Stop_I2c()
{
SDA=0;
delay(1);
SCL=1;
delay(3);
SDA=1;
delay(1);
}
/*********************************I2C写一个字节************************/
void SendB(uchar c)
{
uchar BitCnt,ack;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
if((c<<BitCnt)&0x80)SDA=1;
else SDA=0;
delay(2);
SCL=1;
delay(5);
SCL=0;
delay(2);
}
delay(1);
SDA=1;
delay(5);
SCL=1;
delay(1);
if(SDA==1)ack=0;
else ack=1;
SCL=0;
delay(1);
}
/******************************I2C读取一个字节****************************/
uchar RcvB()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
delay(1);
SCL=0;
delay(5);
SCL=1;
delay(2);
retc=retc<<1;
if(SDA==1)retc=retc+1;
delay(1);
}
SCL=0;
delay(1);
return(retc);
}
/*********************************I2C应答*********************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0;
else SDA=1;
delay(1);
SCL=1;
delay(2);
SCL=0;
delay(1);
}
/**********************************结束***********************************/