欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
我的單片機+iic程序怎么讀寫不了? 搞了好幾天搞不明白
[打印本頁]
作者:
YANGTAIHUAN
時間:
2022-3-11 19:41
標題:
我的單片機+iic程序怎么讀寫不了? 搞了好幾天搞不明白
求求大佬們看看哪出問題了,1602模塊沒問題 仿真里讀出來的是一個黑塊
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);
}
復制代碼
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);
}
}
復制代碼
作者:
YANGTAIHUAN
時間:
2022-3-11 19:42
1602模塊沒問題 仿真里讀出來的是一個黑塊
作者:
tatachaoren
時間:
2022-3-12 02:56
IIC的時序很重要,最好嘗試的用邏輯分析儀讀一下時序,看看是不是時序出現問題,還有如果時序沒問題的話,要看時間,比如起始信號,一高一低時間會不會太短,導致從機識別不了IIC的起始信號等等。
作者:
lkc8210
時間:
2022-3-12 08:09
要貼就貼全一點
為什么不把at24c02.h/proteus_1602.h/proteus_1602.c也貼上來?
void WaitAck(){
uchar i = 0;
SDA =
0
;
SCK = 1;
Delayus(5);
while(SDA == 1 && (i < 250))
i++;
SCK = 0;
_nop_(), _nop_(), _nop_();
}
作者:
wolfinn
時間:
2022-3-13 10:53
讀寫兩句間加個延時看看,器件兩個動作要有間隔的。
作者:
Lxy18
時間:
2022-3-13 11:56
iic通信和晶振頻率24c02的地址都有關系,錯一點都可能導致通信失敗。
分享一下自用的驅動程序,僅供參考。
晶振12MHz或者11.0592MHz,24c02的3個地址全接地。
at24c02.c
#include "at24c02.h"
#include "delay.h"
//IIC啟動
void Start(void)
{
SDA1=1;
Delay_Us(2);
SCL1=1;
Delay_Us(2);//建立時間是SDA保持時間>4.7us
SDA1=0;
Delay_Us(2);//保持時間是>4us
SCL1=0;
Delay_Us(2);
}
//IIC停止
void Stop(void)
{
SDA1=0;
Delay_Us(2);
SCL1=1;
Delay_Us(2);//建立時間大于4.7us
SDA1=1;
Delay_Us(4);
}
//IIC發送字節
//dat:要發送的字節
void Send_Byte(unsigned char dat)
{
unsigned char a=0,b=0;
for(a=0;a<8;a++)//要發送8位,從最高位開始
{
SDA1=dat>>7; //起始信號之后SCL=0,所以可以直接改變SDA信號
dat=dat<<1;
Delay_Us(2);
SCL1=1;
Delay_Us(2);//建立時間>4.7us
SCL1=0;
Delay_Us(2);//時間大于4us
}
}
//IIC檢查應答
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應答
void Ack(void)
{
SDA1=0; //EEPROM通過在收到每個地址或數據之后
SCL1=1; //置SDA低電平的方式確認表示收到讀SDA口狀態
Delay_Us(1);
SCL1=0;
Delay_Us(1);
SDA1=1;
}
//IIC無應答
void NoAck(void)
{
SDA1=1;
SCL1=1;
Delay_Us(1);
SCL1=0;
}
//IIC接收字節
unsigned char Receive_Byte(void)
{
unsigned char a=0,dat=0;
SDA1=1; //起始和發送一個字節之后SCL都是0
Delay_Us(2);
for(a=0;a<8;a++)//接收8個字節
{
SCL1=1;
Delay_Us(2);
dat<<=1;
dat|=SDA1;
Delay_Us(2);
SCL1=0;
Delay_Us(2);
}
return dat;
}
//At24cxx讀寫數據
//addr:要讀/寫數據的地址
//*dat:要讀/寫的數據
//length;數據的長度
//RW:1:寫,0:讀
void At24c02_RW(unsigned char addr,unsigned char *dat,unsigned char length,bit RW)
{
Start();
Send_Byte(0xa0);//發送寫器件地址
Check_Ack();
Send_Byte((unsigned char)addr);//發送要寫入內存地址
Check_Ack();
if(RW) //寫
{ while(length--)
{
Send_Byte(*dat++);
Check_Ack();
}
}
else
{
Start();
Send_Byte(0xa1);
Check_Ack();
while(--length)
{
*dat++=Receive_Byte();
Ack();
}
*dat=Receive_Byte();//讀取最后一個字節
NoAck();
}
Stop();
if(RW)
Delay_Us(1000);
}
復制代碼
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
復制代碼
delay.c
#include "delay.h"
/*******************************************************************************
* 函 數 名 : Delay_Us()
* 函數功能 : 延時1us
* 輸 入 : i
* 輸 出 : 無
*******************************************************************************/
void Delay_Us(int i)
{
while(i--);
}
/*******************************************************************************
* 函 數 名 : Delay_Ms()
* 函數功能 : 延時1Ms
* 輸 入 : m
* 輸 出 : 無
*******************************************************************************/
void Delay_Ms(int m)
{
while(m--)
{
Delay_Us(125);
}
}
復制代碼
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1