标题:
stm8用IIC读写24c02源程序
[打印本页]
作者:
mq-zlm
时间:
2017-3-15 09:06
标题:
stm8用IIC读写24c02源程序
给大家分享一个 stm8单片机用IIC总线方式读写24c02存储芯片 里面是自己写的程序
0.png
(50 KB, 下载次数: 52)
下载附件
2017-3-15 22:34 上传
完整源码下载:
4.I2C 24C02.rar
(396.59 KB, 下载次数: 85)
2017-3-15 09:05 上传
点击文件名下载附件
下载积分: 黑币 -5
下面是部分文件预览:
#include"i2c.h"
uint8_t receive[N],send[N]; //全局数组变量
void I2C_Start() //发送起始信号——在SCL为高电平期间,SDA由高拉低
{
SDA_OUT;
SDA_1;
SCL_1;
Delay_us(3);
SDA_0;
Delay_us(5);
SCL_0;
Delay_us(1);
}
void I2C_Stop() //结束信号——在SCL为高电平期间,SDA由低拉高
{
SDA_OUT;
SDA_0;
SCL_0;
Delay_us(1);
SCL_1;
Delay_us(3);
SDA_1;
Delay_us(5);
SCL_0;
Delay_us(1);
}
void I2C_Ack() //检测应答——第9个时钟周期时,由24C16将SDA拉低
{
SDA_1;
Delay_us(3);
SDA_IN;
Delay_us(1);
SCL_1;
Delay_us(2);
SCL_0;
Delay_us(3);
}
uint8_t I2C_Ack2() //检测应答2
{
SDA_1;
Delay_us(3);
SDA_IN;
Delay_us(2);
SCL_1;
Delay_us(2);
// while(SDA); //很快能完成应答,不需要等待,防止硬件故障导致出错
SCL_0;
Delay_us(2);
return SDA;
}
uint8_t I2C_Send(uint8_t buffer) //发送1个字节的数据
{
uint8_t temp = 0;
uint8_t BitCnt = 7;
SDA_OUT; //SDA为输出
Delay_us(1);
if((buffer&0x80)==0) //由高位开始发送
SDA_0;
else
SDA_1;
Delay_us(1);
SCL_1;
Delay_us(1);
temp = buffer<<1;
buffer = temp;
while(BitCnt)
{
if((buffer&0x80)==0)
{
SCL_0;
SDA_0;
}
else
{
SCL_0;
SDA_1;
}
Delay_us(3);
SCL_1;
Delay_us(2);
temp = buffer<<1;
buffer = temp;
BitCnt--;
}
SCL_0;
if(I2C_Ack2()) //发送8位数据后,检测应答 0:无应答 1:有应答
return 0;
else
return 1;
}
uint8_t I2C_Receive() //接收一个字节的数据
{
uint8_t ReceiveData,i;
SDA_IN; //SDA为输入
Delay_us(1);
for(i=0;i<8;i++) //SCL高电平时,记录SDA,由高位开始
{
SCL_1;
Delay_us(2); //延时的时间
if(SDA==0)
ReceiveData &= 0xfe;
else
ReceiveData |= 0x01;
if(i<7)
ReceiveData = ReceiveData<<1;
SCL_0;
Delay_us(1);
}
return ReceiveData;
}
void I2C_NoAck() //接收数据后不发送应答
{
SDA_1;
SDA_OUT;
SDA_1;
Delay_us(1);
SCL_1;
Delay_us(2);
SCL_0;
Delay_us(2);
SDA_0;
Delay_us(2);
}
void I2C_SendAck() //接收数据后发送应答,由主机发送,告知24C16已经接收到一个字节的数据
{
SDA_OUT;
SDA_0;
Delay_us(1);
SCL_1;
Delay_us(3);
SCL_0;
SDA_0;
Delay_us(2);
}
void I2C_Write_Byte(uint8_t addr,uint8_t data) //向24C06写入数据——单字节写
{
I2C_Start(); //起始信号
I2C_Send(0xa0); //发送器件地址
I2C_Send(addr); //发送字节地址
I2C_Send(data); //发送数据
I2C_Stop(); //结束信号
}
void I2C_Write_Page(uint8_t addr,uint8_t data) //向24C06写入数据——页写 16个字节
{
uint8_t i,j,k,p;
if((N/16)==0) //判断N是否小于16 是:一次页写即可完成 否:需要多次页写
{
I2C_Start(); //起始信号
I2C_Send(0xa0); //发送器件地址
I2C_Send(addr); //发送字节地址
for(j=0;j<N;j++)
{
send[j] = data+j;
I2C_Send(send[j]); //发送数据
}
I2C_Stop(); //结束信号
Delay_ms(5);
}
else //多次页写
{
for(i=0;i<(N/16);i++) //i次页写
{
I2C_Start(); //起始信号
I2C_Send(0xa0); //发送器件地址
I2C_Send(addr+i*16); //发送字节地址
for(j=0;j<16;j++)
{
send[i*16+j] = data+i*16+j;
I2C_Send(send[i*16+j]); //发送数据
}
I2C_Stop(); //结束信号
Delay_ms(5);
}
if(N%16) //写剩余的数据
{
p=N-(N%16);
I2C_Start(); //起始信号
I2C_Send(0xa0); //发送器件地址
I2C_Send(addr+p); //发送字节地址
for(k=0;k<(N%16);k++)
{
send[i*16+k] = data+i*16+k;
I2C_Send(send[i*16+k]); //发送数据
}
I2C_Stop(); //结束信号
Delay_ms(5);
}
}
}
void I2C_Read2(uint8_t add_start)//连续读
{
uint8_t i;
I2C_Start(); //起始信号
I2C_Send(0xa0); //发送器件地址——写
I2C_Send(add_start); //发送字节地址
I2C_Start(); //起始信号
I2C_Send(0xa1); //发送器件地址——读
for(i=0;i<N-1;i++)
{
receive[i]=I2C_Receive();
I2C_SendAck(); //主机发送应答,继续读
}
receive[i]=I2C_Receive();
I2C_NoAck(); //第九个周期发送不应答
I2C_Stop(); //停止信号
// return receive;
}
uint8_t I2C_Read(uint8_t addr) //从24C06读出数据
{
uint8_t receive;
I2C_Start(); //起始信号
I2C_Send(0xa0); //发送器件地址——写
I2C_Send(addr); //发送字节地址
I2C_Start(); //起始信号
I2C_Send(0xa1); //发送器件地址——读
receive=I2C_Receive(); //读出数据
I2C_Stop(); //停止信号,结束读数据操作
return receive;
}
void I2C_Ack_Check() //应答查询
{
I2C_Start();
I2C_Send(0xa0);
I2C_Ack2();
}
/*
void test_1(uint8_t add,uint8_t data) //单次测试
{
uint8_t test=0;
I2C_Write_Byte(add,data);
Delay_ms(5);
test = I2C_Read(add);
if(test==data)
LED = LED1;
else
LED = LED2;
}
void test_write(uint8_t add,uint8_t data) //测试_写
{
I2C_Write_Byte(add,data);
Delay_ms(5);
}
uint8_t test_read(uint8_t add) //测试_读
{
uint8_t test=0;
test = I2C_Read(add);
return test;
}
void test1(uint8_t add_start) //测试函数1
{
uint8_t read[N]={0},write[N]={0},i,k=0;
for(i=0;i<N;i++)
{
write[i]=0x02+i;
test_write(add_start+i,write[i]);
}
for(i=0;i<N;i++)
{
read[i]=test_read(add_start+i);
}
for(i=0;i<N;i++)
{
if(write[i]==read[i])
k+=1;
}
if(k==N)
LED = LED1;
else
LED = LED2;
}
*/
void test2(uint8_t add_start,uint8_t data) //测试函数2
{
uint8_t i,k=0;
I2C_Write_Page(add_start,data);
I2C_Read2(add_start);
for(i=0;i<N;i++)
{
if(receive[i]==send[i])
k+=1;
}
if(k==N)
LED = LED1;
else
LED = LED2;
for(i=0;i<N;i++)
{
receive[i]=0;
send[i]=0;
}
}
#pragma vector=5 //PA口的中断服务函数
__interrupt void PORTA_IRQHandler(void)
{
Delay_ms(20); //软件消抖
if(!(PA_IDR&0x04))
{
Delay_ms(20);
while(!(PA_IDR&0x04));
test2(0x00,0x06);
}
}
复制代码
作者:
windows100
时间:
2017-3-23 19:26
建议,延时加长,数据手册上说的是4.7us. 应答信号要加防出错标志,不等直接过,大批量的生产就会出问题
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1