||
1、程序功能:STM8单片机自带有I2C接口,可直接用于驱动AT24CXX系列存储芯片。本例程为STM8S1054S读写AT24CXX的驱动程序。
2、电路连接:STM8单片机的PE1(SCL)、PE2(SDA)分别与AT24CXX的SCL、SDA相连,采用外部晶振16M,IAR FOR STM8开发环境。
3、程序代码如下:
//-------------------------------------------------------------------
#include <iostm8s105s4.h>
#define uchar unsigned char
#define uint unsigned int
#define WD_DADR 0xa0
#define RD_DADR 0xa1
#define I2C_busy() while((I2C_SR3&0x02)==1);
#define I2C_start() I2C_CR2|=0x01;
#define I2C_stop() I2C_CR2|=0x02;
#define I2C_Ack() I2C_CR2|=0x04;
#define I2C_NAck() I2C_CR2&=(~0x04);
#define I2C_addrask (I2C_SR1&0x02)
#define I2C_SBask (I2C_SR1&0x01)
#define I2C_TxEask (I2C_SR1&0x80)
#define I2C_RxNeask (I2C_SR1&0x40)
#define I2C_BTF (I2C_SR1&0x04)
#define I2C_writebyte(x) I2C_DR=x;
uchar tmp;
/*--------I2C初始化-----------*/
void I2C_Init(void)
{
I2C_FREQR=0x0f; //设置频率寄存器
I2C_CCRH=0x00; //设置时钟寄存器高位
I2C_CCRL=0x50; //设置时钟寄存器低位
I2C_TRISER=0x11; //设置最大SCL上升时间
I2C_CR1|=0x01; //使能I2C模块
I2C_Ack(); //设置匹配应答
I2C_CR2|=0x08; //设置接收应答
}
void I2C_Start(void)
{
I2C_busy();
I2C_start();
while(I2C_SBask==0);
}
/*-------------传送地址---------------*/
void I2C_SendDAdr(uchar Add)
{
I2C_writebyte(Add);
while(I2C_addrask==0);
I2C_busy();
}
/*----------------发送数据------------------*/
void I2C_SendDat(uchar data)
{
I2C_writebyte(data);
I2C_busy();
while(I2C_TxEask==0);
}
/*---------------接收数据-------------------*/
uchar I2C_RcvDat(void)
{
uchar i;
while(I2C_RxNeask==0);
abc:
if(I2C_BTF==0x04)
{i=I2C_DR;}
else goto abc;
if(I2C_BTF==0){}
else goto abc;
return i;
}
/*--------------AT24CXX初始化------------*/
void AT24CXX_Init(void)
{
I2C_Init();
}
/*--------------写一字节---------------------*/
void AT24CXX_WriteAByte(uchar wordAdr,uchar dat)
{
I2C_Start();
I2C_SendDAdr(WD_DADR);
I2C_SendDat(wordAdr);
I2C_SendDat(dat);
I2C_stop();
}
/*--------------读一字节---------------------*/
uchar AT24CXX_ReadAByte(uchar wordAdr)
{
uchar dat;
I2C_Start();
I2C_SendDAdr(WD_DADR);
I2C_SendDat(wordAdr);
I2C_Start();
I2C_NAck();
I2C_SendDAdr(RD_DADR);
dat=I2C_RcvDat();
I2C_stop();
I2C_Ack();
return dat;
}
//延时程序
void Delay_ms( uint ms )
{
uint i,j;
for( j=0; j < ms; j++ )
{
for( i=0; i > 1000; i++ )
{;}
}
}
//时钟初始化
void CLK_Init(void)
{
CLK_ECKR=0x03; //外部时钟寄存器 外部时钟准备就绪,外部时钟开
CLK_SWCR=0x02; //切换控制寄存器 使能切换机制
CLK_SWR=0xB4; //主时钟切换寄存器 选择HSE为主时钟源*/
while (!(CLK_SWCR & 0x08));
CLK_CSSR=0x01; //时钟安全系统寄存器
}
//初始化
void Devices_Init(void)
{
Delay_ms(200);
CLK_Init();
AT24CXX_Init();
}
//主程序
void main( void )
{
Devices_Init();
AT24CXX_WriteAByte(0x01,0x60);
Delay_ms(10);
tmp=AT24CXX_ReadAByte(0x01);
Delay_ms(10);
while (1);
}