查看: 4003|回复: 4

[已解决] I2C从模式例程或中断代码(已解决)

[复制链接]

该用户从未签到

2

主题

46

帖子

0

注册会员

Rank: 2

积分
169
最后登录
2019-6-28
发表于 2013-5-27 14:28:12 | 显示全部楼层 |阅读模式
 LZ你好,想问一下KL系列的I2C从模式代码怎么写,我按照流程图谢了下,只能实现主机写,主机读总是不行,请问有相关例程吗?
另外请问一下MQX往KL上移植方便吗?
我知道答案 目前已有4人回答
回复

使用道具 举报

该用户从未签到

10

主题

459

帖子

0

中级会员

Rank: 3Rank: 3

积分
303
最后登录
2024-10-24
发表于 2013-5-27 15:03:05 | 显示全部楼层

回复:I2C从模式例程或中断代码(正解)

KL的I2C的参考代码你可以参考KL25Z的例程代码,里面又包括MQX+I2C的demo,希望对你有帮助。https://www.freescale.co
m/files/32bit/software/KL25_SC.exe
至于MQX往KL上移植的问题,飞思卡尔对于KL系列专门做了一个MQX的定制版本MQX-Lite,不需要自己再去裁剪MQX,并且飞思卡尔针对KL系列MCU做了很多Demo,结合PE工具,使用很方便。
回复 支持 反对

使用道具 举报

该用户从未签到

35

主题

508

帖子

0

金牌会员

Rank: 6Rank: 6

积分
2167
最后登录
1970-1-1
发表于 2013-5-27 15:22:58 | 显示全部楼层

RE:I2C从模式例程或中断代码(正解)

建议参考飞思卡尔应用笔记AN4342关于I2C从模式相应操作和代码。
http://cache.freescale.com/files/analog/doc/app_note/AN4342.pdf
相应代码可以在下面的链接下载:
http://cache.freescale.com/files/analog/doc/app_note/AN4342.rar
Kinetis L系列产品可以使用MQX Lite,你可以参考KL25产品的例程,其中提供MQX_Lite_i2c_demo 例程。
KL25例程可以从下面的链接中下载:
http://cache.freescale.com/files/32bit/software/KL25_SC.exe
祝顺利。
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

46

帖子

0

注册会员

Rank: 2

积分
169
最后登录
2019-6-28
 楼主| 发表于 2016-8-12 08:53:25 | 显示全部楼层
  1. //用于进行I2C通讯的全局变量
  2. volatile uint8     I2C_sla;                                             /* I2C器件从地址                */
  3. volatile uint32    I2C_suba;                                            /* I2C器件内子地址              */
  4. volatile uint8     I2C_suba_num;                                        /* I2C子地址长度                */
  5. volatile uint8     *I2C_buf;                                            /* 数据缓冲区指针               */
  6. volatile uint32    I2C_num;                                             /* 要读取/写入的数据个数        */
  7. volatile uint8     I2C_end;                                             /* I2C总线结束标志              */
  8. volatile uint8     I2C_restart;                                         /* I2C总线结重复起始标?         */
  9. static   uint8     I2C_irq_status;                                      /* I2C中断读写操作控制       1--读模式             0--写模式     */
  10. volatile uint8     I2C_sla_dir;         /*  从机控制 1--读取操作  0--写操作 */

  11. static uint8    GucSlaverMode;                                          /* 从机操作模式 0:发送/1:接收 */
  12. static uint8    GulCounter;                                             /* I2C数据计数                  */
  13. static uint16   GulAdr;                                                 /* EEPROM操作地址               */
  14. static uint8    IIC_DATA[1100];                                        /* I2C接收数据存储区         */
  15. uint8 IICReceiveFlag;       // IIC接收到帧标志
  16. uint16 IICReceiveLength;     // IIC接收到帧长度

  17. /*********************************************************************************************************
  18. ** Function name:           PE_ISR(isrINT_INT_I2C0)
  19. ** Descriptions:            I2C中断服务函数
  20. ** Created by:              wanghuan
  21. ** Created Date:            2015-7-22
  22. *********************************************************************************************************/
  23. PE_ISR(isrINT_I2C0)
  24. {
  25.         uint16 d; //偏移
  26.         uint32 b; //SRAM对应偏移地址
  27.         uint32 c;
  28.         uint16 i;
  29.         uint8 k;
  30.         uint8 sect;
  31.         uint8 dummy;

  32.         if(I2C0_C1 & I2C_C1_MST_MASK)  //是主机模式
  33.         {
  34. //                delay(1000);
  35.             if (I2C0_FLT & (1 << 6)) {      
  36.                 I2C_end = 1;            
  37.                 I2C0_FLT    |= (1 << 6);                                        /* 清零停止中断标志             */  
  38.                 I2C0_S      |= (1 << 1);                                        /* 清零中断标志                 */  
  39.                 return;                                                         /* 中断返回                     */
  40.             }
  41.             I2C0_S      |= (1 << 1);                                            /* 清零中断标志                 */      
  42.             switch (I2C_irq_status) {
  43.                 case 0:                                                         /* 发送模式                     */
  44.                 if (I2C0_S & 0x01) {                                            /* 应答检测                     */
  45.                     I2C_end = 1;                                                /* 无应答,传输结束             */
  46.                     I2C0_C1 &=  ~(1 << 5);                                      /* 发送STOP                     */
  47.                 }  
  48.                 if (I2C_suba_num == 2) {                            /* 两字节从机子地址处理         */
  49.                     I2C0_D = ((I2C_suba >> 8) & 0xff);
  50.                     I2C_suba_num --;
  51.                 } else if (I2C_suba_num == 1) {                     /* 单字节从机子地址处理         */
  52.                     I2C0_D = (I2C_suba & 0xff);
  53.                     I2C_suba_num --;
  54.                 } else if (I2C_suba_num == 0) {                         /* 无从机子地址处理             */
  55.                     if (I2C_sla_dir == 1) {                                     /* 主机读操作处理               */                                          
  56.                         I2C0_C1 |= 1 << 2;                                      /* 发送Restart                  */
  57.                         I2C_suba_num --;
  58.                         I2C_restart = 1;                                        /* 重复起始信号标志置位         */
  59.                     } else {
  60.                         if (I2C_num > 0) {                                      /* 发送数据                     */
  61.                             I2C0_D = *I2C_buf++;
  62.                             I2C_num --;
  63.                         } else {
  64.                             I2C0_C1 &=  ~(1 << 5);                              /* 发送STOP                     */     
  65.                             I2C0_C1 &=~ I2C_C1_MST_MASK;    // 传输完毕转为 slave mode-------------------------------2015.7.27
  66.                         }
  67.                     }
  68.                 } else {
  69.                     I2C0_C1 &= ~(1 << 4);                                       /* 转为接收模式                 */
  70.                     I2C_irq_status = 1;
  71.                     *I2C_buf = I2C0_D;  
  72.                 }        
  73.                 break;
  74.                 case 1:                                                         /* 接收模式                     */

  75.                 I2C_num--;
  76.                 if (I2C_num == 1) {                                             /* 接收最后一个字节,返回NACK   */
  77.                     I2C0_C1 |= 1 << 3;
  78.                 }   
  79.                 if (I2C_num == 0) {                                             /* 接收完成,结束总线           */
  80.                     I2C0_C1 &=  ~(1 << 5);                                      /* 发送STOP                     */                                          
  81.                 }
  82.                 *I2C_buf++ = I2C0_D;         
  83.                 break;
  84.                 default:
  85.                 I2C0_C1 &=  ~(1 << 5);                                          /* 发送STOP                     */               
  86.                 break;   
  87.             }
  88.             return;
  89.         }

  90.         if((I2C0_C1 & I2C_C1_MST_MASK)==0)    //从机模式
  91.         {
  92.             if (I2C0_FLT & (1 << 6)) {                                          /* 接收到停止信号               */
  93.                 I2C0_FLT    |= (1 << 6);                                        /* 清零停止中断标志             */  
  94.                 I2C0_S      |= (1 << 1);                                        /* 清零中断标志                 */
  95.                 I2C0_C1     &= ~(1 << 3);                                       /* 返回非应答                   */        
  96.                 GulCounter   = 0;                                               /* 参数清零                     */
  97.                 GulAdr       = 0;   
  98.                 return;                                                         /* 中断返回                     */
  99.             }   
  100.             I2C0_S     |= (1 << 1);                                             /* 清零中断标志                 */     
  101.             if (I2C0_S & (1 << 4)) {                                            /* 清除ARBL                     */
  102.                 I2C0_S |= (1 << 4);
  103.                 if (!(I2C0_S & (1 << 6))) {                                     /* IAAS 非 1                    */
  104.                     return ;
  105.                 }   
  106.             }   
  107.             if (I2C0_S & (1 << 6)) {                                            /* 地址传输阶段                 */

  108.                 if (I2C0_S & (1 << 2)) {
  109.                     GucSlaverMode = 0;                                          /* 从发送模式                   */
  110.                     I2C0_C1 |= (1 << 4);                                        /* 发送模式                     */
  111.                     if (GulCounter != 1) {         /* 通讯格式错误                 */                                 
  112.                         I2C0_C1 |= 1 << 3;                                      /* 返回非应答                   */
  113.                     } else {   
  114.                         I2C0_D = IIC_DATA[GulAdr++];                         /* 发送第一个数据               */
  115.                     }   
  116.                 } else {
  117.                     GucSlaverMode = 1;                                          // 从接收模式   --------------需要的2015.7.28
  118.                     I2C0_C1 &= ~(1 << 4);                                       /* 接收模式                     */
  119.                     GulCounter = 0;               
  120.                     if (I2C0_D) ;                                               /* 读一次                       */        
  121.                 }
  122.                 
  123.             } else {
  124.                 switch (GucSlaverMode) {
  125.                     case 0:
  126.                         if (I2C0_S & 0x01) {                                    /* 应答检测                     */
  127.                                                                                 /* 主机应答失败,停止发送       */
  128.                             I2C0_C1 &= ~(1 << 4);                               /* 接收模式                     */
  129.                             if (I2C0_D) ;                                       /* 读一次                       */                       
  130.                         } else {
  131.                             I2C0_D  = IIC_DATA[GulAdr++];                    /* 发送其他数据                 */
  132.                         }
  133.                     break;
  134.                     case 1:                                                      // 从接收模式   --------------需要的2015.7.28
  135.                         if (GulCounter < 1) {
  136.                                 GulAdr = I2C0_D;
  137.                             GulCounter++;  
  138.                         } else {
  139.                                 IIC_DATA[GulAdr] = I2C0_D;   //接收数据存储
  140.                                 GulAdr++;
  141.                                 max=(uint16)((IIC_DATA[7]<<8|IIC_DATA[8]));
  142.                                 if(max==0) {return;}
  143.                                                 if(GulAdr<max){return;}//这是接收任意字节的关键所在
  144.                                                 if(GulAdr==max)
  145.                                                 {GulAdr=0;}
  146.                         }                                        
  147.                     break;
  148.                     default :
  149.                         I2C0_C1 &= ~(1 << 4);                                   /* 接收模式                     */
  150.                         if (I2C0_D) ;                                           /* 读一次                       */                 
  151.                     break;
  152.                 }   
  153.             }   
  154.         }
复制代码
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

46

帖子

0

注册会员

Rank: 2

积分
169
最后登录
2019-6-28
 楼主| 发表于 2016-8-12 08:55:43 | 显示全部楼层
仅作为从机的代码可以参考如下
  1. //用于进行I2C通讯的全局变量
  2. uint8    GucSlaverMode;  //从机操作模式 0:发送/1:接收
  3. uint16   GulCounter;    //I2C数据计数        
  4. uint16   GulAdr;        //EEPROM操作地址

  5. void i2c0_isr(void)
  6. {
  7.     static uint8 *i2c_temp;
  8.     delay_us(200);
  9. //    printf("i2c中断\n");
  10. //        DisableInterrupts;
  11. //    if((I2C0_C1 & I2C_C1_MST_MASK)==0)   //从机模式
  12. //        {
  13.             if (I2C0_FLT & I2C_FLT_STOPF_MASK) //接收到停止信号
  14.             {
  15.                 I2C0_FLT |= I2C_FLT_STOPF_MASK; // 清零停止标志         
  16.                 I2C0_S |= I2C_S_IICIF_MASK;     //清零中断标志         
  17.                 I2C0_C1 &= ~I2C_C1_TXAK_MASK;   // 返回非应答                          
  18.                 GulCounter = 0;   // 参数清零                       
  19.                 GulAdr = 0;   
  20. //            printf("停止中断\n");
  21. //                EnableInterrupts;
  22.                 return;   //中断返回                                                   
  23.             }   
  24.             I2C0_S |= I2C_S_IICIF_MASK;  //清零中断标志                                
  25. //            if (I2C0_S & I2C_S_ARBL_MASK) //仲裁丢失
  26. //            {  
  27. //            printf("仲裁中断\n");
  28. //                I2C0_S |= I2C_S_ARBL_MASK; //清除ARBL
  29. //                if (!(I2C0_S & I2C_S_IAAS_MASK)) { EnableInterrupts; return ;} // IAAS 非 1,退出
  30. //            }   
  31.             if (I2C0_S & I2C_S_IAAS_MASK) //地址传输阶段
  32.             {
  33.                 if (I2C0_S & I2C_S_SRW_MASK) //从发送模式
  34.                 {
  35.                     GucSlaverMode = 0;                                
  36.                     I2C0_C1 |= I2C_C1_TX_MASK;  //从发送模式      
  37.                     if (GulCounter != 2) //通讯格式错误 (与K60协议地址长度为2字节)
  38.                     { I2C0_C1 |= I2C_C1_TXAK_MASK; } //返回非应答
  39.                     else
  40.                     {
  41.                     delay_us(200);
  42.                     I2C0_D = *i2c_temp++;
  43.                 }  //发送第一个数据  
  44.                 }
  45.                 else
  46.                 {
  47.                     GucSlaverMode = 1;  //从接收模式      
  48.                     I2C0_C1 &= ~I2C_C1_TX_MASK;  //接收模式                          
  49.                     GulCounter = 0;               
  50.                     if (I2C0_D) ; //读一次                                      
  51.                 }
  52. //            printf("地址匹配模式: %d\n",GucSlaverMode);
  53.             }
  54.             else
  55.             {
  56.                 switch (GucSlaverMode)
  57.                 {
  58.                     case 0: //从发送(主读)
  59.                     {
  60.                     if(GulCounter>1)
  61.                     {
  62.                         if (I2C0_S & I2C_S_RXAK_MASK) //应答检测
  63.                         {         
  64.                             //主机应答失败,停止发送                                               
  65.                             I2C0_C1 &= ~I2C_C1_TX_MASK;  // 接收模式         
  66.                             if (I2C0_D) ;   //读一次  
  67. //                            printf("非应答%d\n",GulCounter);
  68.                         }
  69.                         else
  70.                         {
  71.                             delay_us(200);
  72.                             I2C0_D  = *i2c_temp++;  //发送其他数据
  73. //                            printf("应答发送%d\n",GulCounter);
  74.                         }
  75.                     }
  76.                     }break;
  77.                     case 1: // 从接收模式(主写)
  78.                     {
  79.                         if (GulCounter < 2) //接收寄存器地址(宽度为2)
  80.                     {  
  81.                                 GulAdr = (GulAdr << 8) + I2C0_D;
  82.                             GulCounter++;  
  83.                             if(GulCounter==2)
  84.                         {
  85.                             i2c_temp=i2c_slave_handle(GulAdr);
  86.                         }
  87. //                        printf("访问地址: %04x  %d\n",GulAdr,GulCounter);
  88.                         }
  89.                         else
  90.                         {
  91. //                        rev = I2C0_D;
  92.                                 *i2c_temp++ = I2C0_D;
  93.                         delay_us(150);
  94.                         }
  95.                     }break;
  96.                     default :
  97.                     {
  98.                         I2C0_C1 &= ~I2C_C1_TX_MASK; //接收模式              
  99.                         if (I2C0_D) ;    //读一次                                             
  100.                     }break;
  101.                 }   
  102.             }   
  103. //        }
  104. //        EnableInterrupts;
  105. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-7-19 09:57 , Processed in 0.095048 second(s), 25 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表