[STM8] 有没有人提供一个I2C中断程序,急急急

[复制链接]
4746|6
 楼主| 菜鸟小王 发表于 2012-8-21 14:50 | 显示全部楼层 |阅读模式
有没有人提供一个I2C中断程序。等着用呢。硬件查询的方法,硬件I2C老是怪掉,奇了怪了。
acgean 发表于 2012-8-21 15:44 | 显示全部楼层
ST 的函数库里的例子还是比较丰富的, 去哪里找找呢
figo20042005 发表于 2012-8-21 16:29 | 显示全部楼层
/**
  * @brief  This function handles I2C1 Event interrupt request, tx, rx
  *         buffer and number of bytes will be changed.
  * @param  None
  * @retval None
  */
void I2C1_EV_IRQHandler(void)
{
#ifdef ARC_I2C_IRQ
    uint32_t i2cEvent;
    I2C_param_struct __IO *pI2C_param;

    pI2C_param = ARC_get_I2C_param();
    i2cEvent = I2C_GetLastEvent(I2C1);
   
    switch (i2cEvent)
    {
        case I2C_EVENT_MASTER_MODE_SELECT:/* EV5 */
            if(pI2C_param->I2C_DIRECTION == ARC_I2C_DIRECTION_TX)
            {
                I2C_Send7bitAddress(I2C1, pI2C_param->DeviceAddr, I2C_Direction_Transmitter);
            }
            else
            {
                I2C_Send7bitAddress(I2C1, pI2C_param->DeviceAddr, I2C_Direction_Receiver);
            }
            break;

        /* Master Transmitter -------------------------------------------------------*/
        case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
            I2C_SendData(I2C1, pI2C_param->SubAddr);
            if(pI2C_param->TxNumOfBytes == 0)
                I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);
            break;
           
        case I2C_EVENT_MASTER_BYTE_TRANSMITTING:  /* Without BTF, EV8 */     
            if(pI2C_param->TX_I2C_Index < pI2C_param->TxNumOfBytes)
            {
                I2C_SendData(I2C1, pI2C_param->TxData[pI2C_param->TX_I2C_Index++]);
            }
            else
            {      
                I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);
            }
            break;

        case I2C_EVENT_MASTER_BYTE_TRANSMITTED: /* With BTF EV8-2 */
           if(pI2C_param->TX_Generate_stop == 1)
           {
             I2C_GenerateSTOP(I2C1, ENABLE);
             I2C_ITConfig(I2C1, I2C_IT_EVT, DISABLE);
           }
           else
           {
             pI2C_param->I2C_DIRECTION = ARC_I2C_DIRECTION_RX;
             I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
             I2C_GenerateSTART(I2C1, ENABLE);
           }
           break;

        /* Master Receiver -------------------------------------------------------*/
        case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
            if(pI2C_param->RX_I2C_Index == (pI2C_param->RxNumOfBytes - 1))
            {
                I2C_AcknowledgeConfig(I2C1, DISABLE);
                I2C_GenerateSTOP(I2C1, ENABLE);
            }
            break;

        case I2C_EVENT_MASTER_BYTE_RECEIVED:
            pI2C_param->RxData[pI2C_param->RX_I2C_Index++] = I2C_ReceiveData (I2C1);
            if(pI2C_param->RX_I2C_Index == (pI2C_param->RxNumOfBytes - 1))
            {
                I2C_AcknowledgeConfig(I2C1, DISABLE);
                I2C_GenerateSTOP(I2C1, ENABLE);
            }
            break;

        default:
            break;
    }

#endif
}
请参考此贴  https://bbs.21ic.com/icview-304149-1-1.html
jgphu 发表于 2012-8-29 15:25 | 显示全部楼层
我在调TEL6621的时候的一个I2C 程序。用的是中断

注意: TEL6621 的I2C read 是如下这样的

start  ADDR  D0 D1 D2 D3 STOP

I2C.C

  1. #include "main.h"
  2. I2C_StruDef I2C1;
  3. void Bsp_I2CInit(void)
  4. {
  5. CLK_PCKENR1 |= 0x01;

  6. I2C_CR1    = 0x00;       //禁用I2C外设

  7. //如果需产生100k的时钟,假始输入时钟为8MHz,则Tck = 125ns.
  8. //因为100k时钟半个周期为5us(5000ns), CCR = 5000/125 = 40(28h)
  9. I2C_FREQR  = 16;         //输入外设时钟频率为16MHz (如果设置为8M, 实际输入是16M时,I2C时钟以16M为准)
  10. I2C_CCRH   = 0x00;       //标准模式
  11. I2C_CCRL   = 0x50;

  12. //标准模式下,最大允许上升时间为1000ns, 因为Tck = 125ns,
  13. //则TRISER = (1000 / 125 + 1) = 9
  14. I2C_TRISER = 0x09;       //设置上升时间

  15. I2C_CR1    = 0x01;       //开启I2C外设
  16. }
  17. void Bsp_I2CWrite(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num)
  18. {
  19. if(0x02 == (I2C_SR3 & 0x02))
  20. {
  21.   ;
  22. }
  23.   else
  24. {
  25.   I2C1.State      = I2C_WRITEMODE;
  26.   I2C1.DeviceAddr = Dev_Addr;
  27.   I2C1.SubAddr    = Sub_Addr;
  28.   I2C1.Tx_I2C_Buf = pdata;
  29.   I2C1.Tx_Cnt     = num;
  30.   I2C1.Rx_Cnt     = 0;
  31.   I2C1.Cnt        = 0;
  32.   
  33.   I2C_ITR = 0x07; //使能事件和出错中断, 缓冲中断
  34.   I2C_CR2 = 0x01; //产生开始位
  35. }
  36. }
  37. void Bsp_I2CRead(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num)
  38. {
  39. if(0x02 == (I2C_SR3 & 0x02))
  40. {
  41.   ;
  42. }
  43. else
  44. {
  45.   I2C1.State      = I2C_READMODE;
  46.   I2C1.DeviceAddr = Dev_Addr;
  47.   I2C1.SubAddr    = Sub_Addr;
  48.   I2C1.Rx_I2C_Buf = pdata;
  49.   I2C1.Rx_Cnt     = num;
  50.   I2C1.Tx_Cnt     = 0;
  51.   I2C1.Cnt        = 0;
  52.   
  53.   I2C_ITR = 0x07; //使能事件和出错中断, 缓冲中断
  54.   I2C_CR2 = 0x01; //产生开始位
  55. }

  56. TIM2DlyHMSM(0, 0, 0, 10);
  57. }
  58. void I2C_Interrupt_Handler(void)
  59. {
  60. uint8_t temp;

  61. if(0x01 == (I2C_SR1 & 0x01)) //EV5, 开始位已发送
  62. {
  63.   temp = I2C_SR1;
  64.   
  65.   if(I2C_WRITEMODE == I2C1.State)
  66.    I2C_DR = I2C1.DeviceAddr & 0xfe;
  67.   else if(I2C_READMODE == I2C1.State)
  68.    I2C_DR = I2C1.DeviceAddr | 0x01;
  69.   else;
  70. }
  71. else if(0x02 == (I2C_SR1 & 0x02)) //EV6, 器件地址已发送
  72. {
  73.   temp = I2C_SR1;
  74.   temp = I2C_SR3;
  75.   
  76.   if(I2C_WRITEMODE == I2C1.State)
  77.    I2C_DR = I2C1.SubAddr;
  78.   else if(I2C_READMODE == I2C1.State)
  79.   {
  80.    if(I2C1.Rx_Cnt > 1)        I2C_CR2 = 0x04;
  81.       else if(I2C1.Rx_Cnt == 1)  I2C_CR2 = 0x00;
  82.    else                       I2C_CR2 = 0x02;  //产生STOP位
  83.   }
  84.   else;
  85. }
  86. else if(0x40 == (I2C_SR1 & 0x40)) //EV7
  87. {
  88.   if(I2C1.Cnt < (I2C1.Rx_Cnt - 1))
  89.   {
  90.    I2C1.Rx_I2C_Buf[I2C1.Cnt] = I2C_DR;
  91.    I2C1.Cnt++;
  92.    
  93.    if(I2C1.Cnt == (I2C1.Rx_Cnt - 1))
  94.    {
  95.     I2C_CR2 = 0x02;  //产生STOP位, no ack
  96.    }
  97.   }
  98.   else if(I2C1.Cnt == (I2C1.Rx_Cnt - 1))
  99.   {
  100.    I2C1.Rx_I2C_Buf[I2C1.Cnt] = I2C_DR;
  101.   }
  102.   else;
  103. }
  104. else if(0x80 == (I2C_SR1 & 0x80)) //EV8
  105. {
  106.   temp = I2C_SR1;
  107.   
  108.   if(I2C1.Cnt < I2C1.Tx_Cnt)
  109.   {
  110.    I2C_DR = I2C1.Tx_I2C_Buf[I2C1.Cnt];
  111.    I2C1.Cnt++;
  112.   }
  113.   else
  114.   {
  115.    I2C_CR2 = 0x02;  //产生STOP位
  116.   }
  117. }
  118. else
  119. {
  120.   printf("\r\n I2C_SR1 = %x", (uint16_t)I2C_SR1);
  121.   temp = I2C_SR1;
  122. }

  123. if(I2C_SR2)
  124. {
  125.   printf("\r\n I2C_SR2 = %x", (uint16_t)I2C_SR2);
  126.   I2C_SR2 = 0;
  127. }
  128. }

I2C.H

  1. #ifndef _BSP_I2C_H_
  2. #define _BSP_I2C_H_
  3. #define I2C_WRITEMODE      0
  4. #define I2C_READMODE       1

  5. typedef struct
  6. {
  7.   uint8_t  State;
  8.   uint16_t Cnt;
  9.   uint16_t Rx_Cnt, Tx_Cnt;
  10.   uint8_t  DeviceAddr;
  11.   uint8_t  SubAddr;
  12.   uint8_t  *Rx_I2C_Buf;
  13. uint8_t  *Tx_I2C_Buf;
  14. }I2C_StruDef;
  15. extern I2C_StruDef I2C1;

  16. void Bsp_I2CInit(void);
  17. void Bsp_I2CWrite(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num);
  18. void Bsp_I2CRead(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num);
  19. void I2C_Interrupt_Handler(void);

  20. #endif

香水城 发表于 2012-8-29 17:17 | 显示全部楼层
ST提供I2C和CPAL两种I2C通信例程库

LZ都可以下载了参考
 楼主| 菜鸟小王 发表于 2012-8-30 14:25 | 显示全部楼层
非常感谢大家。特别是jgphu, 按照你的方法,我的I2C中断法已经成功了。同时感谢figo20042005。
yinhaix 发表于 2015-12-3 13:51 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

2

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部