SYD8821 IIC模块使用说明

  • Post author:
  • Post category:其他




SYD8821是具有全球领先低功耗(RX 2.4mA @-94.5dBm灵敏度,TX 4.3mA @0dBm输出功率)的蓝牙低功耗SOC芯片,在极低电流下实现了优异的射频性能,搭配176kB SRAM,512kB flash,非常适合中高阶可穿戴、智能家居、物联网等低功耗应用







具体可咨询:http://www.sydtek.com/


SYD8821 IIC模块使用说明

IIC测试必须要一个从机设备,单单SYD8821芯片是不可能实现的了,这里的从机设备采用KX022加速度传感器,SYD8821和KX022传感器的电路连接图如下:

一共有六个管脚和GSENSOR连接,分别是;

两个中断管脚:GPIO19/INT1_G ,GPIO18/INT2_G

四个SPI的管脚:GPIO21/G-SDA ,GPIO20/G-SCL,GPIO15/SDO,GPIO17/CS

这里是用IIC和该传感器连接,所以GPIO15固定拉低,GPIO17固定拉高

打开工程“\SYD8821\SYD8821_SDK\Source Code\SYD8821\iic”可看到IIC的初始化配置如下:

int main()

{

uint8_t iic_buff[32]={0};

int16_t x,y,z;

uint16_t i=0;

float vat=0.0;

__disable_irq();

//GPO

pad_mux_write(LED4, 0);

pad_mux_write(LED5, 0);

pad_mux_write(LED6, 0);

pad_mux_write(LED7, 0);

gpo_config(LED4,1);

gpo_config(LED5,1);

gpo_config(LED6,1);

gpo_config(LED7,1);

//GPI

pad_mux_write(KEY1, 0);

pad_mux_write(KEY2, 0);

pad_mux_write(KEY3, 0);

gpi_config(KEY1, PULL_UP);

gpi_config(KEY2, PULL_UP);

gpi_config(KEY3, PULL_UP);

//uart 0

pad_mux_write(12, 7);

pad_mux_write(13, 7);

dbg_init();

dbg_printf(“SYD8821 IIC DEMO\r\n”);

//kx022 gsensor SDA AND CS LOW

pad_mux_write(15, 0);

gpo_config(15,0);                         //固定拉低

pad_mux_write(17, 0);

gpo_config(17,1);                         //固定拉高

// IIC

pad_mux_write(20, 6); //i2c 1 scl       //管脚选择为IIC功能

pad_mux_write(21, 6); //i2c 1 sda     // 管脚选择为IIC功能

/* Masters Init M0*/

//set i2c clk rate param 0, (48/8)*50K=300k

i2c_master_set_speed(1, 0);     //设置速度为480K

i2c_master_enable(1, true);       //使能IIC模块

i2c_master_enable_int(1, true);    //使能IIC中断 不过这里没有使用中断的功能

i2c_master_set_address_mode(1, I2C_MASTER_1BYTE_ADDRESS);     //设置地址模式,这里的传感器寄存器地址为1个字节

NVIC_EnableIRQ(I2CM0_IRQn);    //使能中断

if(kx022_init()) dbg_printf(“kx022 init succeed\r\n”);     //进行传感器的初始化

else dbg_printf(“kx022 init faild\r\n”);

__enable_irq();

while(1)

{


gpo_toggle(LED4);

/*

计算公式:加速度 = 读到的原始值 * 8000mG / 65536 / 1000

其中的8000mG是这样的:本例程的测量量程是 +-4G  也就是正负4G的范围,这里是在Resolution/Range寄存器里设置的

那么所能读到的最大数据是65536,也就是说每个数据的刻度是 8000/65536 mg

*/

gensor_read_xyz(&x, &y, &z);    //读取传感器的值

vat=(float)x*8000/65536/1000;

dbg_printf(“x : %02x vat: %4.3f i:%d\r\n”,x,vat,i);

vat=(float)y*8000/65536/1000;

dbg_printf(“y : %02x vat: %4.3f i:%d\r\n”,y,vat,i);

vat=(float)z*8000/65536/1000;

dbg_printf(“z : %02x vat: %4.3f i:%d\r\n”,z,vat,i);

delay_ms(500);

i++;

delay_ms(1000);

}

}

下面看看kx022_init源码:

uint8_t  kx022_init(void)

{


uint8_t i,st;

kx022_write_reg(0x00, 0x24);

for(i=0; i<(sizeof(kx022_init_data)); i+=2)

{


kx022_write_reg(kx022_init_data[i], kx022_init_data[i+1]);

}

kx022_read_reg(KX022_INT_REL, &st);

kx022_read_reg(KX022_WHO_AM_I_REG, &st);

if(st == 0x14) return 1;

#ifdef CONFIG_UART_ENABLE

dbg_printf(“WHO I ME: %4X \r\n”,st);

#endif

return 0;

}

其中主要调用kx022_read_reg和kx022_write_reg对传感器的寄存器进行初始化,这两个函数的源码如下:

/*

kx022写寄存器函数

参数: uint8_t addr  寄存器地址

uint8_t value 寄存器数据

注意ID地址不作为传入参数 已经在全部变量定义好了

*/

void kx022_write_reg(uint8_t addr, uint8_t value)

{

__align(4) uint8_t val=0;

val=value;

i2c_write(1,I2C_ID_KX022,addr,&val,0x01);

}

/*

kx022读寄存器函数

参数: uint8_t addr  寄存器地址

uint8_t value 读到的内容

注意ID地址不作为传入参数 已经在全部变量定义好了

*/

void kx022_read_reg(uint8_t addr, uint8_t *p_value)

{


__align(4) uint8_t val=0;

i2c_read(1,I2C_ID_KX022,addr,&val,0x01);

*p_value=val;

}

主要调用i2c_write和i2c_read读进行实际的操作,这里都是操作一个字节!

当然还有操作多个字节的,比如读取加速度值得gensor_read_xyz函数:

/*

kx022获取加速度传感器三个轴的数据函数

传入参数:uint16_t *p_x X轴数据存储指针

uint16_t *p_y y轴数据存储指针

uint16_t *p_z z轴数据存储指针

*/

void gensor_read_xyz(int16_t *p_x, int16_t *p_y, int16_t *p_z)

{


//        uint8_t st;

//        uint8_t val[2];

//        int16_t x,y,z;

//            kx022_read_reg(KX022_X_OUTL_REG, &val[0]);

//            kx022_read_reg(KX022_X_OUTL_REG+1, &val[1]);

//            x = (val[0]) | ((int16_t)val[1] << 8);

//            kx022_read_reg(KX022_Y_OUTL_REG, &val[0]);

//            kx022_read_reg(KX022_Y_OUTL_REG+1, &val[1]);

//            y = (val[0]) | ((int16_t)val[1] << 8);

//            kx022_read_reg(KX022_Z_OUTL_REG, &val[0]);

//            kx022_read_reg(KX022_Z_OUTL_REG+1, &val[1]);

//            z = (val[0]) | ((int16_t)val[1] << 8);

//

//            *p_x=x;

//            *p_y=y;

//            *p_z=z;

uint8_t st;

__align(4) uint8_t val[6];

kx022_read_nreg(KX022_X_OUTL_REG, val,6);

*p_x = (val[0]) | ((int16_t)val[1] << 8);

*p_y = (val[2]) | ((int16_t)val[3] << 8);

*p_z = (val[4]) | ((int16_t)val[5] << 8);

}

这里一次获取了6个寄存器的值,这里IIC只有32个byte,所以最多一次只能够读取32个字节的数据!

IIC测试如果没有挂接从机设备,那么时序如下:

可以看到从机没有应答,时序停止,挂机从机设备后结果如下:

可以看到正确的完整的时序,下面是gensor_read_xyz函数中注释的部分打开的时候的时序图,每次读取一个寄存器的值,知道读完六个寄存器:

下面是上面的gensor_read_xyz函数产生的时序:


这里上传逻辑分析仪数据;https://download.csdn.net/download/chengdong1314/10304560


这里上传本节博客源代码:https://download.csdn.net/download/chengdong1314/10304570



版权声明:本文为chengdong1314原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。