上次说了用IO口模拟I2C来读写24C02,现在说一下用硬件自带的I2C接口来读写24C02。
/**********************************************
i2c.h
*********************************************/
#ifndef _i2c_
#define _i2c_
void I2C_init(void);
void I2C_start(void);
void I2C_stop(void);
uint8 Send_a_byte(uint8 addr,uint8 wdata);
uint8 Recive_a_byte(uint8 addr);
void Delayxms(uint32 x);
#endif
/********************************************************
i2c.h
*****************************************************/
#include <iom8v.h>
#include "mytype.h"
#include "i2c.h"
/***************************************************************************************
延时Xms
*****************************************************************************************/
void Delayxms(uint32 x)
{
uint32 i;
while(x--)
{
i="1275";
while(i--);
}
}
void I2C_init(void)
{
TWCR&=~(1<<TWIE);//I2C关中断
TWBR=0X12;
TWSR=0X00;//SCL时钟50KHz
}
void I2C_start(void)
{
TWCR=(1<<TWSTA)|(1<<TWINT)|(1<<TWEN);//设为主模式,中断置位及使能。
}
void I2C_stop(void)
{
TWCR=(1<<TWSTO)|(1<<TWINT)|(1<<TWEN);//
}
uint8 Send_a_byte(uint8 addr,uint8 wdata)
{
I2C_start();
while(!(TWCR&0X80));//等待START发出
if((TWSR&0XF8)!=0X08)
return 1;
TWDR=0xa0;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&0X80));//等待数据发送完成及应答信号
if((TWSR&0XF8)!=0X18)
return 2;
TWDR=addr;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&0X80));//等待数据发送完成及应答信号
if((TWSR&0XF8)!=0X28)
return 3;
TWDR=wdata;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&0X80));//等待数据发送完成及应答信号
if((TWSR&0XF8)!=0X28)
return 3;
I2C_stop();
}
uint8 Recive_a_byte(uint8 addr)
{
uint8 rdata;
I2C_start();
while(!(TWCR&0X80));//等待START发出
if((TWSR&0XF8)!=0X08)
return 1;
TWDR=0xa0;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&0X80));//等待数据发送完成及应答信号
if((TWSR&0XF8)!=0X18)
return 2;
TWDR=addr;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&0X80));//等待数据发送完成及应答信号
if((TWSR&0XF8)!=0X28)
return 3;
I2C_start();
while(!(TWCR&0X80));//等待START发出
if((TWSR&0XF8)!=0X10)
return 4;
TWDR=0xa1;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&0X80));//等待数据发送完成及应答信号
if((TWSR&0XF8)!=0X40)
return 5;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&0X80));//等待数据发送完成及应答信号
rdata=TWDR;
if((TWSR&0XF8)!=0X58)
return 6;
I2C_stop();
return rdata;
}
/***************************************************
main.c
*****************************************************/
#include <iom8v.h>
#include "mytype.h"
#include "i2c.h"
uint8 table[16]={"0123456789abcdef"};
void main(void)
{
uint8 i,m;
uint16 j;
I2C_init();//I2C初始化。
Uart_init();//串口初始化。
Prints("System init completed...",1);
Send_a_byte(0x00,0x22);//地址0x00写入0x22.
Delayxms(5);
Send_a_byte(0x0f,0x55);//地址0x0f写入0x55.
Delayxms(5);
for(m=0x20;m<0x40;m++)//将地址0x20~0x3f写入0xaa。
{
Delayxms(5);
Send_a_byte(m,0xaa);
Delayxms(10);
//Send_abyte('*');
}
for(j=1;j<257;j++) //读取地址0x00~0xff的数据。
{
i=Recive_a_byte(j-1);
Delayxms(5);
//Send_a_byte(0x00,0xaa);
//Prints("Read addr 0xff, data 0x",0);
Send_abyte(table[i/16]);//发送读取值到串口。
Send_abyte(table[i%16]);
Send_abyte(' ');
if(j%16==0)//每行显示16个数。
Prints(" ",1);
}
while(1);
}
调试串口结果如下图:
工程文件见附件:
文章评论(0条评论)
登录后参与讨论