打印
[STM8]

I2C中断程序

[复制链接]
531|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhanghqi|  楼主 | 2016-10-28 21:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

有没有人提供一个I2C中断程序。等着用呢。
沙发
dengdc| | 2016-10-28 21:56 | 只看该作者
楼主详细说说怎么回事啊,这么说太笼统了

使用特权

评论回复
板凳
zhanghqi|  楼主 | 2016-10-28 21:58 | 只看该作者
硬件查询的方法,硬件I2C老是怪掉,奇了怪了。

使用特权

评论回复
地板
jiahy| | 2016-10-28 22:00 | 只看该作者
ST 的函数库里的例子还是比较丰富的, 去哪里找找呢

使用特权

评论回复
5
lizye| | 2016-10-28 22:04 | 只看该作者
/**
  * @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
}

使用特权

评论回复
6
shimx| | 2016-10-28 22:06 | 只看该作者
我在调TEL6621的时候的一个I2C 程序。用的是中断

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

start  ADDR  D0 D1 D2 D3 STOP

I2C.C

使用特权

评论回复
7
shimx| | 2016-10-28 22:08 | 只看该作者

#include "main.h"
I2C_StruDef I2C1;
void Bsp_I2CInit(void)
{
CLK_PCKENR1 |= 0x01;

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

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

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

I2C_CR1    = 0x01;       //开启I2C外设
}
void Bsp_I2CWrite(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num)
{
if(0x02 == (I2C_SR3 & 0x02))
{
  ;
}
  else
{
  I2C1.State      = I2C_WRITEMODE;
  I2C1.DeviceAddr = Dev_Addr;
  I2C1.SubAddr    = Sub_Addr;
  I2C1.Tx_I2C_Buf = pdata;
  I2C1.Tx_Cnt     = num;
  I2C1.Rx_Cnt     = 0;
  I2C1.Cnt        = 0;
  
  I2C_ITR = 0x07; //使能事件和出错中断, 缓冲中断
  I2C_CR2 = 0x01; //产生开始位
}
}
void Bsp_I2CRead(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num)
{
if(0x02 == (I2C_SR3 & 0x02))
{
  ;
}
else
{
  I2C1.State      = I2C_READMODE;
  I2C1.DeviceAddr = Dev_Addr;
  I2C1.SubAddr    = Sub_Addr;
  I2C1.Rx_I2C_Buf = pdata;
  I2C1.Rx_Cnt     = num;
  I2C1.Tx_Cnt     = 0;
  I2C1.Cnt        = 0;
  
  I2C_ITR = 0x07; //使能事件和出错中断, 缓冲中断
  I2C_CR2 = 0x01; //产生开始位
}

TIM2DlyHMSM(0, 0, 0, 10);
}
void I2C_Interrupt_Handler(void)
{
uint8_t temp;

if(0x01 == (I2C_SR1 & 0x01)) //EV5, 开始位已发送
{
  temp = I2C_SR1;
  
  if(I2C_WRITEMODE == I2C1.State)
   I2C_DR = I2C1.DeviceAddr & 0xfe;
  else if(I2C_READMODE == I2C1.State)
   I2C_DR = I2C1.DeviceAddr | 0x01;
  else;
}
else if(0x02 == (I2C_SR1 & 0x02)) //EV6, 器件地址已发送
{
  temp = I2C_SR1;
  temp = I2C_SR3;
  
  if(I2C_WRITEMODE == I2C1.State)
   I2C_DR = I2C1.SubAddr;
  else if(I2C_READMODE == I2C1.State)
  {
   if(I2C1.Rx_Cnt > 1)        I2C_CR2 = 0x04;
      else if(I2C1.Rx_Cnt == 1)  I2C_CR2 = 0x00;
   else                       I2C_CR2 = 0x02;  //产生STOP位
  }
  else;
}
else if(0x40 == (I2C_SR1 & 0x40)) //EV7
{
  if(I2C1.Cnt < (I2C1.Rx_Cnt - 1))
  {
   I2C1.Rx_I2C_Buf[I2C1.Cnt] = I2C_DR;
   I2C1.Cnt++;
   
   if(I2C1.Cnt == (I2C1.Rx_Cnt - 1))
   {
    I2C_CR2 = 0x02;  //产生STOP位, no ack
   }
  }
  else if(I2C1.Cnt == (I2C1.Rx_Cnt - 1))
  {
   I2C1.Rx_I2C_Buf[I2C1.Cnt] = I2C_DR;
  }
  else;
}
else if(0x80 == (I2C_SR1 & 0x80)) //EV8
{
  temp = I2C_SR1;
  
  if(I2C1.Cnt < I2C1.Tx_Cnt)
  {
   I2C_DR = I2C1.Tx_I2C_Buf[I2C1.Cnt];
   I2C1.Cnt++;
  }
  else
  {
   I2C_CR2 = 0x02;  //产生STOP位
  }
}
else
{
  printf("\r\n I2C_SR1 = %x", (uint16_t)I2C_SR1);
  temp = I2C_SR1;
}

if(I2C_SR2)
{
  printf("\r\n I2C_SR2 = %x", (uint16_t)I2C_SR2);
  I2C_SR2 = 0;
}
}

使用特权

评论回复
8
spark周| | 2016-10-28 22:10 | 只看该作者
I2C.H

#ifndef _BSP_I2C_H_
#define _BSP_I2C_H_
#define I2C_WRITEMODE      0
#define I2C_READMODE       1

typedef struct
{
  uint8_t  State;
  uint16_t Cnt;
  uint16_t Rx_Cnt, Tx_Cnt;
  uint8_t  DeviceAddr;
  uint8_t  SubAddr;
  uint8_t  *Rx_I2C_Buf;
uint8_t  *Tx_I2C_Buf;
}I2C_StruDef;
extern I2C_StruDef I2C1;

void Bsp_I2CInit(void);
void Bsp_I2CWrite(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num);
void Bsp_I2CRead(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num);
void I2C_Interrupt_Handler(void);

#endif

使用特权

评论回复
9
午夜粪车| | 2016-10-28 22:12 | 只看该作者
ST提供I2C和CPAL两种I2C通信例程库

LZ都可以下载了参考

使用特权

评论回复
10
zhanghqi|  楼主 | 2016-10-28 22:14 | 只看该作者
非常感谢大家。按照大家的方法,我的I2C中断法已经成功了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

852

主题

11757

帖子

5

粉丝