1. 官方介绍
- 既可以做从机也可以做主机
- 支持标准的100K和400K的速率
void i2c_master_init(unsigned char SlaveID, unsigned char DivClock)
{
reg_i2c_speed = DivClock; //i2c clock = system_clock/(4*DivClock)
reg_i2c_id = SlaveID; //slave address
reg_i2c_mode |= FLD_I2C_MASTER_EN; //enable master mode
reg_clk_en0 |= FLD_CLK0_I2C_EN; //enable i2c clock
reg_spi_sp &= ~FLD_SPI_ENABLE; //force PADs act as I2C; i2c and spi share the hardware of IC
}
2.IIC初始化
/*
* mat_iic.c
*
* Created on: 2022-8-16
* Author:
*/
#include "mat_iic.h"
#include "i2c.h"
#define SLAVE_ADDR 0x82
#define DIV_CLOCK 10
void iic_init(void)
{
i2c_gpio_set(I2C_GPIO_GROUP_C0C1);
i2c_master_init(SLAVE_ADDR, DIV_CLOCK);//system clock = 16MHz, 16/(4*10) = 0.4M = 400K
}
void iic_test(void)
{
unsigned char read_point_arr[64] = {0};
i2c_read_series(0x82, 1, read_point_arr, 64);
}
我使用的IIC读数据并不是标准的IIC通信,我的不需要发送设备地址,直接发送读取设备寄存器,设备那边就会反回数据,以下为我修改的读数据函数:
void i2c_read_series(unsigned int Addr, unsigned int AddrLen, unsigned char * dataBuf, int dataLen)
{
reg_i2c_id &= (~FLD_I2C_WRITE_READ_BIT); //SlaveID & 0xfe,.i.e write data. R:High W:Low
if(AddrLen == 0){
#if (I2C_SLAVE_DEVICE_NO_START_EN)
reg_i2c_ctrl = FLD_I2C_CMD_ID ;
#else
//lanuch start /id start
reg_i2c_ctrl = (FLD_I2C_CMD_START );// when addr=0,other (not telink) iic device no need start signal
#endif
}
else if (AddrLen == 1) {
#if 0
reg_i2c_adr = (unsigned char)Addr; //address
//lanuch start /id/04 start
//reg_i2c_ctrl = (FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR | FLD_I2C_CMD_START);
reg_i2c_ctrl = (FLD_I2C_CMD_ADDR | FLD_I2C_CMD_START);
#endif
reg_i2c_map_hadr = (unsigned char)Addr;
//reg_i2c_ctrl = ( FLD_I2C_CMD_START);
}
else if (AddrLen == 2) {
reg_i2c_adr = (unsigned char)(Addr>>8); //address high
reg_i2c_do = (unsigned char)Addr; //address low
//lanuch start /id/04/05 start
reg_i2c_ctrl = (FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO | FLD_I2C_CMD_START);
}
else if (AddrLen == 3) {
reg_i2c_adr = (unsigned char)(Addr>>16); //address high
reg_i2c_do = (unsigned char)(Addr>>8); //address middle
reg_i2c_di = (unsigned char)(Addr); //address low
//lanuch start /id/04/05/06 start
reg_i2c_ctrl = (FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO | FLD_I2C_CMD_DI | FLD_I2C_CMD_START);
}
while(reg_i2c_status & FLD_I2C_CMD_BUSY );
//start + id(Read)
reg_i2c_id |= FLD_I2C_WRITE_READ_BIT; //SlaveID & 0xfe,.i.e write data. Read:High Write:Low
reg_i2c_ctrl = (FLD_I2C_CMD_ID | FLD_I2C_CMD_START);
while(reg_i2c_status & FLD_I2C_CMD_BUSY );
//read data
unsigned int bufIndex = 0;
dataLen--; //the length of reading data must larger than 0
//if not the last byte master read slave, master wACK to slave
while(dataLen){ //
reg_i2c_ctrl = (FLD_I2C_CMD_DI | FLD_I2C_CMD_READ_ID);
while(reg_i2c_status & FLD_I2C_CMD_BUSY );
dataBuf[bufIndex] = reg_i2c_di;
bufIndex++;
dataLen--;
}
//when the last byte, master will ACK to slave
reg_i2c_ctrl = (FLD_I2C_CMD_DI | FLD_I2C_CMD_READ_ID | FLD_I2C_CMD_ACK);
while(reg_i2c_status & FLD_I2C_CMD_BUSY );
dataBuf[bufIndex] = reg_i2c_di;
//termiante
reg_i2c_ctrl = FLD_I2C_CMD_STOP; //launch stop cycle
while(reg_i2c_status & FLD_I2C_CMD_BUSY );
}
3.关于读取数据的问题
在裸机的情况下,如果读取数据,数据是可以在很快的速度下进行读的,但是当开启蓝牙后(蓝牙并没有连接),读数据的时候就会出现丢包,并且这个丢包率很严重。后来在网上查了一下,发现也有人遇到相同问题:裸机运行OK,在蓝牙demo中运行就会出现丢数据。经那位老哥说是开启了休眠,把休眠关掉就可以了。
在app_config.h文件下:
#define BLE_APP_PM_ENABLE 0//1
#define PM_DEEPSLEEP_RETENTION_ENABLE 0//1
参考链接:泰凌微 Telink TLSR825X Uart 串口无法接收数据 关闭休眠和深度休眠解决 问题_greatriver007的博客-CSDN博客