52单片机iic读写c语言,如何52单片机的I2C读写24C08程序问题排查修改
------波形在一樓
isoimg2130老師提供在單片機(jī)正常運(yùn)行的程序:
#include "reg52.h"
#include??"intrins.h"
typedef unsigned char u8;
sbit SCL=P2^1;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//I2C??時(shí)鐘
sbit SDA=P2^2;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//I2C??數(shù)據(jù)
void delay()? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//4微秒延時(shí)函數(shù)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
void yanshi(unsigned int hm)? ?? ?? ?? ?? ?? ?//延時(shí)毫秒
{
unsigned int i;
do
{
i = 12000000 / 97560;
while(--i)? ?? ???;
}
while(--hm);
}
void Start_I2c()
{
SDA=1;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //發(fā)送起始條件的數(shù)據(jù)信號
SCL=1;
delay();
SDA=0;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //發(fā)送起始信號
delay();
SCL=0;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
}
void Stop_I2c()
{
SCL=0;
SDA=0;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //發(fā)送結(jié)束條件的數(shù)據(jù)信號
delay();
SCL=1;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //結(jié)束條件建立時(shí)間大于4μs
SDA=1;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//發(fā)送I2C總線結(jié)束信號
delay();
}
u8 I2c_wait_ack(void)? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //等待應(yīng)答信號到來? ?? ?? ?1,接收應(yīng)答失敗 0,接收應(yīng)答成功
{
u8 Time=0;
SDA=1;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //準(zhǔn)備接收應(yīng)答位
_nop_();
SCL=1;
_nop_();
while(SDA)
{
Time++;
if(Time>250)
{
Stop_I2c();
return 1;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//無應(yīng)答返回1
}
}
SCL=0;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//時(shí)鐘輸出0
return 0;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//有應(yīng)答返回0
}
void??SendByte(u8??c)? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//字節(jié)數(shù)據(jù)發(fā)送函數(shù)
{
u8??BitCnt;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//條件 一定要開啟總線 保持SCL處于0狀態(tài) 才能進(jìn)行寫入
for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數(shù)據(jù)長度為8位
{
SDA=c<
_nop_();
SCL=1;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //置時(shí)鐘線為高,通知被控器開始接收數(shù)據(jù)位
_nop_();
SCL=0;
_nop_();
}
}
void I2C_Ack(void)? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//產(chǎn)生ACK應(yīng)答
{
SCL=0;
delay();
SDA=1;
delay();
SDA=0;
delay();
SCL=1;
delay();
SCL=0;
delay();
SDA=1;
delay();
}
void I2C_NAck(void)? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //不產(chǎn)生ACK應(yīng)答
{
SCL=0;
delay();
SDA=1;
delay();
SCL=1;
delay();
SCL=0;
delay();
SDA=0;
delay();
}
u8 RcvByte(u8 ack)? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //字節(jié)數(shù)據(jù)接收函數(shù)
{? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //ack??1 發(fā)送應(yīng)答??0 不發(fā)送應(yīng)答
u8 retc=0,i;
SDA=1;
delay();
for(i=0;i<8;i++)
{
SCL=0;? ?? ?? ?? ?? ?? ?? ?? ???//置時(shí)鐘線為低,準(zhǔn)備接收數(shù)據(jù)位
delay();
SCL=1;? ?? ?? ?? ?? ?? ?? ?? ???//置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效
_nop_();
retc<<=1;
if(SDA)retc++;? ?? ?? ?? ?? ?? ?? ? //讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中
_nop_();
}
if (!ack)
I2C_NAck();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//發(fā)送nACK
else
I2C_Ack();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //發(fā)送ACK
return retc;
}
u8 AT24C_Rcvone(u8 Addr)? ?? ?? ?? ?? ?? ?? ?? ?? ?//在AT24CXX指定地址讀出一個(gè)數(shù)據(jù)
{
u8 temp=0;
Start_I2c();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//啟動(dòng)總線
SendByte(0xa0);? ?? ?? ?? ?? ?? ?? ?? ?? ???//發(fā)送寫命令
I2c_wait_ack();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //等待應(yīng)答
SendByte(Addr);? ?? ?? ?? ?? ?? ?? ?? ?? ???//發(fā)送地址
I2c_wait_ack();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //等待應(yīng)答
Start_I2c();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//重新啟動(dòng)總線
SendByte(0xa1);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//設(shè)置為讀操作
I2c_wait_ack();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //等待應(yīng)答;
temp=RcvByte(0);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //讀字節(jié)? ?? ???非應(yīng)答
Stop_I2c();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//結(jié)束總線
return temp;
}
void AT24C_Sendone(u8 Addr,u8 Data)? ?? ???//在AT24CXX指定地址寫入一個(gè)數(shù)據(jù)? ?? ?? ?此函數(shù)只限于 c02-c16
{
Start_I2c();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //啟動(dòng)總線
SendByte(0xa0);? ?? ?? ?? ?? ?? ?? ?? ?? ? //發(fā)送寫命令
I2c_wait_ack();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//等待應(yīng)答
SendByte(Addr);? ?? ?? ?? ?? ?? ?? ?? ?? ? //發(fā)送地址
I2c_wait_ack();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//等待應(yīng)答
SendByte(Data);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//發(fā)送字節(jié)數(shù)據(jù)
I2c_wait_ack();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//等待應(yīng)答
Stop_I2c();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//結(jié)束總線
yanshi(10);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//如果是連續(xù)發(fā)送字節(jié)的時(shí)候這個(gè)延時(shí)很重要 否則將回傳錯(cuò)
}
void main()
{
AT24C_Sendone(10,0xaa);
P1=AT24C_Rcvone(10);
while(1);
}
下面是書本示例運(yùn)行沒有讀出數(shù)據(jù)led燈不亮:
I2C.H
#ifndef __I2C_H__? ?//文件名全部都大寫,首尾各添加2個(gè)下劃線”__”
#define __I2C_H__
#include
#define uchar unsigned char
sbit SDA=P2^0;??//24C02芯片SDA引腳位定義
sbit SCL=P2^2;? ?? ?? ?//24C02芯片SCL引腳位定義
void delay();? ?? ?? ?? ???//分別對各函數(shù)聲明
void start();
void stop();
void ack();
void nack();
void write_byte(uchar date);
uchar read_byte();
void write_at24c02(uchar address ,uchar date);
uchar read_at24c02(uchar address);
#endif
I2C.c
#include "i2c.h"??//包含i2c.h頭文件,注意自建的頭文件是用雙引號
void delay()? ?//微秒級延時(shí)函數(shù)
{
;;??//用兩個(gè)空語句實(shí)現(xiàn)短時(shí)間延時(shí),當(dāng)晶振為11.0592MHz時(shí),約4~5微秒
}
void start() //起始信號
{
SDA=1;
SCL=1;
delay();
SDA=0;
delay();
}
void stop()? ?? ???//終止信號
{
SDA=0;
SCL=1;
delay();
SDA=1;
delay();
}
void ack()? ?? ???//應(yīng)答信號
{
uchar i;
SCL=1;
delay();
while((SDA==1)&&i<250)i++;
SCL=0;
delay();
}
void nack()? ?? ?? ? //無應(yīng)答信號
{
SCL=1;
delay();
SDA=1;
SCL=0;
delay();
}
void??write_byte(uchar date) //寫入一個(gè)字節(jié)到I2C總線
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
SCL=0;
delay();
SDA=CY;
delay();
SCL=1;
}
SCL=0;
delay();
SDA=1;
delay();
}
uchar read_byte() //從I2C讀一個(gè)字節(jié)
{
uchar i,j,k;
SCL=0;
delay();
for(i=0;i<8;i++)
{
SCL=1;
delay();
j=SDA;
k=(k<<1)|j;
SCL=0;
delay();
}
return k;
}
void wrte_at2402(uchar address,uchar date)//at24c02按字節(jié)寫入函數(shù)
{
start();
write_byte(0xa0);
ack();
write_byte(address);
ack();
write_byte(date);
ack();
stop();
}
uchar read_dat24c02(uchar address)? ?? ???//對at24c02隨機(jī)讀函數(shù)
{
uchar date;
start();
write_byte(0xa0);
ack();
write_byte(address);
ack();
start();
write_byte(0xa1);
ack();
date=read_byte();
nack();
stop();
return date;
}
main.c
#include
#include"I2C.h"
#include
void delay_10ms()
{
uchar a,b;
for(a=50;a>0;a--)
for(b=200;b>0;b--) ;
}
void main()
{
start();
write_at24c02(10,0xaa);
delay_10ms();
P1=read_at24c02(10);
while(1);
}
總結(jié)
以上是生活随笔為你收集整理的52单片机iic读写c语言,如何52单片机的I2C读写24C08程序问题排查修改的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言100以内奇数的和为多少,编写C#
- 下一篇: 怎么用c语言写一个贪吃蛇,刚学C语言,想