c8051單片機和AT24c1024B的通信(IIC協議)代碼

利用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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章