|
总感觉模拟IIC总线读写24C256有点浪费时间,然后就想弄个硬件IIC来读写24C256,可是呢,直接操作寄存器总是不成功,最终还是弄的库。这个是参考了网友的程序改的,网名忘记叫啥了,真是惭愧。感谢硬汉对开源的无私奉献,本人才学疏浅搞不了原创,就把网友的程序改动了少许来献丑啦。
- /**
- *****************************************************************************
- *
- * @文件名: iic.c
- * @版 本: V1.0
- * @日 期: 2020-7-1
- * @作 者: 振德
- * @备 注:
- *****************************************************************************
- **/
- #include "IIC.h"
- /******************************************************************************
- * 硬件IIC初始化
- */
- void IIC_Init(I2C_TypeDef* IICx, uint08 SlaveAdd)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- I2C_InitTypeDef I2C_InitStructure;
-
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
- GPIOD->MODER &= ~GPIO_MODER_MODER3; /*00:输入;01:通用输出;10:复用输出;11:模拟输入*/
- GPIOD->MODER |= GPIO_MODER_MODER3_0;
-
- I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
- I2C_InitStructure.I2C_OwnAddress1 = SlaveAdd; //从设备地址
- I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
- I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
- I2C_InitStructure.I2C_ClockSpeed = (100 * 1000); //SCL最大100KHz
-
-
- I2C_Cmd(IICx, ENABLE);
- I2C_Init(IICx, &I2C_InitStructure);
- I2C_AcknowledgeConfig(IICx, ENABLE);
-
- IICx->CR1 |= 1u << 7;/*禁止时钟延长*/
- }
- /*******************************************************************************
- * 硬件IIC等待从设备内部操作完成
- */
- void IICWaiteStandby(I2C_TypeDef* IICx, uint08 SlaveAdd)
- {
- u16 tmp = 0;
- TestValues.BootRunTime = 0;
- IICx->SR1 &= 0x0000;/*清除状态寄存器1*/
- tmp = tmp;
- do {
- TestValues.BootRunTime ++;
- I2C_GenerateSTART(IICx, ENABLE);/*产生起始信号*/
- tmp = IICx->SR1;/*读取SR1寄存器,然后通过写入数据寄存器来清除SB位*/
- I2C_Send7bitAddress(IICx, SlaveAdd, I2C_Direction_Transmitter);/*发送从设备地址*/
- if (TestValues.BootRunTime > 1680000)
- break;
- }
- while ((IICx->SR1 & 0x0002) == 0x0000);/*当ADDR = 1时,表明应答了,退出循环*/
- I2C_ClearFlag(IICx, I2C_FLAG_AF); /*清除应答失败标志位*/
- I2C_GenerateSTOP(IICx, ENABLE); /*发送停止信号*/
- }
- /*******************************************************************************
- * @功能: 硬件IIC发送一个字节数据
- * @输入: I2Cx: IIC组
- * SlaveAdd:从设备时识别地址
- * WriteAdd: 写入EEPROM内存地址
- * Data: 写入的数据
- * @返回: *err: 返回的错误值
- */
- void IICWriteOneByte(I2C_TypeDef* IICx, uint08 SlaveAdd, uint08 WriteAdd, uint08 Data, uint08 * err)
- {
- u16 temp = 0;
-
- while (I2C_GetFlagStatus(IICx, I2C_FLAG_BUSY))/*等待IIC*/
- {
- temp++;
- if (temp > 800)
- {
- *err |= 1<<0;
- I2C_GenerateSTOP(IICx, ENABLE);/*产生停止信号*/
- return;
- }
- }
-
- I2C_GenerateSTART(IICx, ENABLE);/*产生起始信号*/
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_MODE_SELECT))
- {
- temp++;
- if (temp > 800)
- {
- *err |= 1<<1;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
-
- I2C_Send7bitAddress(IICx, SlaveAdd, I2C_Direction_Transmitter);/*发送设备地址*/
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){
- temp++;
- if (temp > 1000){
- *err |= 1<<2;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
-
- temp = IICx->SR2;/*读取SR1寄存器后,对SR2寄存器的读操作将清除ADDR位*/
-
- I2C_SendData(IICx, WriteAdd);/*发送存储地址*/
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTING)){
- temp++;
- if (temp > 800) {
- *err |= 1<<3;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- I2C_SendData(IICx, Data);/*发送数据*/
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
- {
- temp++;
- if (temp > 800)
- {
- *err |= 1<<4;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- I2C_GenerateSTOP(IICx, ENABLE);
- }
- /*****************************************************************************
- * @功能: 硬件IIC读取一个字节数据
- * @输入: I2Cx: IIC组
- * SlaveAdd: 作为从设备时识别地址
- * ReadAdd: 读取的EEPROM内存地址
- * @返回: *err: 返回的错误值
- * 读取到的数据
- */
- uint08 IIC_ReadOneByte(I2C_TypeDef* IICx, uint08 SlaveAdd, uint08 ReadAdd, uint08 * err)
- {
- vuint16 i = 0;
- vuint08 temp = 0;
- vuint16 flag = 0;
-
- while (I2C_GetFlagStatus(IICx, I2C_FLAG_BUSY)){
- i++;
- if (i > 800){
- *err |= 1<<0;
- I2C_GenerateSTOP(IICx, ENABLE);
- return 0;
- }
- }
- I2C_GenerateSTART(IICx, ENABLE);
-
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_MODE_SELECT)){
- i++;
- if (i > 1000){
- *err |= 1<<1;
- I2C_GenerateSTOP(IICx, ENABLE);
- return 0;
- }
- }
- I2C_Send7bitAddress(IICx, SlaveAdd, I2C_Direction_Transmitter);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){
- if (i > 1000){
- *err |= 1<<2;
- I2C_GenerateSTOP(IICx, ENABLE);
- return 0;
- }
- }
- flag = IICx->SR2;
-
- I2C_SendData(IICx, ReadAdd);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTING)){
- i++;
- if (i > 2000){
- *err |= 1<<3;
- I2C_GenerateSTOP(IICx, ENABLE);
- return 0;
- }
- }
- I2C_GenerateSTART(IICx, ENABLE);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_MODE_SELECT)){
- i++;
- if (i > 800){
- *err |= 1<<4;
- I2C_GenerateSTOP(IICx, ENABLE);
- return 0;
- }
- }
- I2C_Send7bitAddress(IICx, SlaveAdd, I2C_Direction_Receiver);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){//EV6
- i++;
- if (i > 800){
- *err |= 1<<5;
- I2C_GenerateSTOP(IICx, ENABLE);
- return 0;
- }
- }
- flag = IICx->SR2;
-
- I2C_AcknowledgeConfig(IICx, DISABLE);/*发送NACK*/
- I2C_GenerateSTOP(IICx, ENABLE);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_RECEIVED)){
- i++;
- if (i > 1000){
- *err |= 1<<6;
- I2C_GenerateSTOP(IICx, ENABLE);
- return 0;
- }
- }
- temp = I2C_ReceiveData(IICx);
- I2C_AcknowledgeConfig(IICx, ENABLE);
-
- return temp;
- }
- /*****************************************************************************
- * @功能: 硬件IIC发送多个字节数据
- * @输入: I2Cx: IIC组
- * SlaveAdd: 作为从设备时识别地址
- * WriteAdd: 写入EEPROM内存起始地址
- * NumToWrite: 写入数据量
- * *pBuffer: 写入的数据组缓存
- * @输出: *err: 返回的错误值
- */
- void IIC_WriteNByte(I2C_TypeDef * IICx, uint08 SlaveAdd, uint16 WriteAdd, uint08 NumToWrite, uint08 * pBuffer, u8 * err)
- {
- vuint16 temp = 0;
- vuint16 Addr = WriteAdd;
-
- while (I2C_GetFlagStatus(IICx, I2C_FLAG_BUSY)){
- temp++;
- if (temp > 1000) {
- *err |= 1<<0;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- I2C_GenerateSTART(IICx, ENABLE);
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_MODE_SELECT))
- {
- temp++;
- if (temp > 1000) {
- *err |= 1<<1;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- I2C_Send7bitAddress(IICx, SlaveAdd, I2C_Direction_Transmitter);
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){
- temp++;
- if (temp > 1000){
- *err |= 1<<2;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- temp = IICx->SR2;
- // if (Addr & 0xff00){
- I2C_SendData(IICx, (uint08)(Addr >> 8)); /*发送存储高8位地址*/
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTING)){//EV8
- temp++;
- if (temp > 1000){
- *err |= 1<<3;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- //}
- I2C_SendData(IICx, (Addr & 0x00ff)); /*发送存储低8位地址*/
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTING)){//EV8
- temp++;
- if (temp > 1000){
- *err |= 1<<3;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- while (NumToWrite--){
- I2C_SendData(IICx, *pBuffer); /*发送数据*/
- pBuffer++;
- temp = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
- temp++;
- if (temp > 1000){
- *err |= 1<<4;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- }
- I2C_GenerateSTOP(IICx, ENABLE);
- }
- /******************************************************************************
- * @功能: 硬件IIC读取多个字节数据
- * @输入: I2Cx: IIC组
- * SlaveAdd: 作为从设备时识别地址
- * ReadAdd: 读取的EEPROM内存起始地址
- * NumToRead: 读取数量
- * @输出: *pBuffer: 数据输出缓冲区
- **/
- void IIC_PageRead(I2C_TypeDef* IICx, uint08 SlaveAdd, uint16 ReadAdd, uint08 NumToRead, uint08 * pBuffer, uint08 * err)
- {
- vuint16 i = 0;
- vuint16 temp = 0;
- vuint16 Addr = ReadAdd;
-
- while (I2C_GetFlagStatus(IICx, I2C_FLAG_BUSY)){
- i++;
- if (i > 1000){
- *err |= 1<<0;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- I2C_GenerateSTART(IICx, ENABLE);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_MODE_SELECT)){
- i++;
- if (i > 800){
- *err |= 1<<1;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- I2C_Send7bitAddress(IICx, SlaveAdd, I2C_Direction_Transmitter);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){
- i++;
- if (i > 1000){
- *err |= 1<<2;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- i = IICx->SR2;
-
- // if (Addr & 0xff00){
- I2C_SendData(IICx, (uint08)(Addr >> 8)); /*发送存储高8位地址*/
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTING)){//EV8
- i++;
- if (i > 2000){
- *err |= 1<<3;
- I2C_GenerateSTOP(IICx, ENABLE); /*出错,产生停止信号*/
- return;
- }
- }
- // }
- I2C_SendData(IICx, (uint08)(Addr & 0x00ff)); /*发送存储低8位地址*/
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTING)){//EV8
- i++;
- if (i > 2000){
- *err |= 1<<3;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- I2C_GenerateSTART(IICx, ENABLE);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_MODE_SELECT)){//EV5
- i++;
- if (i > 800){
- *err |= 1<<4;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- I2C_Send7bitAddress(IICx, SlaveAdd, I2C_Direction_Receiver);
- i = 0;
- while (!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){
- i++;
- if (i > 800)
- {
- *err |= 1<<5;
- I2C_GenerateSTOP(IICx, ENABLE);
- return;
- }
- }
- i = IICx->SR2;
-
- while (NumToRead){/*批量接收数据*/
- if (NumToRead == 1){ /*最后一个数据了,不发送应答信号*/
- I2C_AcknowledgeConfig(IICx, DISABLE); /*发送NACK*/
- I2C_GenerateSTOP(IICx, ENABLE);
- }
- if (I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_RECEIVED)){
- *pBuffer = I2C_ReceiveData(IICx);
- pBuffer++;
- NumToRead--;
- }
- }
- I2C_AcknowledgeConfig(IICx, ENABLE);
- }
- /*****************************************************************************
- * @功能: AT24Cxx页写函数
- *
- * @输入: I2Cx: IIC组
- * SlaveAdd: 从设备地址
- * WriteAdd: 写入EEPROM内存起始地址
- * NumToWrite: 写入数据量
- * *pBuffer: 写入的数据组缓存
- *
- */
- void IIC_PageWrite(I2C_TypeDef * IICx, uint08 SlaveAdd, uint16 WriteAdd, uint08 NumToWrite, uint08 * pBuffer, uint08 * err)
- {
- vuint16 Num_Page = 0; /*按照页大小需要写入的次数*/
- vuint16 Num_Remain = 0; /*页写剩余字节数*/
- vuint16 Addr = 0; /*数据块首地址为EEPROM页数整数倍*/
- vuint16 cnt = 0;
-
- wp_BL24Cxx = 0;
-
- Addr = WriteAdd % AT24Cxx_PageSize; /*计算数据块首地址是否是页大小的整数倍*/
- cnt = AT24Cxx_PageSize - Addr;
- Num_Page = NumToWrite / AT24Cxx_PageSize; /*得到次数*/
- Num_Remain = NumToWrite % AT24Cxx_PageSize; /*剩余字节数*/
-
- if (Addr == 0){ /*是整数倍*/
- if (Num_Page == 0){ *
- IIC_WriteNByte(IICx, SlaveAdd, WriteAdd, Num_Remain, pBuffer, err); /*小于一个页大小数据*/
- IICWaiteStandby(IICx, SlaveAdd); //等待操作完成
- }
- else{ /*大于一页数据*/
- while (Num_Page--){ /*按照页来写*/
- IIC_WriteNByte(IICx, SlaveAdd, WriteAdd, AT24Cxx_PageSize, pBuffer, err);
- IICWaiteStandby(IICx, SlaveAdd);
- WriteAdd += AT24Cxx_PageSize;
- pBuffer += AT24Cxx_PageSize;
- }
- if (Num_Remain != 0){ /*不够一个页的数据*/
- IIC_WriteNByte(IICx, SlaveAdd, WriteAdd, Num_Remain, pBuffer, err);
- IICWaiteStandby(IICx, SlaveAdd);
- }
- }
- }
- else { /*不是整数倍*/
- if (Num_Page == 0){
- IIC_WriteNByte(IICx, SlaveAdd, WriteAdd, Num_Remain, pBuffer, err); /*写入小于一个页的数据量*/
- IICWaiteStandby(IICx, SlaveAdd);
- }
- else {
- NumToWrite -= cnt;
- Num_Page = NumToWrite / AT24Cxx_PageSize;
- Num_Remain = NumToWrite % AT24Cxx_PageSize;
-
- if (cnt != 0){
- IIC_WriteNByte(IICx, SlaveAdd, WriteAdd, cnt, pBuffer, err);
- IICWaiteStandby(IICx, SlaveAdd);
- WriteAdd += cnt;
- pBuffer += cnt;
- }
- while (Num_Page--) { /*按照页来写*/
- IIC_WriteNByte(IICx, SlaveAdd, WriteAdd, AT24Cxx_PageSize, pBuffer, err);
- IICWaiteStandby(IICx, SlaveAdd);
- WriteAdd += AT24Cxx_PageSize;
- pBuffer += AT24Cxx_PageSize;
- }
- if (Num_Remain != 0) {
- IIC_WriteNByte(IICx, SlaveAdd, WriteAdd, Num_Remain, pBuffer, err); /*小于一个页大小数据*/
- IICWaiteStandby(IICx, SlaveAdd);
- }
- }
- }
- wp_BL24Cxx = 1;
- }
- /*****************************************************************************
- * @功能: 确定系统是否有AT24Cxx
- * @输入: I2Cx: IIC组
- *
- * @返回: 1:检测到AT24Cxx,0:没有检测到AT24Cxx
- */
- uint08 AT24CXX_Check(I2C_TypeDef * IICx)
- {
- vuint08 temp;
- vuint08 i;
- temp = IIC_ReadOneByte(IICx ,BL2408Add, 0,&i);
- if(temp == 0x55){
- return 1;
- }
- else {
- wp_BL24Cxx = 0;
- IICWriteOneByte(IICx ,BL2408Add, 0,0x55,&i);
- temp = IIC_ReadOneByte(IICx ,BL2408Add, 0,&i);
- wp_BL24Cxx = 1;
- if(temp == 0x55)return 1;
- }
- return 0;
- }
复制代码
|
评分
-
查看全部评分
|