您的位置:首页 > 其它

读卡器项目总结(三)— 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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: