读卡器项目总结(三)— I2C通信
2016-02-08 15:06
295 查看
<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; } }
相关文章推荐
- Kinect For Windows V2开发日志六:人体的轮廓的表示
- python的拷贝(深拷贝和浅拷贝)
- apt-get 安装路径
- 百元买百鸡
- Python成长之路第二篇(2)_列表元组内置函数用法
- 第八章 JVM性能监控与故障处理工具(2)
- 开灯问题
- R语言学习(一)
- -boundingRectWithSize:options:attributes:context:用法
- ThinkPHP - I 函数
- 分数化小数
- 3、随机森林
- Python 第五篇(下):系统标准模块(shutil、logging、shelve、configparser、subprocess、xml、yaml、自定义模块)
- Redis缓存服务器Java客户端Jedis2.8 demo
- c 编程中的exit(-1)和 return -1
- 1.2.1Logistic回归实例
- ThinkPHP - 模板使用函数
- win10的酒店上网记
- 2016小目标
- 倒三角形