读卡器项目总结(三)— I2C通信

来源:互联网 发布:centos 7.4搭建lnmp 编辑:程序博客网 时间:2024/04/29 09:20

<span style="font-family: Arial, Helvetica, sans-serif;">IIC通信:本次项目用于主控芯片与秘钥芯片通信,使用的是ST公司的官方库。以下直接贴出整套代码:分为两台通信机由于当时没有真正地讲I2C集成为函数,所以会利用中断和全局变量来传输数据。</span>
<span style="font-family: Arial, Helvetica, sans-serif;"></span>
<span style="font-family: Arial, Helvetica, sans-serif;">通信机一号:集成代码库</span>

/******************************************************************************* * 文件名称:IIC硬件库 * 功能:IIC硬件功能集成 * 注意:1)全局变量的引入 *       2)调用IIC中断发送数据  *  *******************************************************************************//* 包含系统头文件 *//* 包含自定义头文件 */#include "iic.h"/* 自定义新类型 *//* 自定义变量或宏表达式 */__IO uint8_t Rx_Idx = 0, Tx_Idx = 0;/*地址计量*/__IO uint8_t Receive_NumOfBytes = BUFFERSIZE;/*接受通讯量计量*/__IO uint8_t Send_NumOfBytes = BUFFERSIZE;/*发送通讯量计量*/uint8_t RxBuffer[6];/*接受通讯数组*/uint8_t TxBuffer[255];/*发送通讯数组*/uint8_t IIC_Commmand = 0xFF;/*UART接收IIC命令(非必要变量)*/uint8_t IIC_Send[255]={0x00};/*发送数据负载数组(非必要变量)*//* 自定义宏 *//*实现函数部分*/static void Delay(__IO uint32_t nCount);/*函数内部延时*//******************************************************************** * 函数名:IIC_Config * 描述  :关于IIC的配置 * 输入  :无 * 输出  :无 * 调用  :外部调用 ********************************************************************/void IIC_Config(void){  I2C_DeInit();  I2C_Init(I2C_SPEED, 0xA0, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);  I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , ENABLE);  ITC_SetSoftwarePriority(ITC_IRQ_I2C, ITC_PRIORITYLEVEL_3);  I2C_Cmd(ENABLE);}/******************************************************************** * 函数名:IIC_WriteByte * 描述  :IIC写数据 * 输入  :*Tx_Buffer       -写入数据指针 *         NumByteToSend   -需要写入字节数 * 输出  :无 * 调用  :外部调用 ********************************************************************/void IIC_WriteByte(uint8_t *Tx_Buffer , uint8_t NumByteToSend){    for (uint8_t i = 0; i < NumByteToSend; i++)      TxBuffer[i] = Tx_Buffer[i];        Delay(0x007F);        I2C_AcknowledgeConfig(I2C_ACK_CURR);/*主模式发送初始化*/    I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , ENABLE);    Send_NumOfBytes = NumByteToSend;/*通讯量重置*/        I2C_GenerateSTART(ENABLE);    while (Send_NumOfBytes);/*发送通讯录计量(中断处理)*/    while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));        I2C->SR1 = 0x00;    I2C->SR2 = 0x00;    I2C->SR3 = 0x00;}/******************************************************************** * 函数名:IIC_ReadByte * 描述  :通过IIC读数据 * 输入  :NumByteToRead   -需要读取字节数 * 输出  : * 调用  :外部调用 ********************************************************************/void IIC_ReadByte(uint8_t NumByteToRead){    Rx_Idx = 0x00;        Delay(0x007F);        I2C_AcknowledgeConfig(I2C_ACK_CURR);/*主模式接受初始化*/    I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , DISABLE);    Receive_NumOfBytes = NumByteToRead;/*通讯量重置*/        /*  Wait while the bus is busy */    while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));        /* Send START condition */    I2C_GenerateSTART(ENABLE);        /* Test on EV5 and clear it */    while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));        /* Send slave Address for write */    I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX);        /* Test on EV6 and clear it */    while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));        /* While there is data to be read */    while (Receive_NumOfBytes)    {      if (Receive_NumOfBytes == 1)      {        /* Disable Acknowledgement */        I2C_AcknowledgeConfig(I2C_ACK_NONE);          /* Send STOP Condition */        I2C_GenerateSTOP(ENABLE);          /* Poll on RxNE Flag */        while ((I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY) == RESET));                /* Read a byte from the Slave */        RxBuffer[Rx_Idx] = I2C_ReceiveData();          /* Point to the next location where the byte read will be saved */        Rx_Idx++;          /* Decrement the read bytes counter */        Receive_NumOfBytes--;      }            /* Test on EV7 and clear it */      if (I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED) )      {        /* Read a byte from the EEPROM */        RxBuffer[Rx_Idx] = I2C_ReceiveData();          /* Point to the next location where the byte read will be saved */        Rx_Idx++;          /* Decrement the read bytes counter */        Receive_NumOfBytes--;      }          }        I2C->SR1 = 0x00;    I2C->SR2 = 0x00;    I2C->SR3 = 0x00;}/******************************************************************** * 函数名:IIC_WriteByte * 描述  :IIC写一个数据数据 * 输入  :Tx_Data         -写入一个数据 * 输出  :无 * 调用  :外部调用 ********************************************************************/void IIC_WriteByte_One(uint8_t Tx_Data){    TxBuffer[0] = Tx_Data;/*发送数据、命令*/        Delay(0x007F);        I2C_AcknowledgeConfig(I2C_ACK_CURR);/*主模式发送初始化*/    I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , ENABLE);    Send_NumOfBytes = 1;/*通讯量重置*/        I2C_GenerateSTART(ENABLE);    while (Send_NumOfBytes);/*发送通讯录计量(中断处理)*/    while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));        I2C->SR1 = 0x00;    I2C->SR2 = 0x00;    I2C->SR3 = 0x00;}/******************************************************************** * 函数名:Delay * 描述  :延时 * 输入  :延时时间 * 输出  :无 * 调用  :内部调用 ********************************************************************/static void Delay(__IO uint32_t nCount){  for (; nCount != 0; nCount--);}通信机一号:在此机的I2C中断服务函数上添加上如下代码:/******************************************************************************  IIC主模式发送中断全局变量声明:(包含在IIC.h文件中)  NumOfBytes:     需要发送字节数  TxBuffer:       需要发送数据数组地址  Tx_Idx:         发送数组指针 ******************************************************************************/INTERRUPT_HANDLER(I2C_IRQHandler, 19){    switch (I2C_GetLastEvent())  {      /* EV5 */    case I2C_EVENT_MASTER_MODE_SELECT :      Tx_Idx = 0x00;/*每次检查起始值都必须将发送数组指针置零*/      /* Send slave Address for write */      I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);      break;          /* EV6 */    case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:      if (Send_NumOfBytes != 0)      {        /* Send the first Data */        I2C_SendData(TxBuffer[Tx_Idx++]);        /* Decrement number of bytes */        Send_NumOfBytes--;      }      if (Send_NumOfBytes == 0)      {        I2C_ITConfig(I2C_IT_BUF, DISABLE);      }      break;      /* EV8 */    case I2C_EVENT_MASTER_BYTE_TRANSMITTING:      /* Transmit Data */      I2C_SendData(TxBuffer[Tx_Idx++]);      /* Decrement number of bytes */      Send_NumOfBytes--;            if (Send_NumOfBytes == 0)      {        I2C_ITConfig(I2C_IT_BUF, DISABLE);      }      break;      /* EV8_2 */    case I2C_EVENT_MASTER_BYTE_TRANSMITTED:      /* Send STOP condition */      I2C_GenerateSTOP(ENABLE);      I2C_ITConfig(I2C_IT_EVT, DISABLE);      break;    default:      break;  }  }通信机二号:/* 包含系统头文件 *//* 包含自定义头文件 */#include "iic.h"/* 自定义新类型 *//* 自定义宏 */__IO uint8_t Slave_Buffer_Rx[255];__IO uint8_t Tx_Idx = 0, Rx_Idx = 0;__IO uint16_t Event = 0x00;__IO uint8_t IIC_Command = 0x00;/* 操作IIC命令 *//*实现函数部分*//******************************************************************** * 函数名:IIC_Config * 描述  :初始化从机IIC的配置 * 输入  :无 * 输出  :无 * 调用  :外部调用 ********************************************************************/void IIC_Config(void){   I2C_DeInit();   I2C_Init(I2C_SPEED, SLAVE_ADDRESS, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);      /* 错误中断,事件中断,缓冲中断*/   I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);   ITC_SetSoftwarePriority(ITC_IRQ_I2C, ITC_PRIORITYLEVEL_3);   I2C_Cmd(ENABLE);}通信机二号:在此机的I2C中断服务函数上添加上如下代码:INTERRUPT_HANDLER(I2C_IRQHandler, 19){  /* In order to detect unexpected events during development,     it is recommended to set a breakpoint on the following instruction.  */    /* Read SR2 register to get I2C error */  if ((I2C->SR2) != 0)  {    /* Clears SR2 register */    I2C->SR2 = 0;  }    Event = I2C_GetLastEvent();  switch (Event)  {      /******* Slave transmitter ******/      /* check on EV1 */    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:      Tx_Idx = 0;/*检测到起始位,开始计算通讯量(发送)*/      break;      /* check on EV3 */    case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:      /* Transmit data */      I2C_SendData(Key[Tx_Idx++]);      break;            /******* Slave receiver **********/      /* check on EV1*/    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:      Rx_Idx = 0;/*检测到起始位,开始计算通讯量(接收)*/      break;      /* Check on EV2*/    case I2C_EVENT_SLAVE_BYTE_RECEIVED:      /* 读取105命令,分别为管理员、超级管理员、教练、会员、裁判 */      //Slave_Buffer_Rx[Rx_Idx++] = I2C_ReceiveData();      IIC_Command= I2C_ReceiveData();      break;      /* Check on EV4 */    case (I2C_EVENT_SLAVE_STOP_DETECTED):          /* write to CR2 to clear STOPF flag */          I2C->CR2 |= I2C_CR2_ACK;      break;    default:      break;  }  }


0 0
原创粉丝点击