打印

[技术问答] Nano100SD3BN的I2C通信问题

[复制链接]
146|6
跳转到指定楼层
楼主
本萌新第一次接触新唐单片机,代码如下,使用的I2C1新唐做主机,从机为ADM1278-2,ADM1278-2两地址引脚状态为接地,时钟使用内部时钟。代码如下,在线调试时,一直无法通信上,在发送从机地址后,状态寄存器每次都是由0X08变为0X20,无法正常接收从机地址,请大神帮忙,是我的代码出了问题,还是硬件有问题,谢谢大家!(硬件不是我设计的,是别人设计提供给我的使用I2C1引脚以及ADM1278地址接地,我没有图纸)
  1. uint32_t data,dataV,dataI,dataP,dataF,q;
  2. uint32_t hdata,hdataV,hdataI,hdataP,hdataF;

  3. void I2C1_Init(void)
  4. {
  5.                         I2C_Open(I2C1, 100000);      //ADM1278最大时钟频率400KHz

  6. }

  7. uint32_t I2C1_read(uint32_t Slaveadd,uint32_t Slaveregister)
  8. {
  9.         uint32_t shuju,shuju_L,shuju_H,history;
  10.         PWM1->DUTY1&=(0X0000<<16);
  11.         //I2C开始命令,进入主机模式
  12.         history=I2C1->STATUS;
  13.         I2C_SET_CONTROL_REG(I2C1, I2C_SI);                       //写1清除标志位
  14.         I2C_SET_CONTROL_REG(I2C1, I2C_STA);                       //开始
  15.         while(history==I2C1->STATUS);                            //等待产生新的STS状态
  16.         if(I2C1->STATUS!=0X08)                                     //开始不成功
  17.         {
  18.                 I2C_Close(I2C1);
  19.     I2C_SET_CONTROL_REG(I2C1, I2C_STO);                       //错误,停止I2C
  20.                 I2C_Open(I2C1, 100000);
  21.     return 0;
  22.         }
  23.         history=I2C1->STATUS;
  24.         I2C_SET_CONTROL_REG(I2C1, I2C_SI);                       //清除标志位
  25.         //发送从器件地址 R/W=0
  26.   I2C_SetData(I2C1,((Slaveadd<<1)|0X00));   
  27.         while(history==I2C1->STATUS);                            //等待产生新的STS状态
  28.         if(I2C1->STATUS!=0X18)
  29.         {
  30.                 I2C_Close(I2C1);
  31.     I2C_SET_CONTROL_REG(I2C1, I2C_STO);                       //错误,停止I2C
  32.                 I2C_Open(I2C1, 100000);
  33.     return 0;
  34.         }
  35.         history=I2C1->STATUS;
  36.         I2C_SET_CONTROL_REG(I2C1, I2C_SI);                       //清除标志位
  37.         //发送从寄存器地址
  38.         I2C_SetData(I2C1,Slaveregister);                                   
  39.         while(history==I2C1->STATUS);                            //等待产生新的STS状态
  40.         if(I2C1->STATUS!=0X28)
  41.         {
  42.                 I2C_Close(I2C1);
  43.     I2C_SET_CONTROL_REG(I2C1, I2C_STO);                       //错误,停止I2C
  44.                 I2C_Open(I2C1, 100000);
  45.     return 0;
  46.         }
  47.         history=I2C1->STATUS;
  48.         I2C_SET_CONTROL_REG(I2C1, I2C_SI);                       //清除标志位
  49.         //I2C开始命令,进入主机模式
  50.         I2C0->CON|=I2C_STA;
  51.         while(history==I2C1->STATUS);                            //等待产生新的STS状态
  52.         if(I2C1->STATUS!=0X08||I2C1->STATUS!=0X10)             //开始、重复开始失败
  53.         {
  54.                 I2C_Close(I2C1);
  55.     I2C_SET_CONTROL_REG(I2C1, I2C_STO);                       //错误,停止I2C
  56.                 I2C_Open(I2C1, 100000);
  57.     return 0;
  58.         }
  59.         history=I2C1->STATUS;
  60.         I2C_SET_CONTROL_REG(I2C1, I2C_SI);                       //清除标志位
  61.         //发送从器件地址 R/W=1
  62.         I2C_SetData(I2C1,(Slaveadd<<1)|0X01);   
  63.         while(history==I2C1->STATUS);                            //等待产生新的STS状态
  64.         if(I2C1->STATUS!=0X40)
  65.         {
  66.                 I2C_SET_CONTROL_REG(I2C1, I2C_STO);                       //接收地址错误,停止I2C
  67.     return 0;
  68.         }
  69.         history=I2C1->STATUS;
  70.         I2C_SET_CONTROL_REG(I2C1, I2C_SI);                       //清除标志位
  71.         I2C_SET_CONTROL_REG(I2C1, I2C_AA);                       //需要读取两个字节
  72.         while(history==I2C1->STATUS);                            //等待产生新的STS状态
  73.         if(I2C1->STATUS!=0X50)
  74.         {
  75.                 I2C_Close(I2C1);
  76.     I2C_SET_CONTROL_REG(I2C1, I2C_STO);                       //错误,停止I2C
  77.                 I2C_Open(I2C1, 100000);
  78.     return 0;
  79.                
  80.         }
  81.         history=I2C1->STATUS;
  82.         shuju_L=I2C_GetData(I2C1);
  83.         I2C_SET_CONTROL_REG(I2C1, I2C_SI);                       //清除标志位
  84.   I2C1->CON&=~I2C_AA;
  85.         while(history==I2C1->STATUS);                            //等待产生新的STS状态
  86.         if(I2C1->STATUS!=0X58)
  87.         {
  88.                 I2C_Close(I2C1);
  89.     I2C_SET_CONTROL_REG(I2C1, I2C_STO);                       //错误,停止I2C
  90.                 I2C_Open(I2C1, 100000);
  91.     return 0;
  92.         }
  93.        
  94.         shuju_H=I2C_GetData(I2C1);
  95.         I2C_SET_CONTROL_REG(I2C1, I2C_STO|I2C_SI);                       //接收地址错误,停止I2C
  96.         shuju=((shuju_H<<8)|shuju_L);
  97.         //        CLK_SysTickDelay(5000);                                  //延时5000us
  98.   return shuju;

  99. }




  100. /*---------------------------------------------------------------------------------------------------------*/
  101. /*  I2C1 TRx Callback Function                                                                               */
  102. /*---------------------------------------------------------------------------------------------------------*/

  103. void I2C1_dataCalculation(uint32_t Slaveadd,uint32_t Slaveregister)
  104. {
  105.         float f;
  106.         uint32_t i;
  107.         switch(Slaveregister)
  108.         {
  109.                 case 0X88:                         //输入电压
  110.                if(I2C1_read(Slaveadd,Slaveregister)!=0)
  111.                 {
  112.                          hdataV=dataV;
  113.                         i=I2C1_read(Slaveadd,Slaveregister);
  114.             dataV=i;
  115.                  }
  116.                 break;
  117.                 case 0x8D:                  //温度
  118.                            if(I2C1_read(Slaveadd,Slaveregister)!=0)
  119.                 {
  120.                          hdataF=dataF;
  121.                         i=I2C1_read(Slaveadd,Slaveregister);
  122.             dataF=i;
  123.                  }
  124.                                         break;
  125.                 case 0x97:                   //输入功率
  126.                                    if(I2C1_read(Slaveadd,Slaveregister)!=0)
  127.                 {
  128.                          hdataP=dataP;
  129.                         i=I2C1_read(Slaveadd,Slaveregister);
  130.             dataP=i;
  131.                  }
  132.                                         break;
  133.                 case 0x8C:                   //输出电流
  134.                                    if(I2C1_read(Slaveadd,Slaveregister)!=0)
  135.                 {
  136.                          hdataI=dataI;
  137.                         i=I2C1_read(Slaveadd,Slaveregister);
  138.             dataI=i;
  139.                  }
  140.                                         break;
  141.                 default:                     //
  142.                                    if(I2C1_read(Slaveadd,Slaveregister)!=0)
  143.                 {
  144.                          hdata=data;
  145.                         i=I2C1_read(Slaveadd,Slaveregister);
  146.             data=i;
  147.                  }
  148.                                        
  149.         }
  150. }



  151. /*---------------------------------------------------------------------------------------------------------*/
  152. /*  MAIN function                                                                                          */
  153. /*---------------------------------------------------------------------------------------------------------*/
  154. int main (void)
  155. {

  156. //        char result;

  157.         //Initial System
  158.         SYS_Init();


  159.     /* Configure I2C0 as master and I2C1 as slave */
  160.     I2C0_Init();
  161.     I2C1_Init();
  162.        

  163.        
  164.           PWM_ConfigOutputChannel(PWM1, 1, 5, 50);
  165.        
  166.           PWM_EnableOutput(PWM1, PWM_CH_1_MASK);

  167.                 PWM_Start(PWM1,PWM_CH_1_MASK);       
  168.        
  169.                 SYS->PE_L_MFP |= (SYS_PE_L_MFP_PE5_MFP_PWM1_CH1);


  170. //            for (i = 0; i < 0x100; i++)
  171. //   {
  172. //        g_u8SlvData[i] = 0;
  173. //    }

  174.                 /* I2C function to Slave receive/transmit data */
  175. //    s_I2C0HandlerFn = (I2C_FUNC)I2C_SlaveTRx;
  176.                
  177. //                g_u8DeviceAddr = 0XB0;
  178.     q=1;
  179.         while(1)
  180.         {
  181.                 I2C1_dataCalculation(0X10,0X88);
  182.                 I2C1_dataCalculation(0X10,0X8D);
  183.                 I2C1_dataCalculation(0X10,0X97);
  184.                 I2C1_dataCalculation(0X10,0X8C);
  185.           PWM_ConfigOutputChannel(PWM1, 1, 5, 50);
  186.         }
  187.           
  188.        
  189.        
  190.        
  191. }


  192. void SYS_Init(void)
  193. {
  194. /* Unlock protected registers */
  195.     SYS_UnlockReg();               //寄存器解锁地址寄存器,解锁受保护的寄存器

  196.     /* Set HCLK source from HIRC and HCLK source divide 1  */
  197.         CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC,CLK_HCLK_CLK_DIVIDER(1));         //时钟源为HIRC,1分频

  198.     /* Enable external 12MHz HXT, 32KHz LXT and HIRC */
  199.     CLK_EnableXtalRC( CLK_PWRCTL_HIRC_EN_Msk);//(1或2或4)  CLK_PWRCTL_HXT_EN_Msk | CLK_PWRCTL_LXT_EN_Msk |

  200.     /*  Set HCLK frequency 42MHz */
  201. //   CLK_SetCoreClock(42000000);           //
  202.        
  203.     /* Waiting for 12MHz clock ready */
  204.     CLK_WaitClockReady( CLK_CLKSTATUS_HIRC_STB_Msk);
  205.        
  206.           //I2C0_MODULE                    I2C1_MODULE
  207.           CLK_SetModuleClock(I2C0_MODULE, 0, 0);
  208.                 CLK_SetModuleClock(I2C1_MODULE, 0, 0);
  209.                 CLK_SetModuleClock(PWM1_CH01_MODULE, CLK_CLKSEL2_PWM1_CH01_S_HIRC, 0);
  210.        
  211.           //使能I2C0时钟                  使能I2C1时钟
  212.           CLK_EnableModuleClock(I2C0_MODULE);
  213.           CLK_EnableModuleClock(I2C1_MODULE);
  214.                     /* Enable PWM clock */
  215.     CLK_EnableModuleClock(PWM1_CH01_MODULE);
  216.        
  217.          /* Set multi function pin for I2C0/I2C1 */
  218.          SYS->PA_H_MFP |= (SYS_PA_H_MFP_PA9_MFP_I2C0_SCL | SYS_PA_H_MFP_PA8_MFP_I2C0_SDA | SYS_PA_H_MFP_PA11_MFP_I2C1_SCL | SYS_PA_H_MFP_PA10_MFP_I2C1_SDA);
  219.        
  220.           SystemCoreClockUpdate();
  221.                        
  222.     /* Lock protected registers */
  223.     SYS_LockReg();
  224.        
  225. }
复制代码
沙发
 楼主 | 2019-10-28 14:56 | 只看该作者
这是1278的I2C从机地址描述,我把这个页面上支持的所有地址全部试了一遍也无法正常通信,我不知是不是我的代码出了问题,还是通信线路连接出现了问题,请大神帮忙分析以下代码是否存在问题,采用的库函数编程,库文件压缩包版本为V3.03

1.png (169.78 KB, 下载次数: 1)

1.png
板凳
 楼主 | 2019-10-28 15:39 | 只看该作者
有人吗?求大神帮我看一下代码,不胜感激
地板
| 2019-10-28 22:44 | 只看该作者
官方的BSP不是提供了的例子吗,使用例子测一下看看。
5
| 2019-10-29 08:53 | 只看该作者
先排除硬件问题,这个芯片没用过,查了一下,这个跟单片机连接还挺复杂。
6
 楼主 | 2019-10-29 10:47 | 只看该作者
xinpian101 发表于 2019-10-29 08:53
先排除硬件问题,这个芯片没用过,查了一下,这个跟单片机连接还挺复杂。 ...

主要是我没有硬件图纸,我只一块板,硬件那边又不肯给我图纸,然后我就想先判断一下是不是软件程序的问题,我现在已经调好了,不过还是谢谢你
7
 楼主 | 2019-10-29 10:52 | 只看该作者
玛尼玛尼哄 发表于 2019-10-28 22:44
官方的BSP不是提供了的例子吗,使用例子测一下看看。

我不是用的官方开发板,官方提供的例程用不上的,还有他的UART啥的我这边都没有设计这个外围,包括引脚接法时钟定义全部都是要改的,而且官方的I2C用的中断,我并不想用I2C中断来发送读取,直接使能I2C更好用一点,问题还是找到了,是通信时序的问题,不过还是感谢你!
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表
鼎鼎彩票 五福彩票 爱投彩票 中兴彩票 亿万彩票 智胜彩票 欢乐生肖网上哪里买 广西快3 彩娃彩票 全中彩票