原创 AVR(Mega8)的study:6、用IO口模拟I2C读写24C02

2008-3-10 21:14 4558 3 3 分类: MCU/ 嵌入式

现在I2C总线的器件多如牛毛,应用非常的广泛。虽然Mega8自带I2C接口,这个我们下章再说。我们还是先来看看IO口模拟的I2C总线,相信你看完之后,一定可以对时序等有更进一步的认识,会对I2C协议有更好的了解。


/**********************************************


24C02.h


***********************************************/



#ifndef _at24c02_
#define _at24c02_


#define SDA 4   //选用PORTC4
#define SCL 5   //选用PORTC5


#define PORT1 PORTC
#define PIN1 PINC
#define DDR1 DDRC
#define SDA_0 PORT1&=~(1<#define SDA_1 PORT1|=(1<#define SCL_0 PORT1&=~(1<#define SCL_1 PORT1|=(1<

#define in_SDA ((1<


void Delay(void);
void Delayxms(uint32 x);
void Start(void);
void Stop(void);
uint8 Wait_answer();
void Send_answer(void);
void Send_noanswer(void);
void Send_abyte(uint8 data);
uint8 Receive_abyte(void);
void Write_abyte(uint8 addr,uint8 data);
uint8 Read_abyte(uint8 addr);
void Write_string(uint8 *string,uint8 addr,uint8 n);
void Read_string(uint8 addr,uint8 n);


#endif


/***********************************************


24c02.c


***************************************************/


#include
#include "mytype.h"
#include "24c02.h"
#include "uart.h"
extern uint8 systemerror;
uint8 read_a_string[6];
/**************************************
delay
****************************************/
void Delay(void)//短延时。
{
uint8 i;
for(i=0;i<100;i++);
}


/***************************************************************************************
 延时Xms
*****************************************************************************************/
void Delayxms(uint32 x)
{
 uint32 i;
 while(x--)
  {
i=1275;
   while(i--);
  }
}


/******************************************************
start
*****************************************************/
void Start(void)//开始信号。
{
SDA_1;
SCL_1;//bus free
Delay();
SDA_0;
Delay();
SCL_0;
}


/******************************************
stop
******************************************/
void Stop(void)//停止信号。
{
SCL_0;
SDA_0;
Delay();
SCL_1;
Delay();
SDA_1;
}


/*************************************************


*****************************************************/
uint8 Wait_answer()//等待应答。
{
uint8 i;
DDR1=0xef;
SCL_1;
while((in_SDA!=0)&&(i<20))
{
//Prints("No ack...",1);
i++;
if(i==19)
return 11;//如果没有应答,返回11.
}
SCL_0;
DDR1=0xff;
//Prints("ack...",1);
}


/*******************************************


*******************************************/
void Send_answer(void)//发送应答信号。
{
SDA_0;
Delay();
SCL_1;
Delay();
SCL_0;
}


/********************************************


************************************************/
void Send_noanswer(void)//发送无应答信号。
{
SDA_1;
Delay();
SCL_1;
Delay();
SCL_0;
//Prints("Read over...",1);
}



/***********************************************


********************************************************/
void Send_abyte(uint8 data)//发送一个字节到总线。
{
uint8 i;
for(i=0;i<8;i++)//循环写入
{
SCL_0;
Delay();
if(data&0x80)//高位优先
SDA_1;
else
SDA_0;
data<<=1;
Delay();
SCL_1;
Delay();
}
SCL_0;
}


/******************************************************


********************************************************/
uint8 Receive_abyte(void)//从总线接收一个字节。
{
uint8 i;
uint8 data;
data=0;
DDR1=(DDR1&(~(1<//SDA_1;
for(i=0;i<8;i++)
{
data<<=1;
SCL_0;
Delay();
SCL_1;
Delay();
if(in_SDA)
data=data+1;
else ;
}
SCL_0;
DDR1|=((1<return(data);
}
/****************************************************
写一个字节到24C02.
*******************************************************/
void Write_abyte(uint8 addr,uint8 data)
{
Start();
Send_abyte(0xa0);//发送写命令
Wait_answer();//等待应答
Send_abyte(addr);//发送写的地址
Wait_answer();
Send_abyte(data);//发送写的数据
Wait_answer();
Stop();//停止总线
Delayxms(10);
}
/***************************************************************
从24C02读取一个字节。
****************************************************************/
uint8 Read_abyte(uint8 addr)
{
uint8 readdata;
Start();
Send_abyte(0xa0);//发送写命令
Wait_answer();
Send_abyte(addr);//发送要读取的地址
Wait_answer();
Start();//重复开始
Send_abyte(0xa1);//发送读取命令
Wait_answer();
readdata=Receive_abyte();//接受数据
Send_noanswer();//发送接收无应答
Stop();
return (readdata);
}
/***********************************************************
读取一字符串。
*************************************************************/
void Read_string(uint8 addr,uint8 n)
{
uint8 i;
Start();
Send_abyte(0xa0);
Wait_answer();
Send_abyte(addr);
Wait_answer();
Start();
Send_abyte(0xa1);
Wait_answer();
for(i=0;i<n;i++)


{
read_a_string=Receive_abyte();
Send_answer();
}
Send_noanswer();
Stop();
}


/***************************************************


写入一个字符串,最多8个。
****************************************************/
void Write_string(uint8 *string,uint8 addr,uint8 n)
{
uint8 i;
Start();
Send_abyte(0xa0);
Wait_answer();
Send_abyte(addr);
Wait_answer();
Delayxms(10);
for(i=0;i<n;i++)


{
Send_abyte(*string);
Wait_answer();
Delayxms(10);
//Send_a_byte('*');
string++;
}
Stop();


}


/********************************************************


main.c


**********************************************************/


#include
#include "mytype.h"
#include "24c02.h"
#include "uart.h"



uint8 systemerror;
uint8 table[16]={"0123456789abcdef"};
extern uint8 read_a_string[6];
uint8 str[6]={'1','2','3','4','5','6'};
void main(void)
{
uint8 i;
uint16 j;
Uart_init();
DDR1=(DDR1|((1<Prints("System init completed...",1);
Write_abyte(0x00,0xaa);
Prints("Write addr 0x00, data 0xaa...",1);
Delayxms(3);
Write_abyte(0x0f,0x00);
Prints("Write addr 0x0f, data 0x00...",1);
Delayxms(3);
for(j=0x20;j<0x40;j++)//写数据0xbb到地址ox20~ox3f.
{
Write_abyte(j,0xbb);
Delayxms(3);
}
for(j=1;j<=256;j++)//读取0x00~0xff的数据。
{
i=Read_abyte(j-1);
Delayxms(10);
//Prints("Read addr 0x00, data ",0);
Send_a_byte(table[i/16]);//发送数据到串口。
Send_a_byte(table[i%16]);
Send_a_byte(' ');
if(j%16==0)//每行显示16个数据。
Prints("  ",1);
}
while(1);
}


由于实验板没有带回,所以现在无法发串口实验图片,有了在补上。


工程文件如下:


点击下载

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条