久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1140|回復: 5
打印 上一主題 下一主題
收起左側

我的單片機+iic程序怎么讀寫不了? 搞了好幾天搞不明白

[復制鏈接]
跳轉到指定樓層
樓主
ID:1009775 發表于 2022-3-11 19:41 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
求求大佬們看看哪出問題了,1602模塊沒問題 仿真里讀出來的是一個黑塊  

at24c02.c
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5.         
  6. sbit SCK = P1^3;
  7. sbit SDA = P1^4;

  8. void Delayms(uint x);
  9. void Delayus(uchar x);
  10. void Delay5us();
  11. void Delay5ms();

  12. void init(){
  13.         SCK = 1;
  14.         _nop_();_nop_();_nop_();
  15.         SDA = 1;
  16.         _nop_();_nop_();_nop_();
  17. }
  18. void start(){
  19.         SCK = 1;
  20.         _nop_();_nop_();_nop_();
  21.         SDA = 1;
  22.         _nop_();_nop_();_nop_();
  23.         _nop_();_nop_();_nop_();
  24.         SDA = 0;
  25.         _nop_();_nop_();_nop_();
  26.         _nop_();_nop_();_nop_();
  27.         SCK = 0;
  28. }
  29.         
  30. void stop(){
  31.         SCK  =1;
  32.         SDA = 0;
  33.         _nop_();_nop_();_nop_();
  34.         _nop_();_nop_();_nop_();
  35.         SDA = 1;
  36.         _nop_();_nop_();_nop_();
  37.         _nop_();_nop_();_nop_();
  38.         SDA = 0;
  39.         SCK = 0;
  40. }
  41. void WaitAck(){
  42.         uchar i = 0;
  43.         SDA = 1;
  44.         SCK = 1;
  45.         Delayus(5);
  46.         while(SDA == 1 && (i < 250))
  47.                 i++;
  48.         SCK = 0;
  49.         _nop_(), _nop_(), _nop_();
  50. }


  51. //void react(){
  52. //        SCK = 0;
  53. //        SDA = 1;
  54. //        SDA = 0;
  55. //        SCK = 1;
  56. //        _nop_();_nop_();_nop_();
  57. //        _nop_();_nop_();_nop_();
  58. //        SCK = 0;
  59. //        SDA = 1;
  60. //}
  61. void noack(){
  62.          SDA=1;
  63.          _nop_();_nop_();_nop_();
  64.          SCK=1;
  65.          _nop_();_nop_();_nop_();
  66.                 _nop_();_nop_();_nop_();
  67.          SCK=0;
  68.          _nop_();_nop_();_nop_();
  69.                 SDA = 0;
  70. }

  71. uchar readByte(){
  72.         uchar i, k = 0;
  73.         for(i = 0; i < 8; i++){
  74.                 SCK = 0;
  75.                 k <<= 1;
  76.                 Delay5us();        
  77.                 if(SDA == 1){
  78.                         k |= 0x01;
  79.                 }
  80.                 SCK = 0;
  81.                 Delay5us();
  82.         }
  83.         _nop_();
  84.         Delay5ms();
  85.         return k;
  86. }

  87. void writeByte(uchar dat){
  88.         uchar i = 0;
  89.         for(i = 0; i < 8; i++){
  90.                 SCK = 0;
  91.                 Delay5us();
  92.                 SDA = dat & 0x80;
  93.                 _nop_();_nop_();_nop_();_nop_();
  94.                 SCK = 1;
  95.                 Delay5us();
  96.                 dat <<= 1;
  97.         }
  98.         SCK = 0;
  99.         _nop_();_nop_();_nop_();
  100.         Delay5ms();
  101. }

  102. void addByte(uchar wordAddress, uchar dat){
  103.         start();
  104.         writeByte(0xa0);
  105.         WaitAck();
  106.         writeByte(wordAddress);
  107.         WaitAck();
  108.         writeByte(dat);
  109.         WaitAck();
  110.         stop();
  111.         Delayms(5);
  112. }

  113. uchar readAddByta(uchar wordAddress){
  114.         uchar dat;
  115.         start();
  116.         writeByte(0xa0);
  117.         WaitAck();
  118.         writeByte(wordAddress);
  119.         WaitAck();
  120.         stop();
  121.         start();
  122.         writeByte(0xa1);
  123.         WaitAck();
  124.         dat = readByte();
  125.         noack();
  126.         stop();
  127.         return dat;
  128. }

  129. void Delayms(uint x){
  130.         int i, j;
  131.         for(i = x; i > 0; --i){
  132.                 for(j = 110; j > 0; --j);
  133.         }
  134. }
  135. void Delayus(uchar x){
  136.         while(x--);
  137. }

  138. void Delay5us()                //@12.000MHz
  139. {
  140.         _nop_();
  141. }

  142. void Delay5ms()                //@12.000MHz
  143. {
  144.         unsigned char i, j;

  145.         i = 10;
  146.         j = 183;
  147.         do
  148.         {
  149.                 while (--j);
  150.         } while (--i);
  151. }
復制代碼

main.c
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include "at24c02.h"
  4. #include "proteus_1602.h"
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. sbit SCK = P1^3;
  8. sbit SDA = P1^4;
  9. void main(){
  10.         Delayms(2000);
  11.         while(1){
  12.                 uchar temp = 0;
  13.                 init();
  14.                 init_1602();
  15.                 addByte(0x00, 0x00);
  16.                 Delayms(10);
  17.                 temp = readAddByta(0x00);
  18.                 writeData_1602(temp + 0x38);
  19.                 Delayms(50);
  20.         }         
  21. }
復制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1009775 發表于 2022-3-11 19:42 | 只看該作者
1602模塊沒問題 仿真里讀出來的是一個黑塊  
回復

使用道具 舉報

板凳
ID:488334 發表于 2022-3-12 02:56 | 只看該作者
IIC的時序很重要,最好嘗試的用邏輯分析儀讀一下時序,看看是不是時序出現問題,還有如果時序沒問題的話,要看時間,比如起始信號,一高一低時間會不會太短,導致從機識別不了IIC的起始信號等等。
回復

使用道具 舉報

地板
ID:161164 發表于 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_();
}
回復

使用道具 舉報

5#
ID:776619 發表于 2022-3-13 10:53 | 只看該作者
讀寫兩句間加個延時看看,器件兩個動作要有間隔的。
回復

使用道具 舉報

6#
ID:856329 發表于 2022-3-13 11:56 | 只看該作者
iic通信和晶振頻率24c02的地址都有關系,錯一點都可能導致通信失敗。
分享一下自用的驅動程序,僅供參考。
晶振12MHz或者11.0592MHz,24c02的3個地址全接地。
at24c02.c
  1. #include "at24c02.h"
  2. #include "delay.h"

  3. //IIC啟動
  4. void Start(void)
  5. {
  6.         SDA1=1;
  7.         Delay_Us(2);
  8.         SCL1=1;
  9.         Delay_Us(2);//建立時間是SDA保持時間>4.7us
  10.         SDA1=0;
  11.         Delay_Us(2);//保持時間是>4us
  12.         SCL1=0;                       
  13.         Delay_Us(2);
  14. }
  15. //IIC停止
  16. void Stop(void)
  17. {
  18.         SDA1=0;
  19.         Delay_Us(2);
  20.         SCL1=1;
  21.         Delay_Us(2);//建立時間大于4.7us
  22.         SDA1=1;
  23.         Delay_Us(4);               
  24. }
  25. //IIC發送字節
  26. //dat:要發送的字節
  27. void Send_Byte(unsigned char dat)
  28. {
  29.         unsigned char a=0,b=0;
  30.         for(a=0;a<8;a++)//要發送8位,從最高位開始
  31.         {
  32.                 SDA1=dat>>7;         //起始信號之后SCL=0,所以可以直接改變SDA信號
  33.                 dat=dat<<1;
  34.                 Delay_Us(2);
  35.                 SCL1=1;
  36.                 Delay_Us(2);//建立時間>4.7us
  37.                 SCL1=0;
  38.                 Delay_Us(2);//時間大于4us
  39.         }       
  40. }
  41. //IIC檢查應答
  42. bit Check_Ack(void)
  43. {
  44.         //unsigned char t;
  45.         SCL1=0;
  46.         SDA1=1;
  47.         Delay_Us(2);
  48.         SCL1=1;
  49.         Delay_Us(2);
  50.         CY=SDA1;
  51.         SCL1=0;
  52.         Delay_Us(2);       
  53.         return(CY);
  54. }
  55. //IIC應答
  56. void Ack(void)
  57. {
  58.         SDA1=0;   //EEPROM通過在收到每個地址或數據之后
  59.         SCL1=1;   //置SDA低電平的方式確認表示收到讀SDA口狀態
  60.         Delay_Us(1);
  61.         SCL1=0;
  62.         Delay_Us(1);
  63.         SDA1=1;
  64. }
  65. //IIC無應答
  66. void NoAck(void)
  67. {
  68.         SDA1=1;
  69.         SCL1=1;
  70.         Delay_Us(1);
  71.         SCL1=0;
  72. }
  73. //IIC接收字節
  74. unsigned char Receive_Byte(void)
  75. {
  76.         unsigned char a=0,dat=0;
  77.         SDA1=1;                        //起始和發送一個字節之后SCL都是0
  78.         Delay_Us(2);
  79.         for(a=0;a<8;a++)//接收8個字節
  80.         {
  81.                 SCL1=1;
  82.                 Delay_Us(2);
  83.                 dat<<=1;
  84.                 dat|=SDA1;
  85.                 Delay_Us(2);
  86.                 SCL1=0;
  87.                 Delay_Us(2);
  88.         }
  89.         return dat;               
  90. }
  91. //At24cxx讀寫數據
  92. //addr:要讀/寫數據的地址
  93. //*dat:要讀/寫的數據
  94. //length;數據的長度
  95. //RW:1:寫,0:讀
  96. void At24c02_RW(unsigned char addr,unsigned char *dat,unsigned char length,bit RW)
  97. {
  98.         Start();
  99.         Send_Byte(0xa0);//發送寫器件地址
  100.         Check_Ack();
  101.         Send_Byte((unsigned char)addr);//發送要寫入內存地址
  102.         Check_Ack();
  103.         if(RW)                 //寫
  104.         {        while(length--)
  105.                 {
  106.                         Send_Byte(*dat++);
  107.                         Check_Ack();       
  108.                 }
  109.         }
  110.         else
  111.         {
  112.                 Start();
  113.                 Send_Byte(0xa1);
  114.                 Check_Ack();
  115.                 while(--length)
  116.                 {
  117.                         *dat++=Receive_Byte();
  118.                          Ack();
  119.                 }
  120.                 *dat=Receive_Byte();//讀取最后一個字節
  121.                 NoAck();
  122.         }
  123.         Stop();
  124.         if(RW)
  125.         Delay_Us(1000);
  126. }

復制代碼


at24c02.h
  1. #ifndef __AT24C02_H__
  2. #define __AT24C02_H__

  3. #include<reg52.h>

  4. sbit SCL1=P2^1;
  5. sbit SDA1=P2^0;

  6. void Start(void);
  7. void Stop(void);
  8. bit Check_Ack(void);
  9. void Ack(void);
  10. void NoAck(void);
  11. void Send_Byte(unsigned char dat);
  12. unsigned char Receive_Byte(void);
  13. void At24c02_RW(unsigned char addr,unsigned char *dat,unsigned char length,bit RW);

  14. #endif
復制代碼


delay.c
  1. #include "delay.h"

  2. /*******************************************************************************
  3. * 函 數 名         : Delay_Us()
  4. * 函數功能                   : 延時1us
  5. * 輸    入         : i
  6. * 輸    出         : 無
  7. *******************************************************************************/
  8. void Delay_Us(int i)
  9. {
  10.         while(i--);
  11. }
  12. /*******************************************************************************
  13. * 函 數 名         : Delay_Ms()
  14. * 函數功能                   : 延時1Ms
  15. * 輸    入         : m
  16. * 輸    出         : 無
  17. *******************************************************************************/
  18. void Delay_Ms(int m)
  19. {
  20.         while(m--)
  21.         {
  22.                  Delay_Us(125);
  23.         }
  24. }
復制代碼
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品亚洲一区二区 | 欧美二区三区 | 亚洲免费在线 | 日韩在线看片 | www.久草.com| 国产精品一区二区欧美黑人喷潮水 | 精品免费视频一区二区 | 久久久久久久av | 一区二区三区国产在线观看 | 久久精品亚洲一区二区三区浴池 | 高清不卡毛片 | 久久99精品久久久久久 | 国产成人精品一区二区三 | 亚洲国产高清免费 | 久久久精品网 | 九九免费| 91影院在线观看 | 国产日韩免费观看 | 亚洲免费在线观看 | 手机看黄av免费网址 | 国内自拍偷拍 | 四虎影院免费在线播放 | 国产精品福利在线 | 亚洲视频1区 | 欧美一级网站 | 国产小视频在线 | 美女高潮网站 | 97热在线 | 成人国产精品久久久 | 国产精品一区二区久久 | 国产99久久精品一区二区永久免费 | 免费不卡视频 | 欧美美女二区 | h免费观看| 性一爱一乱一交一视频 | 国产韩国精品一区二区三区 | 成人av网站在线观看 | 国产精品久久久久久久久久久久久久 | 国产精品久久久久久久久久久久 | 无码日韩精品一区二区免费 | 久久久久久国产精品免费免费 |