利用51單片機的I/O口來模擬IIC協議,加深對其時序的理解,其次學習AT24c1024b的讀寫方法.已經通過運行代碼如下:
#include <reg51.h>
#include<intrins.h>//包含_nop_()函數
#define CTL_R 0xa1//AT24讀控制
#define CTL_W 0xa0//AT24寫控制
sbit SCL=P1^6;
sbit SDA=P1^7;
void Delay(int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<1000;j++);
}
void delay(void) //延時>4us
{
_nop_();//空指令
_nop_();
_nop_();
_nop_();
}
void IIC_start(void)//IIC開始
{
SDA=1;
SCL=1;
delay();
SDA=0;
delay();
SCL=0;
}
void IIC_stop(void)//IIC結束
{
SDA=0;
SCL=1;
delay();
SDA=1;
delay();
SCL=0;
}
void IIC_ACK(void)//發送應答ACK=0
{
SDA=0;
SCL=1;
delay();
SCL=0;
SDA=1;
}
void IIC_nACK(void)//發送非應答
{
SDA=1;
SCL=1;
delay();
SCL=0;
}
int IIC_CACK() //檢查應答
{
int C=0;
while(C!=SDA);
SCL=1;
delay();
SCL=0;
return C;
}
void IIC_send(char n)//字節發送
{
int i;
char tmp=n;
for(i=0;i<8;i++)
{
SDA=(bit)(tmp>>7);//發送一個字節的高位
SCL=1;
delay();
tmp<<=1;
SCL=0;
}
}
char IIC_rec(void)//字節接收
{
int i;
char tmp=0;
for(i=0;i<8;i++)
{
tmp <<=1;
tmp |=SDA;
SCL=1;
delay();
SCL=0;
}
return tmp;
}
void IIC_W_AT24C1024B(int n,short int ADDR,char *from)//多字節發送
{
int i;
IIC_start();
do
IIC_send(CTL_W);
while(IIC_CACK());//等待應答
do
IIC_send((char)(ADDR>>4));//1字節高位地址
while(IIC_CACK());//等待應答
do
IIC_send((char)ADDR);//1字節低位地址
while(IIC_CACK());//等待應答
for(i=0;i<n;i++)
{
do
IIC_send(*from);//發送一個字節
while(IIC_CACK());//等待應答
from++;
}
IIC_stop();
}
void IIC_R_AT24C1024B(int n,short int ADDR,char to[])//多字節接收
{
int i;
IIC_start();
do
IIC_send(CTL_W);
while(IIC_CACK());//等待應答
do
IIC_send((char)(ADDR>>4));//1字節高位地址
while(IIC_CACK());//等待應答
do
IIC_send((char)ADDR);//1字節低位地址
while(IIC_CACK());//等待應答
IIC_start();
do
IIC_send(CTL_R);
while(IIC_CACK());//等待應答
for(i=0;i<n;i++)
{
to[i]=IIC_rec();//接收一個字節
if(n!=i)
IIC_ACK();//發送應答
else
IIC_nACK();
}
IIC_stop();
}
char a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//0~F的字形碼
char s[16]={0};
int main(void)
{
int i;
IIC_W_AT24C1024B(16,0x0020,a);
Delay(30);
IIC_R_AT24C1024B(16,0x0020,s);
for(i=0;i<15;i++)
{
P3=b[i];
Delay(60);
}
}
硬件接圖如下:
實現過程原來蠻簡單,就是時序要把握好,特別是單片機作爲收機的時候,應答信號ACK完成記得釋放總線SDA(爲1)