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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2649|回復: 7
收起左側

發送完地址后24c02一直不產生應答,附單片機程序

[復制鏈接]
ID:967353 發表于 2021-9-21 16:43 | 顯示全部樓層 |閱讀模式
  1. #include "mpu_i2c.h"
  2. #include "usart.h"

  3. //配置i2c端口
  4. void I2C_GPIO_Config(void)
  5. {
  6.         //定義結構體
  7.         GPIO_InitTypeDef  GPIO_InitStruct;
  8.         
  9.         //打開SDA與SCL端口時鐘
  10.         RCC_APB2PeriphClockCmd(I2C_SDA_CLK,ENABLE);
  11.         RCC_APB2PeriphClockCmd(I2C_SCL_CLK,ENABLE);
  12.         
  13.         //配置SDA端口
  14.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//開漏復用輸出
  15.         GPIO_InitStruct.GPIO_Pin = I2C_SDA_Pin;
  16.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  17.   GPIO_Init(I2C_SDA_PORT,&GPIO_InitStruct);        

  18.         //配置SCL端口
  19.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//開漏復用輸出
  20.         GPIO_InitStruct.GPIO_Pin = I2C_SCL_Pin;
  21.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  22.   GPIO_Init(I2C_SCL_PORT,&GPIO_InitStruct);        

  23. }


  24. void I2C_InitConfig(void)
  25. {
  26.         I2C_GPIO_Config();
  27. }


  28. void delay(void)
  29. {
  30.         uint8_t time = 10;
  31.         while(time--)
  32.         {
  33.         }
  34. }


  35. void I2C_START(void)
  36. {
  37.         SDA_OUT();
  38.         I2C_SDA_1();
  39.         I2C_SCL_1();
  40.         delay();
  41.         I2C_SDA_0();
  42.         delay();
  43.         I2C_SCL_0();
  44.         delay();
  45. }

  46. void  I2C_STOP(void)
  47. {
  48.         SDA_OUT();
  49.         I2C_SDA_0();
  50.         I2C_SCL_1();
  51.         delay();
  52.         I2C_SDA_0();
  53.         delay();
  54. }

  55. void I2C_Ack(void)
  56. {
  57.         I2C_SCL_0();
  58.         I2C_SDA_1();
  59.         delay();
  60.         I2C_SDA_1();
  61.         delay();
  62.         I2C_SDA_0();
  63.         delay();
  64.         I2C_SCL_1();
  65.         delay();
  66.         I2C_SCL_0();
  67.         delay();
  68.         I2C_SDA_1();
  69. }

  70. void I2C_NACK(void)
  71. {
  72.         I2C_SCL_0();
  73.         I2C_SDA_0() ;
  74.         delay();
  75.         I2C_SDA_1();
  76.         delay();
  77.         I2C_SCL_1();
  78.         delay();
  79.         I2C_SCL_0();
  80.         delay();
  81.         I2C_SDA_0();
  82.         delay();
  83. }

  84. void I2C_Sent_Byte(uint8_t msg)
  85. {
  86.         uint8_t i;
  87.         SDA_OUT();
  88.   I2C_SCL_0();
  89.         delay();
  90.         /* 先發送字節的高位bit7 */
  91.         for (i = 0; i < 8; i++)
  92.         {               
  93.                 if (msg & 0x80 ==1)
  94.                 {
  95.                 I2C_SDA_1();
  96.                 }
  97.                 else
  98.                 {
  99.                 I2C_SDA_0();
  100.                 }
  101.                 delay();
  102.                 I2C_SCL_1();
  103.                 delay();        
  104.                 I2C_SCL_0();
  105.                 if (i == 7)
  106.                 {
  107.                 I2C_SDA_1(); // 釋放總線
  108.                 }
  109.                 msg <<= 1;        /* 左移一個bit */
  110.                 delay();
  111.         }
  112.         I2C_SCL_0();
  113. }


  114. uint8_t I2C_Read_Byte(void)
  115. {
  116.         uint8_t i;
  117.         uint8_t receive = 0;
  118.         
  119.         /* 讀到的第一位為數據的7bit位!!!
  120.            所以每次讀取數據時都要將數據左移一位*/
  121.         
  122.         I2C_SCL_1();//鎖定SCL線,確保其穩定

  123.         for(i=0;i<8;i++)
  124.         {
  125.                 receive <<= 1;
  126.                 I2C_SCL_0();//讀取數據時拉低SCL
  127.                 delay();
  128.                 if(I2C_SDA_State() == 1)
  129.                 {
  130.                         receive++;
  131.                 }
  132.                 I2C_SCL_0();
  133.                 delay();
  134.                
  135.         }
  136.         
  137.         return receive;
  138. }


  139. void delay_us(uint8_t i)
  140. {
  141.         while(i--)
  142.         {
  143.         }
  144. }

  145. uint8_t I2C_WaitAck(void)
  146. {
  147.         uint8_t re;

  148.         I2C_SDA_1();        /* CPU釋放SDA總線 */
  149.         delay();
  150.         I2C_SCL_1();        /* CPU驅動SCL = 1, 此時器件會返回ACK應答 */
  151.         delay();
  152.         if (I2C_SDA_State())        /* CPU讀取SDA口線狀態 */
  153.         {
  154.                 re = 1;
  155.         }
  156.         else
  157.         {
  158.                 re = 0;
  159.         }
  160.         I2C_SCL_0();
  161.         delay();
  162.         return re;
  163. }






  164. uint8_t  EEPROM_Byte_Write(uint16_t _usAddress, uint16_t data)
  165. {
  166.         uint8_t i;
  167.         //開始信號
  168.         I2C_START();
  169.         //發送地址
  170.         I2C_Sent_Byte(Slave_Addr | I2C_Write);
  171.         //檢測應答
  172.         //delay();
  173.         //return printf("SDA的狀態為:%d\n",I2C_SDA_State());
  174.         if(I2C_WaitAck() != 0)
  175.         {
  176.                 return printf("寫入失敗,未檢測到響應1\n");
  177.         }
  178.         //發送從機中的數據地址(起始地址)
  179.         I2C_Sent_Byte(_usAddress);
  180.   //檢測應答
  181.         if(I2C_WaitAck() != 0)
  182.         {
  183.                 return printf("寫入失敗,未檢測到響應2\n");
  184.         }
  185.         
  186.         for(i=0;i<8;i++)
  187.         {
  188.                 I2C_Sent_Byte(data & 0x80);
  189.                 I2C_Ack();
  190.                 data <<= 1;
  191.         }
  192.         return printf("寫入完成!!!\n");
  193. }




  194. uint8_t  EEPROM_Byte_Read(uint8_t *_pReadBuf, uint16_t _usAddress, uint16_t _usSize)
  195. {
  196.         uint8_t i;
  197.         //開始信號
  198.         
  199.         //test SDA
  200.         //return printf("開始信號前SDA狀態為:%d\n",READ_I2C_SDA());
  201.         
  202.         I2C_START();
  203.         //發送地址
  204.         
  205.         //test SDA
  206.         //return printf("開始信號后SDA狀態為:%d\n",READ_I2C_SDA());
  207.         
  208.         I2C_Sent_Byte(Slave_Addr | I2C_Write);

  209.         //test SDA
  210.         //return printf("發送地址后SDA狀態為:%d\n",READ_I2C_SDA());
  211.         
  212.         //檢測應答
  213.         if(I2C_WaitAck() != 0)
  214.         {
  215.                 return printf("讀取失敗,未檢測到響應1\n");
  216.         }
  217.         //發送從機中的數據地址(起始地址)
  218.         I2C_Sent_Byte(_usAddress);
  219.   //檢測應答
  220.         if(I2C_WaitAck() != 0)
  221.         {
  222.                 return printf("讀取失敗,未檢測到響應2\n");
  223.         }
  224.         //開始信號
  225.         I2C_START();
  226.         //發送地址
  227.         I2C_Sent_Byte(Slave_Addr | I2C_Read);
  228.          //檢測應答
  229.         if(I2C_WaitAck() != 0)
  230.         {
  231.                 return printf("讀取失敗,未檢測到響應3\n");
  232.         }
  233.         
  234.         //讀取數據
  235.         for(i=0;i< _usSize;i++)
  236.         {

  237. //                if(I2C_GetFlagStatus(I2C_Driver,I2C_FLAG_BUSY) == SET)
  238. //                {
  239. //                        return printf("他媽的鎖死了,讀取失敗\n");
  240. //                }
  241.                
  242.                 _pReadBuf[i] = I2C_Read_Byte();//每次讀取一個字節
  243.                 if(i != (_usSize-1))
  244.                 {
  245.                         I2C_Ack();
  246.                 }
  247.                 else
  248.                 {
  249.                         I2C_NACK();
  250.                 }
  251.         }
  252.         
  253.         //發送停止信號
  254.         I2C_STOP();
  255.         
  256.         return printf("讀取完成!\n");
  257.         
  258. }
復制代碼
回復

使用道具 舉報

ID:967353 發表于 2021-9-21 16:44 | 顯示全部樓層
前前后后搞了幾天了,真不知道問題出在了哪里
回復

使用道具 舉報

ID:123289 發表于 2021-9-21 22:28 | 顯示全部樓層
用示波器看通訊的波形,是否與手冊上說的相符。
回復

使用道具 舉報

ID:161164 發表于 2021-9-21 23:17 | 顯示全部樓層
放入Protues仿真看波型時序
如有硬件示波器更好
回復

使用道具 舉報

ID:887202 發表于 2021-9-22 09:20 | 顯示全部樓層
你的IIC_READ_BYTE函數,讀取數據的時候為什么要先把SCL拉低????應該是先把SCL拉高,然后讀取數據再拉低循環8次。按照你的操作,先把SCL拉高,讀取之前又拉低了,這時候你讀取即可能是高電平也可能是低電平,根據IIC的協議,這時候SDA上的電平是允許變化的,所以這么讀是有問題的。建議你用邏輯分析儀去抓一下IIC,然后再結合你的代碼分析。最好去看一下別人的IIC怎么寫的,參考一下
回復

使用道具 舉報

ID:624769 發表于 2021-9-22 17:10 | 顯示全部樓層
沒仔細看,但是,看到STOP就覺得不太對勁了……
STOP 不是應該拉高時鐘之后,拉高數據線么?為什么,拉高時鐘之后,你SDA 還是 0?
void  I2C_STOP(void)
{
        SDA_OUT();
        I2C_SDA_0();
        I2C_SCL_1();
        delay();
        I2C_SDA_0();      // 這里不應該  SDA 1 么?
        delay();
}

你仔細看看你的整個時序 我感覺 你的 讀 ACK 那里 也 少一個 CLK 0,所以讀不到 ACK
回復

使用道具 舉報

ID:668885 發表于 2021-9-22 17:28 | 顯示全部樓層
用邏輯分析儀,抓波形,看發送接收有沒有問題
回復

使用道具 舉報

ID:887202 發表于 2021-9-22 17:51 | 顯示全部樓層
整個IIC的起始信號,停止信號等都有問題啊,都不用邏輯分析儀抓了,肯定通訊不成功的,你去看別人寫好的IIC吧,對照著IIC的協議時序仔細看
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产区免费视频 | 色爱综合网 | 黄色网址在线播放 | 久久亚| 精品国产一区二区三区观看不卡 | 国产三区精品 | 99久久久国产精品 | 亚洲bt 欧美bt 日本bt | 波多野结衣精品在线 | 夜夜夜夜草| www.狠狠操 | jizz中国日本 | 青青99 | 国产欧美一区二区精品忘忧草 | 日韩av成人 | 高清一区二区三区 | 黄视频国产 | 国产成人在线视频播放 | 一区视频| 91视频在线观看 | 亚洲精品乱码久久久久久蜜桃91 | 国产免费观看视频 | 久久国产麻豆 | 亚洲国产精品va在线看黑人 | 本地毛片 | 色欧美片视频在线观看 | 久久综合影院 | 亚洲韩国精品 | 亚洲视频免费在线看 | 日韩高清国产一区在线 | 亚洲国产成人精品久久 | 精品久久久久久中文字幕 | 精品久久中文字幕 | 亚洲第一区久久 | 国产在线视频三区 | 国产乡下妇女做爰 | 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | av一级久久| 日韩伦理电影免费在线观看 | 一级片在线免费播放 | 精品国产aⅴ |