ESP8266单片机使用I/O引脚模拟软件IIC,与合泰触摸芯片—BS8112A进行通信
这篇文章来讲一下如何使用ESP8266单片机与触摸芯片—BS8112A(可测12个按键)进行IIC通信测量9个按键,因为自己之前没有接触过类似的触摸芯片,所以就选择先挑选网上教程和售卖比较多的芯片和模块,但是我发现使用ESP系列单片机来控制芯片的教程比较少。于是,写下这篇文章,希望对大家有帮助。
1、起因:最近在做一个项目,需要测量9个触摸按键,于是上网开始挑选合适的触摸芯片和模块。
(1)TTP2x系列芯片——TTP229-BSF(可测量16个按键)
这款芯片比较热门(自身感觉!),网上它的教程(但有关ESP8266的程序代码都是一样的)相对来说比较多,并且TB卖的触摸按键模块大部分都是使用它。

图1 TTP229-BSF芯片
我在大致读了一下芯片手册后,便购买了它,同时还画了PCB准备验证,结果因为自己只是粗略地读了英文版的芯片手册,导致对该芯片的了解不准确,导致画的板子出错了,索性直接买一个模块来测试一下。

图2 TTP229触摸按键模块
模块到来后便跟着网上教程直接测试触摸效果,ESP8266烧录好代码后测试一下果然有反应了,但是不知道为啥当按下按键“1”、“2”、“3”时,串口打印出来的却是其它按键的返回值,跟教程里展示的不一样。
于是重新开始在网上地毯式搜索相关芯片的代码编写,发现该芯片是有中文版的手册,重新看了一遍后,发现它有多种模式来控制,感觉对我来说比较复杂,而且TTP229-BSF是用2线串行接口通信的,有些博主说可以用SPI通信,但是我只了解过IIC,SPI没了解过。
所以我想着要不直接找IIC通信的触摸芯片吧,于是放弃了这款芯片。
(2)BS81xA系列芯片——BS8112A-3(可测量12个按键)
在某个视频评论区里看到说合泰的触摸芯片比较容易,查了一下芯片手册发现是IIC通信的,并且推荐的外围电路十分简单,只有一个滤波电容!于是选择了它,再认真看完手册后,便画了PCB准备再次测试。
芯片手册网址:Holtek-simBS81xA-xv170.pdf

图3 BS8112A-3芯片

图4 BS8112A外围电路图
2、过程:
找了一些网上的教程,虽然没有搜到用ESP8266实现触摸的代码,但是IIC的代码大致都是相同的,便开始学习。前期主要是复习一下IIC的通信原理,再学习ESP8266的wire.h库(用来IIC通信调用的),并看看别人写的代码。想着结合芯片手册给的IIC传输示意图来调用wire.h来写,但花了一天都没成功,暂时放弃这种写法了。

图5 BS8112A的从机七位地址、八位地址

图6 BS8112A读取按键状态寄存器
于是想着使用I/O口来模拟IIC,去B站看了一下江科大的软件IIC的视频,尝试先用STM32来实现,花了大概几个小时成功实现了触摸按键,将所写的代码移植到ESP8266上,改一改代码格式(C语言变成C++),过程十分顺利,当然结果也顺利实现了。

图7 STM32实现触摸按键


图8 ESP8266实现触摸按键
软件IIC代码如下:
//模拟SCL
void MyI2C_W_SCL(uint8_t BitValue)
{
digitalWrite(SCL_PIN, (BitValue? 1 : 0));
delayMicroseconds(5);
}
//模拟SDA(主机向从机写数据)
void MyI2C_W_SDA(uint8_t BitValue)
{
digitalWrite(SDA_PIN, (BitValue? 1 : 0));
delayMicroseconds(5);
}
//模拟SDA(主机读取从机发来的数据)
uint8_t MyI2C_R_SDA(void)
{
uint8_t BitValue;
BitValue = digitalRead(SDA_PIN);
delayMicroseconds(5);
return BitValue;
}
//起始
void MyI2C_Start(void)
{
//MyI2C_W_SCL(0);
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
MyI2C_W_SDA(0);
MyI2C_W_SCL(0);
}
//结束
void MyI2C_Stop(void)
{
MyI2C_W_SDA(0);
MyI2C_W_SCL(1);
MyI2C_W_SDA(1);
}
//主机发送数据
void MyI2C_SendByte(uint8_t Byte)
{
uint8_t i;
for (i = 0; i < 8; i ++)
{
MyI2C_W_SDA(Byte & (0x80 >> i));
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
}
//主机接收数据
uint8_t MyI2C_ReceiveByte(void)
{
uint8_t i, Byte = 0x00;
MyI2C_W_SDA(1);
for (i = 0; i < 8; i ++)
{
MyI2C_W_SCL(1);
if (MyI2C_R_SDA() == 1){Byte |= (0x80 >> i);}
MyI2C_W_SCL(0);
}
return Byte;
}
//主机发送应答
void MyI2C_SendAck(uint8_t AckBit)
{
MyI2C_W_SDA(AckBit);
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
//主机接收从机的应答
uint8_t MyI2C_ReceiveAck(void)
{
uint8_t AckBit;
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
AckBit = MyI2C_R_SDA();
MyI2C_W_SCL(0);
return AckBit;
}
/*
函 数 名:BSI2C_SendByte
函数功能:IIC发送字节数据
返 回 值:ack 接受到的响应
形 参:data 待发送的数据
备 注:
*/
uint8_t BSI2C_SendByte(uint8_t data)
{
MyI2C_SendByte(data);
uint8_t ack = MyI2C_ReceiveAck();
return ack;
}
/*
函 数 名:BSI2C_RevByte
函数功能:IIC接收字节数据
返 回 值:接收到的数据
形 参:ack 待发送的响应
备 注:
*/
uint8_t BSI2C_RevByte(uint8_t ack)
{
uint8_t data;
data = MyI2C_ReceiveByte();
MyI2C_SendAck(ack);
return data;
}
// BS8112A检测函数
uint8_t BS8112_Read_Key(void)
{
MyI2C_Start();
if(BSI2C_SendByte(0xA0))
{
return 1;
}
if(BSI2C_SendByte(0x08))
{
return 2;
}
MyI2C_Start();
if(BSI2C_SendByte(0xA1))
{
return 3;
}
Touch_Key = BSI2C_RevByte(0);
Touch_Key = BSI2C_RevByte(1)<<8|Touch_Key;
MyI2C_Stop();
switch(Touch_Key)
{
case 0x0001:return '1';
case 0x0008:return '2';
case 0x0040:return '3';
case 0x0002:return '4';
case 0x0010:return '5';
case 0x0080:return '6';
case 0x0004:return '7';
case 0x0020:return '8';
case 0x0100:return '9';
}
return 0;
}
ESP8266完整代码如下:
#include <Arduino.h>
#include <stdint.h>
#include <Ticker.h>
#define SDA_PIN 4 // SDA引脚,默认gpio4(D2)
#define SCL_PIN 5 // SCL引脚,默认gpio5(D1)
uint16_t Actual_Key,Touch_Key = 0;
Ticker key_tick; //定时器
void KEY_GET(void)
{
Actual_Key = BS8112_Read_Key(); //定时器执行函数
}
void setup()
{
Serial.begin(115200); //初始化串口
pinMode(SDA_PIN, OUTPUT_OPEN_DRAIN); //初始化SCL、SDA引脚
pinMode(SCL_PIN, OUTPUT_OPEN_DRAIN);
key_tick.attach_ms(10,KEY_GET); //配置好定时器
delay(100);
}
void loop()
{
if (Actual_Key != 0)
{
Serial.print("Read key: "); //串口打印按键值
Serial.println(Actual_Key);
}
delay(50);
}
//模拟SCL
void MyI2C_W_SCL(uint8_t BitValue)
{
digitalWrite(SCL_PIN, (BitValue? 1 : 0));
delayMicroseconds(5);
}
//模拟SDA(主机向从机写数据)
void MyI2C_W_SDA(uint8_t BitValue)
{
digitalWrite(SDA_PIN, (BitValue? 1 : 0));
delayMicroseconds(5);
}
//模拟SDA(主机读取从机发来的数据)
uint8_t MyI2C_R_SDA(void)
{
uint8_t BitValue;
BitValue = digitalRead(SDA_PIN);
delayMicroseconds(5);
return BitValue;
}
//起始
void MyI2C_Start(void)
{
//MyI2C_W_SCL(0);
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
MyI2C_W_SDA(0);
MyI2C_W_SCL(0);
}
//结束
void MyI2C_Stop(void)
{
MyI2C_W_SDA(0);
MyI2C_W_SCL(1);
MyI2C_W_SDA(1);
}
//主机发送数据
void MyI2C_SendByte(uint8_t Byte)
{
uint8_t i;
for (i = 0; i < 8; i ++)
{
MyI2C_W_SDA(Byte & (0x80 >> i));
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
}
//主机接收数据
uint8_t MyI2C_ReceiveByte(void)
{
uint8_t i, Byte = 0x00;
MyI2C_W_SDA(1);
for (i = 0; i < 8; i ++)
{
MyI2C_W_SCL(1);
if (MyI2C_R_SDA() == 1){Byte |= (0x80 >> i);}
MyI2C_W_SCL(0);
}
return Byte;
}
//主机发送应答
void MyI2C_SendAck(uint8_t AckBit)
{
MyI2C_W_SDA(AckBit);
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
//主机接收从机的应答
uint8_t MyI2C_ReceiveAck(void)
{
uint8_t AckBit;
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
AckBit = MyI2C_R_SDA();
MyI2C_W_SCL(0);
return AckBit;
}
/*
函 数 名:BSI2C_SendByte
函数功能:IIC发送字节数据
返 回 值:ack 接受到的响应
形 参:data 待发送的数据
备 注:
*/
uint8_t BSI2C_SendByte(uint8_t data)
{
MyI2C_SendByte(data);
uint8_t ack = MyI2C_ReceiveAck();
return ack;
}
/*
函 数 名:BSI2C_RevByte
函数功能:IIC接收字节数据
返 回 值:接收到的数据
形 参:ack 待发送的响应
备 注:
*/
uint8_t BSI2C_RevByte(uint8_t ack)
{
uint8_t data;
data = MyI2C_ReceiveByte();
MyI2C_SendAck(ack);
return data;
}
// BS8112A检测函数
uint8_t BS8112_Read_Key(void)
{
MyI2C_Start();
if(BSI2C_SendByte(0xA0))
{
return 1;
}
if(BSI2C_SendByte(0x08))
{
return 2;
}
MyI2C_Start();
if(BSI2C_SendByte(0xA1))
{
return 3;
}
Touch_Key = BSI2C_RevByte(0);
Touch_Key = BSI2C_RevByte(1)<<8|Touch_Key;
MyI2C_Stop();
switch(Touch_Key)
{
case 0x0001:return '1';
case 0x0008:return '2';
case 0x0040:return '3';
case 0x0002:return '4';
case 0x0010:return '5';
case 0x0080:return '6';
case 0x0004:return '7';
case 0x0020:return '8';
case 0x0100:return '9';
}
return 0;
}
3、总结:
记录了自己使用ESP8266单片机实现了对BS8112A触摸按键芯片的IIC通信,以上内容希望对大家也有帮助!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)