?? iic.c
字號:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCL=P3^5;//I2C時鐘線
sbit SDA=P3^6;//I2C數據線
sbit PROM_CS=P3^4;//片選
sbit WP=P3^7;
bit receive;//接收標志
bit re_finish;//接收一串字符完成標志
sbit LED = P0^0;//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; //接受計數器清零
PROM_CS=0;
WP=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(6); //數據存放初始地址為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(6+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);
}
/**********************************結束***********************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -