找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

[NUC] NUC 240 smbus I2C_WAIT_READY(i2c) 無限等待

[复制链接]
跳转到指定楼层
楼主
chayi_alex 发表于 2019-4-30 12:39:43 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
我在網站上找到關於 SMBUS 的相關的程式, 因此複製下來放在 NUC 240 環境下執行, 卻都在當在指令 I2C_WAIT_READY(i2c) 無法繼續執行, 卻不知為何?
不知是否可以幫幫忙解決問題,  感恩不盡.

我的設備位置是 0x16,  功能編號位址為 0x03,  傳回資料位元組 2 byte,  程式碼如下:

  1. #include <stdio.h>
  2. #include "NUC230_240.h"

  3. #define PLLCON_SETTING      SYSCLK_PLLCON_50MHz_XTAL
  4. #define PLL_CLOCK           50000000

  5. volatile uint8_t g_u8DeviceAddr;
  6. volatile uint8_t g_au8TxData[3];
  7. volatile uint8_t g_u8RxData;
  8. volatile uint8_t g_u8DataLen;
  9. volatile uint8_t g_u8EndFlag = 0;

  10. typedef void (*I2C_FUNC)(uint32_t u32Status);

  11. static I2C_FUNC s_I2C0HandlerFn = NULL;

  12. void I2C0_IRQHandler(void)
  13. {
  14.     uint32_t u32Status;

  15.     u32Status = I2C_GET_STATUS(I2C0);
  16.     if(I2C_GET_TIMEOUT_FLAG(I2C0)) {
  17.         /* Clear I2C0 Timeout Flag */
  18.         I2C_ClearTimeoutFlag(I2C0);
  19.     } else {
  20.         if(s_I2C0HandlerFn != NULL)
  21.             s_I2C0HandlerFn(u32Status);
  22.     }
  23. }

  24. void I2C_MasterRx(uint32_t u32Status)
  25. {
  26.     if(u32Status == 0x08) {   
  27.         I2C_SET_DATA(I2C0, (g_u8DeviceAddr << 1));
  28.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  29.     } else if(u32Status == 0x18) {  
  30.         I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
  31.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  32.     } else if(u32Status == 0x20) {
  33.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_STO_SI);
  34.     } else if(u32Status == 0x28) {
  35.         if(g_u8DataLen != 2) {
  36.             I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
  37.             I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  38.         } else {
  39.             I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_SI);
  40.         }
  41.     } else if(u32Status == 0x10) {  
  42.         I2C_SET_DATA(I2C0, ((g_u8DeviceAddr << 1) | 0x01));
  43.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  44.     } else if(u32Status == 0x40) {  
  45.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  46.     } else if(u32Status == 0x58) {
  47.         g_u8RxData = (unsigned char) I2C_GET_DATA(I2C0);
  48.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
  49.         g_u8EndFlag = 1;
  50.     } else {
  51.         printf("Status 0x%x is NOT processed\n", u32Status);
  52.     }
  53. }

  54. void I2C_MasterTx(uint32_t u32Status)
  55. {
  56.     if(u32Status == 0x08) {
  57.         I2C_SET_DATA(I2C0, g_u8DeviceAddr << 1);  
  58.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  59.     } else if(u32Status == 0x18) {
  60.         I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
  61.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  62.     } else if(u32Status == 0x20) {
  63.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_STO_SI);
  64.     } else if(u32Status == 0x28) {  
  65.         if(g_u8DataLen != 3) {
  66.             I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
  67.             I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  68.         } else {
  69.             I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
  70.             g_u8EndFlag = 1;
  71.         }
  72.     } else {
  73.         /* TO DO */
  74.         printf("Status 0x%x is NOT processed\n", u32Status);
  75.     }
  76. }

  77. void SYS_Init(void)
  78. {
  79.      /* Enable Internal RC 22.1184MHz clock */
  80.     CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

  81.     /* Waiting for Internal RC clock ready */
  82.     CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

  83.     /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
  84.     CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

  85.     /* Enable external XTAL 12MHz clock */
  86.     CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

  87.     /* Waiting for external XTAL clock ready */
  88.     CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

  89.     /* Set core clock as PLL_CLOCK from PLL */
  90.     CLK_SetCoreClock(PLL_CLOCK);

  91.     /* Enable UART module clock */
  92.     CLK_EnableModuleClock(UART0_MODULE);

  93.     /* Enable I2C0 module clock */
  94.     CLK_EnableModuleClock(I2C0_MODULE);

  95.     /* Select UART module clock source */
  96.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));

  97.      /* Set GPB multi-function pins for UART0 RXD and TXD */
  98.     SYS->GPB_MFP = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;

  99.     /* Set GPA multi-function pins for I2C0 SDA and SCL */
  100.     SYS->GPA_MFP = SYS_GPA_MFP_PA8_I2C0_SDA | SYS_GPA_MFP_PA9_I2C0_SCL;
  101. }

  102. void UART0_Init()
  103. {
  104.     /* Reset IP */
  105.     SYS_ResetModule(UART0_RST);

  106.     /* Configure UART0 and set UART0 Baudrate */
  107.     UART_Open(UART0, 115200);
  108. }

  109. void I2C0_Close(void)
  110. {
  111.     /* Disable I2C0 interrupt and clear corresponding NVIC bit */
  112.     I2C_DisableInt(I2C0);
  113.     NVIC_DisableIRQ(I2C0_IRQn);

  114.     /* Disable I2C0 and close I2C0 clock */
  115.     I2C_Close(I2C0);
  116.     CLK_DisableModuleClock(I2C0_MODULE);

  117. }

  118. void I2C0_Init(void)
  119. {
  120.     /* Open I2C module and set bus clock */
  121.     I2C_Open(I2C0, 80000); //BaudRate 80k, 100000 => 100K

  122.     /* Get I2C0 Bus Clock */
  123.     printf("I2C clock %d Hz\n", I2C_GetBusClockFreq(I2C0));

  124.     /* Set I2C 4 Slave Addresses */
  125.     I2C_SetSlaveAddr(I2C0, 0, 0x1ˊ6, 0);   /* Slave Address : 0x15 */

  126.     /* Enable I2C interrupt */
  127.     I2C_EnableInt(I2C0);
  128.     NVIC_EnableIRQ(I2C0_IRQn);
  129. }

  130. uint8_t I2C_WriteByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, const uint8_t data)
  131. { uint8_t u8Xfering = 1, u8Err = 0, u8Addr = 1, u8Ctrl = 0;
  132.   uint32_t u32txLen = 0;

  133.   I2C_START(i2c);
  134.         
  135.         while(u8Xfering && (u8Err == 0))
  136.         {
  137.                 I2C_WAIT_READY(i2c);
  138.                
  139.                 switch(I2C_GET_STATUS(i2c))
  140.     {
  141.        case 0x08:
  142.           I2C_SET_DATA(i2c, (u8SlaveAddr << 1 | 0x00));
  143.           u8Ctrl = I2C_I2CON_SI;
  144.           break;
  145.        case 0x18:  
  146.           I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF00) >> 8);
  147.           break;
  148.        case 0x20:
  149.        case 0x30:     
  150.           u8Ctrl = I2C_I2CON_STO_SI;      
  151.           u8Err = 1;               
  152.           break;
  153.        case 0x28:
  154.           if(u8Addr)
  155.           {
  156.              I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF));
  157.              u8Addr = 0;
  158.           }
  159.           else if((u32txLen < 1) && (u8Addr == 0))
  160.           {
  161.              I2C_SET_DATA(i2c, data);
  162.              u32txLen++;
  163.           }
  164.           else
  165.           {
  166.              u8Ctrl = I2C_I2CON_STO_SI;
  167.              u8Xfering = 0;
  168.           }
  169.           break;
  170.        case 0x38:  
  171.        default:  
  172.              u8Ctrl = I2C_I2CON_STO_SI;                  
  173.              u8Err = 1;
  174.              break;                                       
  175.                  }
  176.                  I2C_SET_CONTROL_REG(i2c, u8Ctrl);
  177.          }
  178.          return (u8Err | u8Xfering);  
  179. }

  180. uint8_t I2C_ReadByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr)
  181. {
  182.   uint8_t u8Xfering = 1, u8Err = 0, rdata = 0, u8Addr = 1, u8Ctrl = 0;

  183.   I2C_START(i2c);
  184.   while(u8Xfering && (u8Err == 0))
  185.   {
  186.     switch(I2C_GET_STATUS(i2c))
  187.           {
  188.       case 0x08:
  189.          I2C_SET_DATA(i2c, (u8SlaveAddr << 1 | 0x00));
  190.          u8Ctrl = I2C_I2CON_SI; //I2C_CTL_SI;
  191.          break;
  192.       case 0x18:  
  193.          I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF00) >> 8);
  194.          break;
  195.       case 0x20:   
  196.       case 0x30:   
  197.          u8Ctrl = I2C_I2CON_STO_SI;            
  198.          u8Err = 1;               
  199.          break;
  200.       case 0x28:
  201.          if(u8Addr)
  202.          {
  203.            I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFF));  
  204.            u8Addr = 0;
  205.          }
  206.          else            
  207.            u8Ctrl = I2C_I2CON_STA_SI;
  208.            break;
  209.       case 0x10:           
  210.          I2C_SET_DATA(i2c, ((u8SlaveAddr << 1) | 0x01));
  211.          u8Ctrl = I2C_I2CON_SI;
  212.          break;
  213.       case 0x40:  
  214.          u8Ctrl = I2C_I2CON_SI;
  215.          break;
  216.       case 0x48:
  217.          u8Ctrl = I2C_I2CON_STO_SI;
  218.          u8Err = 1;               
  219.          break;            
  220.       case 0x58:
  221.          rdata = (unsigned char) I2C_GET_DATA(i2c);
  222.          u8Ctrl = I2C_I2CON_STO_SI; //I2C_CTL_STO_SI;
  223.          u8Xfering = 0;
  224.          break;
  225.       case 0x38:
  226.       default:  
  227.          u8Ctrl = I2C_I2CON_STO_SI; //I2C_CTL_STO_SI;
  228.          u8Err = 1;
  229.          break; // Arbitration Lost
  230.            }
  231.           I2C_SET_CONTROL_REG(i2c, u8Ctrl);  
  232.   }
  233.   if(u8Err) rdata = 0;  

  234.   return rdata;  
  235. }

  236. volatile uint8_t g_u8DeviceAddr;
  237. volatile uint32_t ret_code;
  238. volatile uint16_t u16DataAddr;

  239. int32_t main(void)
  240. {
  241.     /* Unlock protected registers */
  242.     SYS_UnlockReg();

  243.     /* Init System, IP clock and multi-function I/O */
  244.     SYS_Init();

  245.     /* Lock protected registers */
  246.     SYS_LockReg();

  247.     /* Init UART0 for printf */
  248.     UART0_Init();


  249.     printf("I2C0_SDA(PD.4), I2C0_SCL(PD.5)\n");

  250.     I2C0_Init();
  251.         
  252. ret_code = I2C_WriteByteTwoRegs(I2C0, 0x16, 0x03, 0x2);

  253. CLK_SysTickDelay(20000);

  254. g_u8DeviceAddr = 0x16;

  255. u16DataAddr = 0x0003;

  256. ret_code = I2C_ReadByteTwoRegs(I2C0, g_u8DeviceAddr, u16DataAddr);

  257.     while(1);        
  258. }
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 顶 踩
回复

使用道具 举报

板凳
匿名  发表于 2019-5-10 13:17:28
#define I2C_WAIT_READY(i2c)     while(!((i2c)->I2CON & I2C_I2CON_SI_Msk))
回复 支持 反对

使用道具

沙发
匿名  发表于 2019-5-5 09:49:59
请给出I2C_WAIT_READY函数程序代码实现部分
回复 支持 反对

使用道具

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU