合泰BS8116A

时间: 2023-09-30 admin IT培训

合泰BS8116A

合泰BS8116A

一、硬件说明

引脚图:

接线:

 说明:由于用到了唤醒检测,所以KEY16引脚用作IRQ中断唤醒功能,未使用引脚拉低。

二、IIC配置说明

1、最大波特率:

实际单片机配置最好不要设置波特率100Khz容易出错,50Khz就可以了。

2、从机地址:

 注意:这里需要注意的是,从机地址位不包括读写位,实际使用需要右移一位,从机地址是0x50实际发送读是0xA1,写是0xA0。

3、从机忙碌

 这个判断程序里面还是加一下,不加的话一般也能用,但是容易出问题。

三、读写按键寄存器

 1、中断说明:

 

 检测到IRQ引脚低电平开始读取按键状态,高电平停止读取。

2、工作模式:

 这里需要注意在8秒按键没有按下时,会进入低功耗状态。两种状态下的按键唤醒速度是不同的,体验有明显差异,且无法修改进入休眠时间。

3、读取按键状态

 4、读写配置寄存器

 注意:最后是一个字节的校验和,只是简单的单字节累加从合泰同类型其他手册里找到说明了。

 5、配置寄存器

注意:触发门槛值越低敏感度越高,门槛值数值越高敏感度越低。

 免大家去查表直接复制过来了。

四、代码片段

1、配置寄存器数据结构

#define KEY_ADDR1_8		0x08
#define KEY_ADDR9_12	0x09#define REG_CFG_ADDR	0xB0
#define REG_CFG_CNT		21#pragma pack(1) //单字节对齐typedef union {uint8_t reg[REG_CFG_CNT+1];struct {uint8_t opt1_oms : 1;uint8_t opt1_17_res:7;uint8_t res1;uint8_t res2;uint8_t res3;uint8_t opt2_05_res : 6;uint8_t opt2_6_lsc : 1;uint8_t opt2_7_res : 1;uint8_t k1_th_val : 6;uint8_t k1_th_res : 1;uint8_t k1_th_wu : 1;uint8_t k2_th_val : 6;uint8_t k2_th_res : 1;uint8_t k2_th_wu : 1;uint8_t k3_th_val : 6;uint8_t k3_th_res : 1;uint8_t k3_th_wu : 1;uint8_t k4_th_val : 6;uint8_t k4_th_res : 1;uint8_t k4_th_wu : 1;uint8_t k5_th_val : 6;uint8_t k5_th_res : 1;uint8_t k5_th_wu : 1;uint8_t k6_th_val : 6;uint8_t k6_th_res : 1;uint8_t k6_th_wu : 1;uint8_t k7_th_val : 6;uint8_t k7_th_res : 1;uint8_t k7_th_wu : 1;uint8_t k8_th_val : 6;uint8_t k8_th_res : 1;uint8_t k8_th_wu : 1;uint8_t k9_th_val : 6;uint8_t k9_th_res : 1;uint8_t k9_th_wu : 1;uint8_t k10_th_val : 6;uint8_t k10_th_res : 1;uint8_t k10_th_wu : 1;uint8_t k11_th_val : 6;uint8_t k11_th_res : 1;uint8_t k11_th_wu : 1;uint8_t k12_th_val : 6;uint8_t k12_th_res : 1;uint8_t k12_th_wu : 1;uint8_t k13_th_val : 6;uint8_t k13_th_res : 1;uint8_t k13_th_wu : 1;uint8_t k14_th_val : 6;uint8_t k14_th_res : 1;uint8_t k14_th_wu : 1;uint8_t k15_th_val : 6;uint8_t k15_th_res : 1;uint8_t k15_th_wu : 1;uint8_t k16_th_val : 6;uint8_t k16_th_mod : 1;uint8_t k16_th_wu : 1;uint8_t checksum;}setting;
} key_setting_t;#pragma pack()

 2、初始化配置寄存器

void TK_Module_Cfg(void)
{int i;rt_int32_t ret = 0;key_setting_t write_setting = {{0x00,0x00,0x83,0xf3,0xd8,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x4f,0},},read_setting={0};for(i=0;i<REG_CFG_CNT;i++){write_setting.setting.checksum += write_setting.reg[i];}for(i=0;i<30;i++){TK_WriteReg(&write_setting);rt_thread_mdelay(1);TK_ReadReg(&read_setting);ret = rt_memcmp(&write_setting,&read_setting,REG_CFG_CNT);if(ret==0){break;}}
}

3、寄存器读写

//写寄存器
int TK_I2c_WriteReg(uint8_t *dest,uint16_t count,uint8_t reg)
{uint8_t u8i=0,flag[10]={0},idx=0,u8State;uint32_t u32KeyTimer = rt_tick_get()+200;I2C_ClearFunc(BS8116A_IIC,I2cStart_En);I2C_ClearFunc(BS8116A_IIC,I2cAck_En);I2C_ClearFunc(BS8116A_IIC,I2cStop_En);I2C_SetFunc(BS8116A_IIC,I2cModule_En);I2C_SetFunc(BS8116A_IIC,I2cStart_En);    while(u32KeyTimer > rt_tick_get()){while(0 == I2C_GetIrq(BS8116A_IIC) && u32KeyTimer > rt_tick_get()){;}u8State = I2C_GetState(BS8116A_IIC);switch(u8State){case 0x08:                                    //已发送起始条件,将发送SLA+Rflag[0]++;I2C_ClearFunc(BS8116A_IIC,I2cStart_En);I2C_WriteByte(BS8116A_IIC,(I2C_DEVADDR));//发送SLA+Wbreak;case 0x18:                                    //已发送SLA+W,并接收到ACKflag[1]++;while(!IIC_READ_SDA){}I2C_WriteByte(BS8116A_IIC,reg);              //发送内存地址case 0x20:flag[2]++;I2C_WriteByte(BS8116A_IIC,reg);              //发送内存地址break;case 0x28:										//已发送 I2Cx_DATA 中的数据,已接收 ACKflag[3]++;I2C_WriteByte(BS8116A_IIC,dest[u8i++]);              //发送内存地址if(u8i>count){I2C_SetFunc(BS8116A_IIC,I2cStop_En);            //其他错误状态,重新发送起始条件goto FINISH;}break;default:                                      //其他错误状态,重新发送起始条件flag[9]++;I2C_SetFunc(BS8116A_IIC,I2cStop_En);            //其他错误状态,重新发送起始条件goto FINISH;}I2C_ClearIrq(BS8116A_IIC);                               //清除中断状态标志位idx++;}FINISH:I2C_ClearIrq(BS8116A_IIC);                               //清除中断状态标志位return 0;
}//获取按键码
int TK_I2c_ReadReg(uint8_t *dest,uint16_t count,uint8_t reg)
{en_result_t enRet = Error;uint8_t u8i=0,flag[10]={0},idx=0,u8State,pu8Data[32]={0};uint32_t u32KeyTimer = rt_tick_get()+200;I2C_ClearFunc(BS8116A_IIC,I2cStart_En);I2C_ClearFunc(BS8116A_IIC,I2cAck_En);I2C_ClearFunc(BS8116A_IIC,I2cStop_En);I2C_SetFunc(BS8116A_IIC,I2cModule_En);I2C_SetFunc(BS8116A_IIC,I2cStart_En);    while(u32KeyTimer > rt_tick_get()){while(0 == I2C_GetIrq(BS8116A_IIC) && u32KeyTimer > rt_tick_get()){;}u8State = I2C_GetState(BS8116A_IIC);switch(u8State){case 0x08:                                    //已发送起始条件,将发送SLA+Rflag[0]++;I2C_ClearFunc(BS8116A_IIC,I2cStart_En);I2C_WriteByte(BS8116A_IIC,(I2C_DEVADDR));//发送SLA+Wbreak;case 0x18:                                    //已发送SLA+W,并接收到ACKflag[1]++;while(!IIC_READ_SDA){}I2C_WriteByte(BS8116A_IIC,reg);              //发送内存地址break;case 0x28:                                    //已发送数据,接收到ACKflag[2]++;I2C_SetFunc(BS8116A_IIC,I2cStart_En);break;case 0x10:                                    //已发送重复起始条件flag[3]++;I2C_ClearFunc(BS8116A_IIC,I2cStart_En);I2C_WriteByte(BS8116A_IIC,(I2C_DEVADDR)|0x01);//读命令发送break;case 0x40:                                    //已发送SLA+R,并接收到ACKflag[4]++;if(count>1){I2C_SetFunc(BS8116A_IIC,I2cAck_En);}break;case 0x50:                                    //已接收数据字节,并已返回ACK信号flag[5]++;pu8Data[u8i++] = I2C_ReadByte(BS8116A_IIC);if(u8i>=count){I2C_ClearFunc(BS8116A_IIC,I2cAck_En);        //读数据时,倒数第二个字节ACK关闭}else{I2C_SetFunc(BS8116A_IIC,I2cAck_En);}break;case 0x58:                                    //已接收到最后一个数据,NACK已返回case 0x38:                                    //在发送地址或数据时,仲裁丢失case 0x48:                                    //发送SLA+R后,收到一个NACKdefault:                                      //其他错误状态,重新发送起始条件flag[9]++;I2C_SetFunc(BS8116A_IIC,I2cStop_En);            //其他错误状态,重新发送起始条件goto FINISH;}I2C_ClearIrq(BS8116A_IIC);                               //清除中断状态标志位idx++;}FINISH:I2C_ClearIrq(BS8116A_IIC);                               //清除中断状态标志位rt_memcpy(dest,pu8Data,count);return 0;
}void TK_ReadReg(key_setting_t * setting)
{uint8_t * pset = (uint8_t *)setting,i=0;TK_I2c_ReadReg(pset,REG_CFG_CNT,REG_CFG_ADDR);
}void TK_WriteReg(key_setting_t * setting)
{uint8_t * pset = (uint8_t *)setting,i=0;uint16_t checksum = 0;TK_I2c_WriteReg(pset,REG_CFG_CNT+1,REG_CFG_ADDR);
}uint16_t TK_GetKey(void)
{uint8_t pu8Data[2]={0};uint16_t key_status = 0;TK_I2c_ReadReg(pu8Data,2,KEY_ADDR1_8);key_status = pu8Data[1];key_status = key_status<<8 | pu8Data[0];return key_status;
}

结束。