123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597 |
- #include "dev_at24cxx.h"
- #include <stdint.h>
- /*----------------------------------------
- * @函数名:dev_at24cxx_get_i2c1_time_limit
- * @描述: 获取i2c超时值获取-时间大约值不一定准确
- * @原理: 1、是一般i2c最迟响应时间在10ms内。
- * 2、一个while(--i)语句时间大约是0.3us。
- * 在使用过程中先获取此值,然后直接用while(--i),就是i*0.3 us了。
- * @入参: None
- * @出参: uint32_t
- * @返回值: 超时值(us)
- * @调用:
- * @被调用:
- ----------------------------------------
- * 作者 创建时间 操作
- 樊春春 2023/11/19 Create/Modify
- ----------------------------------------*/
- static uint32_t dev_at24cxx_get_i2c1_time_limit(void)
- {
- RCC_ClocksTypeDef RCC_Clocks;
- RCC_GetClocksFreq(&RCC_Clocks);
- return RCC_Clocks.SYSCLK_Frequency / 10000; // 168000000/10000=16800 5.40ms
- }
- /*----------------------------------------
- * @函数名: dev_at24cxx_read_one_byte
- * @描述: 利用硬件i2c1读取目标寄存器数据
- * @入参: 两个参数:寄存器地址,寄存器地址是否是16位
- * @arg1:目标设备地址(写地址就好了)
- * @arg2:目标8位寄存器地址
- * @arg3:寄存器地址是否是16位的
- * @arg4:读取结果指针()
- * @出参: int32_t
- * @返回值: >0 成功
- * <0 失败
- * -1 i2c busy
- * -2 i2c send start fail
- * -3 i2c send address failed
- * -4 i2c send high regAdder failed
- * -5 i2c send low regAdder failed
- * -6 i2c reSend start fail
- * -7 i2c reSend address failed
- * -8 i2c no received
- * @调用:
- * @被调用:
- ----------------------------------------
- * 作者 创建时间 操作
- 樊春春 2023/11/19 Create/Modify
- ----------------------------------------*/
- int32_t dev_at24cxx_read_one_byte(uint8_t devAdder, uint16_t regAdder, bool is16BitRegAdder, uint8_t *num)
- {
- uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
- uint32_t tmp = timeLimit;
- /*第一步:先将读指针移到指定的地址寄存器上*/
- //--判断当前i2c是否忙
- while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
- ;
- if (tmp == 0)
- // i2c busy
- return -1;
- //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
- I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
- ; // EV5事件
- if (tmp == 0)
- return -2; // i2c send start fail
- //--发送7位设备地址
- I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
- ;
- if (tmp == 0)
- return -3; // i2c send address failed
- // 清零事件EV6 ADDR位(先读SR1再读SR2)
- (void)(I2C1_NAME->SR1);
- (void)(I2C1_NAME->SR2); // 清除EV6事件
- //--发送要写入的目标寄存器
- if (is16BitRegAdder)
- {
- I2C_SendData(I2C1_NAME, regAdder >> 8); // 发送高8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ;
- if (tmp == 0)
- return -4; // i2c high regAdder failed
- }
- I2C_SendData(I2C1_NAME, regAdder % 256); // 发送低8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ;
- if (tmp == 0)
- return -5; // i2c send low regAdder failed
- /*第二步:开始读取*/
- //--再次生成起始位
- I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
- ;
- if (tmp == 0)
- return -6; // i2c reSend start fail
- //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
- I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址,非十位地址。设置接收时会默认地址最后一位取反即为1
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
- ; // EV6事件
- if (tmp == 0)
- return -7; // i2c reSend address failed
- //--准备接收数据
- I2C_AcknowledgeConfig(I2C1_NAME, DISABLE); // 因为只接收一个字节数据,所以不需要响应
- I2C_GenerateSTOP(I2C1_NAME, ENABLE); // 将在接收后产生停止信号-在此书写原因在手册
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_RECEIVED)))
- ; // EV7事件
- if (tmp == 0)
- return -8; // i2c no received
- //--接收数据
- *num = I2C_ReceiveData(I2C1_NAME); // 保存数据
- //--恢复响应
- I2C_AcknowledgeConfig(I2C1_NAME, ENABLE);
- return 1;
- }
- /**
- * @brief: 利用硬件i2c1读取目标寄存器开始以后的两个数据
- * @args:两个参数:寄存器地址,寄存器地址是否是16位
- * @arg1:目标设备地址(写地址就好了)
- * @arg2:目标8位寄存器地址
- * @arg3:寄存器地址是否是16位的
- * @arg4:读取结果指针
- * @arg5:是否允许跨页
- * @return:
- * >0 成功(成功读取的字节数)
- * <=0 失败
- * -1 i2c busy
- * -2 i2c send start fail
- * -3 i2c send address failed
- * -4 i2c send high regAdder failed
- * -5 i2c send low regAdder failed
- * -6 i2c reSend start fail
- * -7 i2c reSend address failed
- * -8 i2c no received
- */
- int32_t dev_at24cxx_read_two_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, bool isAllowOverPage)
- {
- uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
- uint32_t tmp = timeLimit;
- #if I2C1_DEVICE_IS_EEPROM
- // 跨页问题
- uint16_t pageRemain = 0;
- uint16_t newAdder = 0;
- if (getI2C1DeviceCurrentPageRemain(startRegAdder, &pageRemain) < 0)
- {
- return 0;
- }
- if (pageRemain < 2)
- {
- // 需要跨页
- if (dev_at24cxx_read_one_byte(devAdder, startRegAdder, true, &buf[0]) < 0) // 读取第一个数据
- {
- return 0;
- }
- if (!isAllowOverPage)
- {
- // 不允许,直接退出,返回已经读取的一个数量
- return 1; // 只存在一个数据
- }
- if (getI2C1DeviceNewPage(startRegAdder, &newAdder) < 0) // 移动到下一页
- {
- return 1; // 只存在一个数据
- }
- if (dev_at24cxx_read_one_byte(devAdder, newAdder, true, &buf[1]) < 0) // 读取第二个数据
- {
- return 0; // 只存在一个数据
- }
- return 2;
- }
- #endif
- if (buf == NULL)
- {
- return 0;
- }
- /*第一步:先将读指针移到指定的地址寄存器上*/
- //--判断当前i2c是否忙
- while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
- ;
- if (tmp == 0)
- return -1; // i2c busy
- //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
- I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
- ; // EV5事件
- if (tmp == 0)
- return -2; // i2c send start fail
- //--发送7位设备地址
- I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
- ;
- if (tmp == 0)
- return -3; // i2c send address failed
- // 清零事件EV6 ADDR位(先读SR1再读SR2)
- (void)(I2C1_NAME->SR1);
- (void)(I2C1_NAME->SR2); // 清除EV6事件
- //--发送要写入的目标寄存器
- if (is16BitRegAdder)
- {
- I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ;
- if (tmp == 0)
- return -4; // i2c high regAdder failed
- }
- I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ;
- if (tmp == 0)
- return -5; // i2c send low regAdder failed
- /*第二步:开始读取*/
- //--再次生成起始位
- I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
- ;
- if (tmp == 0)
- return -6; // i2c reSend start fail
- //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
- I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址,非十位地址。设置接收时会默认地址最后一位取反即为1
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
- ; // EV6事件
- if (tmp == 0)
- return -7; // i2c reSend address failed
- //--准备接收数据
- I2C_NACKPositionConfig(I2C1_NAME, I2C_NACKPosition_Next); // POS位置位,在接收的下一个字节产生NACK
- tmp = timeLimit;
- while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
- ; // 等待BTF置位
- if (tmp == 0)
- return -8; // i2c no received
- //--发送结束信号
- I2C_GenerateSTOP(I2C1_NAME, ENABLE);
- //--接收两个字节数据.读取第一个数据后第二个数据将会从移位寄存器转到DR中
- buf[0] = (uint8_t)I2C_ReceiveData(I2C1_NAME); // 保存第一个字节
- tmp = timeLimit; // 给移位寄存器转到DR中时间,相当于nop
- buf[1] = (uint8_t)I2C_ReceiveData(I2C1_NAME); // 保存第二个字节
- return 2; // 成功读取两个字节
- }
- /**
- * @brief: 利用硬件i2c1读取从目标寄存器开始的bufsize个数据
- * @args:四个参数:寄存器起始地址,寄存器地址是否是16位,保存数据的buf,保存数据数量
- * @arg1:目标设备地址(写地址就好了)
- * @arg2:目标8位寄存器地址
- * @arg3:寄存器地址是否是16位的
- * @arg4:读取结果指针
- * @arg5:要读取的大小,调用此函数最小读取为3个字节
- * @return:
- * >0 成功 表示已经接收的字节数量
- * <0 失败
- * -1 i2c busy
- * -2 i2c send start fail
- * -3 i2c send address failed
- * -4 i2c send high regAdder failed
- * -5 i2c send low regAdder failed
- * -6 i2c reSend start fail
- * -7 i2c reSend address failed
- */
- // static
- int32_t dev_at24cxx_read_more_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, uint8_t bufSize)
- {
- uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
- uint32_t tmp = timeLimit;
- uint32_t index = 0;
- if (bufSize < 3)
- {
- return 0;
- }
- /*第一步:先将读指针移到指定的地址寄存器上*/
- //--判断当前i2c是否忙
- while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
- ;
- if (tmp == 0)
- return -1; // i2c busy
- //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
- I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
- ; // EV5事件
- if (tmp == 0)
- return -2; // i2c send start fail
- //--发送7位设备地址
- I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
- ;
- if (tmp == 0)
- return -3; // i2c send address failed
- // 清零事件EV6 ADDR位(先读SR1再读SR2)
- (void)(I2C1_NAME->SR1);
- (void)(I2C1_NAME->SR2); // 清除EV6事件
- //--发送要写入的目标寄存器
- if (is16BitRegAdder)
- {
- I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ;
- if (tmp == 0)
- return -4; // i2c high regAdder failed
- }
- I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ;
- if (tmp == 0)
- return -5; // i2c send low regAdder failed
- /*第二步:开始读取*/
- //--再次生成起始位
- I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
- ;
- if (tmp == 0)
- return -6; // i2c reSend start fail
- //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
- I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址,非十位地址。设置接收时会默认地址最后一位取反即为1
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
- ; // EV6事件
- if (tmp == 0)
- return -7; // i2c reSend address failed
- //--开始接收数据
- while (index < bufSize)
- {
- if (index == bufSize - 3)
- {
- // 已经是倒数第三个了
- tmp = timeLimit;
- while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
- ; // step1等待BTF置位(读DR复位)
- if (tmp == 0)
- return index; // 返回已经接收的字节数
- I2C_AcknowledgeConfig(I2C1_NAME, DISABLE); // step2复位ACK
- buf[index] = I2C_ReceiveData(I2C1_NAME); // step3读取n-2数据
- index++;
- tmp = timeLimit;
- while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
- ; // step4再次等待BTF置位(读DR复位)
- if (tmp == 0)
- return index; // 返回已经接收的字节数
- I2C_GenerateSTOP(I2C1_NAME, ENABLE); // step5生成停止位
- buf[index++] = I2C_ReceiveData(I2C1_NAME); // step6读取第n-1数据
- tmp = timeLimit; // 此操作就是为了等待移位寄存器中的数据移入DR,相当于一个nop
- buf[index++] = I2C_ReceiveData(I2C1_NAME); // step7读取第n数据
- // 接收完成
- I2C_AcknowledgeConfig(I2C1_NAME, ENABLE); // 恢复响应
- return index; // 返回已经接收数量
- }
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_RECEIVED)))
- ; // EV7事件
- if (tmp == 0)
- return index; // 返回已经接收的字节数
- buf[index] = I2C_ReceiveData(I2C1_NAME);
- index++; // 接收下一字节
- }
- return 0;
- }
- /**
- * @brief: 利用硬件i2c1向目标寄存器写入一个数据
- * @args:三个参数:寄存器地址,寄存器地址是否是16位,需要写入的数据
- * @arg1:目标设备地址(写地址就好了)
- * @arg2:目标寄存器地址
- * @arg3:寄存器地址是否是16位的
- * @arg4:一个字节数据
- * @return:
- * >0 成功
- * <0 失败
- * -1 i2c busy
- * -2 i2c send start fail
- * -3 i2c send address failed
- * -4 i2c high regAdder failed
- * -5 i2c send low regAdder failed
- * -6 i2c send data failed
- */
- int32_t dev_at24cxx_write_one_byte(uint8_t devAdder, uint16_t regAdder, bool is16BitRegAdder, uint8_t num)
- {
- uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
- uint32_t tmp = timeLimit;
- //--判断当前i2c是否忙
- while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
- ;
- if (tmp == 0)
- return -1; // i2c busy
- //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
- I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
- ; // EV5事件
- if (tmp == 0)
- return -2; // i2c send start fail
- //--发送7位设备地址.调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
- I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
- ; // EV6事件
- if (tmp == 0)
- return -3; // i2c send address failed
- //--发送要写入的目标寄存器
- if (is16BitRegAdder)
- {
- I2C_SendData(I2C1_NAME, regAdder >> 8); // 发送高8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ; // EV8事件-写DR清除
- if (tmp == 0)
- return -4; // i2c high regAdder failed
- }
- I2C_SendData(I2C1_NAME, regAdder % 256); // 发送低8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ; // EV8事件-写DR清除
- if (tmp == 0)
- return -5; // i2c send low regAdder failed
- //--发送数据
- I2C_SendData(I2C1_NAME, num);
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTED)))
- ; // EV8_2事件
- if (tmp == 0)
- return -6; // i2c send data failed
- //--发送结束信号
- I2C_GenerateSTOP(I2C1_NAME, ENABLE);
- return 1;
- }
- /***@brief : 利用硬件i2c1向目标起始寄存器连续写入多个数据
- *@args : 5个参数:开始寄存器地址,寄存器地址是否是16位,需要写入的数据数组,数据数组大小,是否允许跨页(如果不是eerpom不用管) *
- @arg1 : 目标设备地址(写地址就好了) * @arg2 : 目标寄存器地址 *@arg3 : 寄存器地址是否是16位的 *@arg4 : 一个要写入数据的数组 *@arg5 : 写入数据长度 *@ return : * >
- 0 成功发送的字节数
- * <= 0 失败
- * 0 buf大小为0
- * -1 i2c busy
- * -2 i2c send start fail
- * -3 i2c send address failed
- * -4 i2c high regAdder failed
- * -5 i2c send low regAdder failed */
- // static
- int32_t dev_at24cxx_write_more_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, uint8_t bufSize)
- {
- uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
- uint32_t tmp = timeLimit;
- uint32_t index = 0;
- if (bufSize <= 0)
- {
- return 0;
- }
- //--判断当前i2c是否忙
- while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
- ;
- if (tmp == 0)
- return -1; // i2c busy
- //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
- I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
- ; // EV5事件
- if (tmp == 0)
- return -2; // i2c send start fail
- //--发送7位设备地址.调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
- I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
- ; // EV6事件
- if (tmp == 0)
- return -3; // i2c send address failed
- //--发送要写入的目标寄存器
- if (is16BitRegAdder)
- {
- I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ; // EV8事件-写DR清除
- if (tmp == 0)
- return -4; // i2c high regAdder failed
- }
- I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ; // EV8事件-写DR清除
- if (tmp == 0)
- return -5; // i2c send low regAdder failed
- //--发送数据
- while (index < bufSize)
- {
- if (index == (bufSize - 1))
- {
- // 已经是最后一个字节了,在写入DR后发送停止位了
- I2C_SendData(I2C1_NAME, buf[index]);
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTED)))
- ; // EV8_2事件
- I2C_GenerateSTOP(I2C1_NAME, ENABLE);
- if (tmp == 0)
- return index; // 返回已发送的字节数量
- }
- else
- {
- I2C_SendData(I2C1_NAME, buf[index]);
- tmp = timeLimit;
- while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
- ; // EV8事件
- if (tmp == 0)
- return index; // 返回已发送的字节数量
- }
- index++;
- }
- return index;
- }
- int32_t dev_at24cxx_read_bytes(uint8_t addr, uint8_t *buf, uint8_t size)
- {
- if (1 == size)
- {
- return dev_at24cxx_read_one_byte(I2C1_ADDRESS, addr, 1, buf);
- }
- else if (2 == size)
- {
- return dev_at24cxx_read_two_bytes(I2C1_ADDRESS, addr, 1, buf, 1);
- }
- else
- {
- return dev_at24cxx_read_more_bytes(I2C1_ADDRESS, addr, 1, buf, size);
- }
- }
- int32_t dev_at24cxx_write_bytes(uint8_t addr, uint8_t *buf, uint8_t size)
- {
- if (1 == size)
- {
- return dev_at24cxx_write_one_byte(I2C1_ADDRESS, addr, 1, *buf);
- }
- else
- {
- return dev_at24cxx_write_more_bytes(I2C1_ADDRESS, addr, 1, buf, size);
- }
- }
|