標(biāo)題:
我的單片機(jī)+iic程序怎么讀寫(xiě)不了? 搞了好幾天搞不明白
[打印本頁(yè)]
作者:
YANGTAIHUAN
時(shí)間:
2022-3-11 19:41
標(biāo)題:
我的單片機(jī)+iic程序怎么讀寫(xiě)不了? 搞了好幾天搞不明白
求求大佬們看看哪出問(wèn)題了,1602模塊沒(méi)問(wèn)題 仿真里讀出來(lái)的是一個(gè)黑塊
at24c02.c
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCK = P1^3;
sbit SDA = P1^4;
void Delayms(uint x);
void Delayus(uchar x);
void Delay5us();
void Delay5ms();
void init(){
SCK = 1;
_nop_();_nop_();_nop_();
SDA = 1;
_nop_();_nop_();_nop_();
}
void start(){
SCK = 1;
_nop_();_nop_();_nop_();
SDA = 1;
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
SDA = 0;
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
SCK = 0;
}
void stop(){
SCK =1;
SDA = 0;
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
SDA = 1;
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
SDA = 0;
SCK = 0;
}
void WaitAck(){
uchar i = 0;
SDA = 1;
SCK = 1;
Delayus(5);
while(SDA == 1 && (i < 250))
i++;
SCK = 0;
_nop_(), _nop_(), _nop_();
}
//void react(){
// SCK = 0;
// SDA = 1;
// SDA = 0;
// SCK = 1;
// _nop_();_nop_();_nop_();
// _nop_();_nop_();_nop_();
// SCK = 0;
// SDA = 1;
//}
void noack(){
SDA=1;
_nop_();_nop_();_nop_();
SCK=1;
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
SCK=0;
_nop_();_nop_();_nop_();
SDA = 0;
}
uchar readByte(){
uchar i, k = 0;
for(i = 0; i < 8; i++){
SCK = 0;
k <<= 1;
Delay5us();
if(SDA == 1){
k |= 0x01;
}
SCK = 0;
Delay5us();
}
_nop_();
Delay5ms();
return k;
}
void writeByte(uchar dat){
uchar i = 0;
for(i = 0; i < 8; i++){
SCK = 0;
Delay5us();
SDA = dat & 0x80;
_nop_();_nop_();_nop_();_nop_();
SCK = 1;
Delay5us();
dat <<= 1;
}
SCK = 0;
_nop_();_nop_();_nop_();
Delay5ms();
}
void addByte(uchar wordAddress, uchar dat){
start();
writeByte(0xa0);
WaitAck();
writeByte(wordAddress);
WaitAck();
writeByte(dat);
WaitAck();
stop();
Delayms(5);
}
uchar readAddByta(uchar wordAddress){
uchar dat;
start();
writeByte(0xa0);
WaitAck();
writeByte(wordAddress);
WaitAck();
stop();
start();
writeByte(0xa1);
WaitAck();
dat = readByte();
noack();
stop();
return dat;
}
void Delayms(uint x){
int i, j;
for(i = x; i > 0; --i){
for(j = 110; j > 0; --j);
}
}
void Delayus(uchar x){
while(x--);
}
void Delay5us() //@12.000MHz
{
_nop_();
}
void Delay5ms() //@12.000MHz
{
unsigned char i, j;
i = 10;
j = 183;
do
{
while (--j);
} while (--i);
}
復(fù)制代碼
main.c
#include <reg52.h>
#include <intrins.h>
#include "at24c02.h"
#include "proteus_1602.h"
#define uchar unsigned char
#define uint unsigned int
sbit SCK = P1^3;
sbit SDA = P1^4;
void main(){
Delayms(2000);
while(1){
uchar temp = 0;
init();
init_1602();
addByte(0x00, 0x00);
Delayms(10);
temp = readAddByta(0x00);
writeData_1602(temp + 0x38);
Delayms(50);
}
}
復(fù)制代碼
作者:
YANGTAIHUAN
時(shí)間:
2022-3-11 19:42
1602模塊沒(méi)問(wèn)題 仿真里讀出來(lái)的是一個(gè)黑塊
作者:
tatachaoren
時(shí)間:
2022-3-12 02:56
IIC的時(shí)序很重要,最好嘗試的用邏輯分析儀讀一下時(shí)序,看看是不是時(shí)序出現(xiàn)問(wèn)題,還有如果時(shí)序沒(méi)問(wèn)題的話,要看時(shí)間,比如起始信號(hào),一高一低時(shí)間會(huì)不會(huì)太短,導(dǎo)致從機(jī)識(shí)別不了IIC的起始信號(hào)等等。
作者:
lkc8210
時(shí)間:
2022-3-12 08:09
要貼就貼全一點(diǎn)
為什么不把a(bǔ)t24c02.h/proteus_1602.h/proteus_1602.c也貼上來(lái)?
void WaitAck(){
uchar i = 0;
SDA =
0
;
SCK = 1;
Delayus(5);
while(SDA == 1 && (i < 250))
i++;
SCK = 0;
_nop_(), _nop_(), _nop_();
}
作者:
wolfinn
時(shí)間:
2022-3-13 10:53
讀寫(xiě)兩句間加個(gè)延時(shí)看看,器件兩個(gè)動(dòng)作要有間隔的。
作者:
Lxy18
時(shí)間:
2022-3-13 11:56
iic通信和晶振頻率24c02的地址都有關(guān)系,錯(cuò)一點(diǎn)都可能導(dǎo)致通信失敗。
分享一下自用的驅(qū)動(dòng)程序,僅供參考。
晶振12MHz或者11.0592MHz,24c02的3個(gè)地址全接地。
at24c02.c
#include "at24c02.h"
#include "delay.h"
//IIC啟動(dòng)
void Start(void)
{
SDA1=1;
Delay_Us(2);
SCL1=1;
Delay_Us(2);//建立時(shí)間是SDA保持時(shí)間>4.7us
SDA1=0;
Delay_Us(2);//保持時(shí)間是>4us
SCL1=0;
Delay_Us(2);
}
//IIC停止
void Stop(void)
{
SDA1=0;
Delay_Us(2);
SCL1=1;
Delay_Us(2);//建立時(shí)間大于4.7us
SDA1=1;
Delay_Us(4);
}
//IIC發(fā)送字節(jié)
//dat:要發(fā)送的字節(jié)
void Send_Byte(unsigned char dat)
{
unsigned char a=0,b=0;
for(a=0;a<8;a++)//要發(fā)送8位,從最高位開(kāi)始
{
SDA1=dat>>7; //起始信號(hào)之后SCL=0,所以可以直接改變SDA信號(hào)
dat=dat<<1;
Delay_Us(2);
SCL1=1;
Delay_Us(2);//建立時(shí)間>4.7us
SCL1=0;
Delay_Us(2);//時(shí)間大于4us
}
}
//IIC檢查應(yīng)答
bit Check_Ack(void)
{
//unsigned char t;
SCL1=0;
SDA1=1;
Delay_Us(2);
SCL1=1;
Delay_Us(2);
CY=SDA1;
SCL1=0;
Delay_Us(2);
return(CY);
}
//IIC應(yīng)答
void Ack(void)
{
SDA1=0; //EEPROM通過(guò)在收到每個(gè)地址或數(shù)據(jù)之后
SCL1=1; //置SDA低電平的方式確認(rèn)表示收到讀SDA口狀態(tài)
Delay_Us(1);
SCL1=0;
Delay_Us(1);
SDA1=1;
}
//IIC無(wú)應(yīng)答
void NoAck(void)
{
SDA1=1;
SCL1=1;
Delay_Us(1);
SCL1=0;
}
//IIC接收字節(jié)
unsigned char Receive_Byte(void)
{
unsigned char a=0,dat=0;
SDA1=1; //起始和發(fā)送一個(gè)字節(jié)之后SCL都是0
Delay_Us(2);
for(a=0;a<8;a++)//接收8個(gè)字節(jié)
{
SCL1=1;
Delay_Us(2);
dat<<=1;
dat|=SDA1;
Delay_Us(2);
SCL1=0;
Delay_Us(2);
}
return dat;
}
//At24cxx讀寫(xiě)數(shù)據(jù)
//addr:要讀/寫(xiě)數(shù)據(jù)的地址
//*dat:要讀/寫(xiě)的數(shù)據(jù)
//length;數(shù)據(jù)的長(zhǎng)度
//RW:1:寫(xiě),0:讀
void At24c02_RW(unsigned char addr,unsigned char *dat,unsigned char length,bit RW)
{
Start();
Send_Byte(0xa0);//發(fā)送寫(xiě)器件地址
Check_Ack();
Send_Byte((unsigned char)addr);//發(fā)送要寫(xiě)入內(nèi)存地址
Check_Ack();
if(RW) //寫(xiě)
{ while(length--)
{
Send_Byte(*dat++);
Check_Ack();
}
}
else
{
Start();
Send_Byte(0xa1);
Check_Ack();
while(--length)
{
*dat++=Receive_Byte();
Ack();
}
*dat=Receive_Byte();//讀取最后一個(gè)字節(jié)
NoAck();
}
Stop();
if(RW)
Delay_Us(1000);
}
復(fù)制代碼
at24c02.h
#ifndef __AT24C02_H__
#define __AT24C02_H__
#include<reg52.h>
sbit SCL1=P2^1;
sbit SDA1=P2^0;
void Start(void);
void Stop(void);
bit Check_Ack(void);
void Ack(void);
void NoAck(void);
void Send_Byte(unsigned char dat);
unsigned char Receive_Byte(void);
void At24c02_RW(unsigned char addr,unsigned char *dat,unsigned char length,bit RW);
#endif
復(fù)制代碼
delay.c
#include "delay.h"
/*******************************************************************************
* 函 數(shù) 名 : Delay_Us()
* 函數(shù)功能 : 延時(shí)1us
* 輸 入 : i
* 輸 出 : 無(wú)
*******************************************************************************/
void Delay_Us(int i)
{
while(i--);
}
/*******************************************************************************
* 函 數(shù) 名 : Delay_Ms()
* 函數(shù)功能 : 延時(shí)1Ms
* 輸 入 : m
* 輸 出 : 無(wú)
*******************************************************************************/
void Delay_Ms(int m)
{
while(m--)
{
Delay_Us(125);
}
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1