久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機iic連續(xù)讀取epprom出錯的問題解決
[打印本頁]
作者:
maowentao0416
時間:
2018-9-3 09:32
標題:
單片機iic連續(xù)讀取epprom出錯的問題解決
現(xiàn)象:單個讀取字符正確,連續(xù)讀取字符出錯環(huán)境:stc89c52單片機 24C02的epprom
我的解決辦法:
IIC_wirte 8bit時等待ack,如無ack,則stop-->start 重新發(fā)起信號,結(jié)果解決問題,下面貼出代碼:
#include <reg52.h>
#include "intrins.h"
#include "type.h"
#include "i2c.h"
sbit SCL=P2^1;
sbit SDA=P2^0;
#define IIC_WRITE 0xA0
#define IIC_READ 0xA1
static void delay10Us(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函數(shù)名 : Delay10us()
* 函數(shù)功能 : 延時10us
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
/*
void Delay10us()
{
}
*/
/*******************************************************************************
* 函數(shù)名 : I2cStart()
* 函數(shù)功能 : 起始信號:在SCL時鐘信號在高電平期間SDA信號產(chǎn)生一個下降沿
* 輸入 : 無
* 輸出 : 無
* 備注 : 起始之后SDA和SCL都為0
*******************************************************************************/
void I2cStart()
{
SCL=0;
delay10Us(1);
SDA=1;
SCL=1;
delay10Us(1);//建立時間是SDA保持時間>4.7us
SDA=0;
delay10Us(1);//保持時間是>4us
}
/*******************************************************************************
* 函數(shù)名 : I2cStop()
* 函數(shù)功能 : 終止信號:在SCL時鐘信號高電平期間SDA信號產(chǎn)生一個上升沿
* 輸入 : 無
* 輸出 : 無
* 備注 : 結(jié)束之后保持SDA和SCL都為1;表示總線空閑
*******************************************************************************/
void I2cStop()
{
SCL=0;
delay10Us(1);
SDA=0;
SCL=1;
delay10Us(1);
SDA=1;
delay10Us(1);
}
/*******************************************************************************
* 函數(shù)名 : I2cSendByte(unsigned char dat)
* 函數(shù)功能 : 通過I2C發(fā)送一個字節(jié)。在SCL時鐘信號高電平期間,保持發(fā)送信號SDA保持穩(wěn)定
* 輸入 : num
* 輸出 : 0或1。發(fā)送成功返回1,發(fā)送失敗返回0
* 備注 : 發(fā)送完一個字節(jié)SCL=0,SDA=1
*******************************************************************************/
unsigned char I2cSendByte(unsigned char dat)
{
unsigned char a=0,b=0;//最大255,一個機器周期為1us,最大延時255us。
SCL=0;
delay10Us(1);
for(a=0;a<8;a++)//要發(fā)送8位,從最高位開始
{
SDA = dat>>7; //起始信號之后SCL=0,所以可以直接改變SDA信號
dat = dat<<1;
delay10Us(1);
SCL=1;
delay10Us(2);
SCL=0;
delay10Us(1);
}
SDA=1;
delay10Us(1);
SCL=1;
while(SDA)//等待應答,也就是等待從設(shè)備把SDA拉低
{
b++;
if(b>200) //如果超過2000us沒有應答發(fā)送失敗,或者為非應答,表示接收結(jié)束
{
return 0;
}
delay10Us(1);
}
return 1;
}
/*******************************************************************************
* 函數(shù)名 : I2cReadByte()
* 函數(shù)功能 : 使用I2c讀取一個字節(jié)
* 輸入 : 無
* 輸出 : dat
* 備注 : 接收完一個字節(jié)SCL=0,SDA=1.
*******************************************************************************/
unsigned char I2cReadByte()
{
unsigned char a=0,dat=0;
SCL = 0;
delay10Us(1);
SDA=1; //起始和發(fā)送一個字節(jié)之后SCL都是0
delay10Us(1);
for(a=0;a<8;a++)//接收8個字節(jié)
{
SCL=1;
delay10Us(2);
dat<<=1;
dat|=SDA;
SCL=0;
delay10Us(1);
}
return dat;
}
/*******************************************************************************
* 函數(shù)名 : void At24c02Write(unsigned char addr,unsigned char dat)
* 函數(shù)功能 : 往24c02的一個地址寫入一個數(shù)據(jù)
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void At24c02Write(unsigned char addr,unsigned char dat)
{
unsigned char ret;
again:
I2cStart();
ret = I2cSendByte(IIC_WRITE);//發(fā)送寫器件地址
if(!ret){
I2cStop();
goto again;
}
ret = I2cSendByte(addr);//發(fā)送要寫入內(nèi)存地址
if(!ret){
I2cStop();
goto again;
}
ret = I2cSendByte(dat); //發(fā)送數(shù)據(jù)
if(!ret){
I2cStop();
goto again;
}
I2cStop();
}
/*******************************************************************************
* 函數(shù)名 : unsigned char At24c02Read(unsigned char addr)
* 函數(shù)功能 : 讀取24c02的一個地址的一個數(shù)據(jù)
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
unsigned char ret;
again:
I2cStart();
ret = I2cSendByte(IIC_WRITE); //發(fā)送器件寫地址
if(!ret){
I2cStop();
goto again;
}
ret = I2cSendByte(addr); //發(fā)送要讀取的地址
if(!ret){
I2cStop();
goto again;
}
I2cStart();
ret = I2cSendByte(IIC_READ); //發(fā)送讀器件地址
if(!ret){
I2cStop();
goto again;
}
num=I2cReadByte(); //讀取數(shù)據(jù)
NoAck();
I2cStop();
return num;
}
/*
非應答
*/
void NoAck(void)
{
SCL=0;
SDA=1;
delay10Us(1);
SCL=1;
delay10Us(2);
}
/*
應答信號
*/
void Ack(void)
{
SCL=0;
SDA=0;
delay10Us(1);
SCL=1;
delay10Us(2);
}
/*******************************************************************************
* 函數(shù)名 : unsigned char At24c02Read(unsigned char addr)
* 函數(shù)功能 : 讀取24c02的一個地址的一個數(shù)據(jù)
* 輸入 : 無
* 輸出 : -1:error 0:success
*******************************************************************************/
void At24c02ReadBytes(unsigned char addr,unsigned char *dat,unsigned char n)
{
//unsigned char num = n;
unsigned char ret;
again:
I2cStart();
ret=I2cSendByte(0xa0); //發(fā)送寫器件地址
if(!ret){
I2cStop();
goto again;
}
ret=I2cSendByte(addr); //發(fā)送要讀取的地址
if(!ret){
I2cStop();
goto again;
}
I2cStart();
ret=I2cSendByte(0xa1); //發(fā)送讀器件地址
if(!ret){
I2cStop();
goto again;
}
if(addr + n >256)
{
n = 256 - addr;
}
while(n--)
{
*dat = I2cReadByte(); //讀取數(shù)據(jù)
if(n!=0) Ack();
dat++;
}
I2cStop();
//return num;
}
/*******************************************************************************
* 函數(shù)名 : unsigned char At24c02Read(unsigned char addr)
* 函數(shù)功能 : 讀取24c02的一個地址的一個數(shù)據(jù)
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
/*******************************************************************************
* 函數(shù)名 : void At24c02ReadBytes2(unsigned char addr,unsigned char *dat,unsigned char n)
* 函數(shù)功能 : 從地址addr開始,連續(xù)讀取n個字符,讀取字符放入dat中
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void At24c02ReadBytes2(unsigned char addr,unsigned char *dat,unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
dat[i]= At24c02Read(addr+i);
}
/*******************************************************************************
* 函數(shù)名 : void At24c02ReadBytes2(unsigned char addr,unsigned char *dat,unsigned char n)
* 函數(shù)功能 : 將dat中的字符寫入addr開始的epprom中去,寫入n個
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void At24c02WriteBytes(unsigned char addr,unsigned char *dat,unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
{
At24c02Write(addr+i,dat[i]);
}
}
復制代碼
上訴代碼的關(guān)鍵點在
I2cSendByte
這個方法有返回值,當I2cSendByte的返回值是1說明成功
1、在At24c02Write函數(shù)中利用goto語句來處理
寫
出錯;
2、At24c02Read 利用goto語句來處理地址寫出錯
3、At24c02ReadBytes 同上
總結(jié):
1、在iic的連續(xù)read過程一定要有ACK
2、起始信號之后的器件地址寫,存儲器地址、器件地址讀 這三個地址時,確保收到epprom發(fā)來的ack
單片機交流學習群:
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
香蕉久久久
|
免费永久av
|
亚洲高清三级
|
国产亚洲精品久久久久动
|
91在线精品秘密一区二区
|
男人的天堂中文字幕
|
在线免费观看视频黄
|
在线视频一区二区三区
|
欧美中国少妇xxx性高请视频
|
免费亚洲网站
|
国产一级一片免费播放
|
中文视频在线
|
a在线视频
|
成人一区二区三区在线观看
|
国产精品美女一区二区三区
|
天天天堂
|
污片在线免费观看
|
美女福利网站
|
伊人久久大香线
|
国产情侣激情
|
中文精品视频
|
欧美二区三区
|
中文字幕 国产
|
天堂一区
|
国产精品久久久久久亚洲调教
|
欧美中文字幕一区二区三区亚洲
|
午夜影院在线播放
|
在线观看中文字幕
|
欧美a区
|
中文字字幕一区二区三区四区五区
|
久久9久
|
免费日韩网站
|
亚洲精品一区中文字幕
|
亚洲国产高清免费
|
欧美日韩欧美
|
羞羞的视频在线
|
玖操
|
免费a v网站
|
亚洲一区二区精品视频
|
久久国产成人精品国产成人亚洲
|
国产一级片免费视频
|