SC12B驱动
这里只是把数据手册中使用到的重要部分摘取出来,完整版请看SC12B.pdf,这只是这个项目中的一个驱动代码,后续继续更新项目代码。项目实现功能请先看,智能门锁专栏 / 智能门锁功能实现这篇文章,里面介绍了实现的功能,后续将更新详细项目介绍
一. 简介
-
SC12B 是带自校正的容性触摸感应器,可以检测12个感应盘是否被触摸。它可以通过任何非导电介质 (如玻璃和塑料)来感应电容变化。
-
12个完全独立的触摸感应按键
-
保持自动校正,无需外部干预
-
按键输出经过完全消抖处理
-
多接口 – I2C 串行接口 / BCD码输出
-
多种灵敏度调节方式 – 共用灵敏度电容/寄存器配置
-
空闲状态可以节省功耗
-
引脚说明
管脚编号 名称 类型 功能 不使用时 1 GND Pwr 电源地 - 2 CMOD I/O 接电荷收集电容 - 3 CDC I/O 接灵敏度电容 - 4 CIN0 I/O 感应按键0检测输入 悬空 5 CIN1 I/O 感应按键1检测输入 悬空 6 CIN2 I/O 感应按键2检测输入 悬空 7 CIN3 I/O 感应按键3检测输入 悬空 8 CIN4 I/O 感应按键4检测输入 悬空 9 CIN5 I/O 感应按键5检测输入 悬空 10 CIN6 I/O 感应按键6检测输入 悬空 11 CIN7 I/O 感应按键7检测输入 悬空 12 CIN8 I/O 感应按键8检测输入 悬空 13 CIN9 I/O 感应按键9检测输入 悬空 14 CIN10 I/O 感应按键10检测输入 悬空 15 CIN11 I/O 感应按键11检测输入 悬空 16 BCD3 O BCD码输出 悬空 17 BCD2 O BCD码输出 悬空 18 BCD1 O BCD码输出 悬空 19 BCD0 O BCD码输出 悬空 20 ASEL I 地址选择引脚 悬空 21 SCL I I2C 时钟输入 连接GND或VDD 22 SDA I/O I2C 数据输入输出 连接GND或VDD 或者悬空 23 INT O 触摸指示输出 24 VDD Pwr 电源正极 - VDD, GND :电源正负输入端。
CMOD :电荷收集电容输入端,接固定值的电容,和灵敏度无关。
CDC :接灵敏度电容,电容范围是最小5pf,最大100pf。根据使用环境选择合适的电容值,数值越小,灵敏度越高。
CIN0~CIN11 :接感应盘,是感应电容的输入检测端口。
BCD3~BCD0 :BCD码输出端口。无按键时,全部输出高电平;有按键时,输出相应BCD码。多按键时,只输 出优先级最高的按键码。
ASEL:I2C器件地址选择端口。
SCL, SDA:SCL 是I2C时钟输入端口。SDA是I2C数据输入输出端口。 SDA 端口有内部弱上拉。
INT: 触摸信号输出指示端口。有按键时输出高电平, 无按键时输出低电平。
二. 关键参数
-
使用I2C通信,读写地址,因为开发板的ASEL接地,所以后面地址使用0x42
状态 ASEL为高电平 ASEL悬空 ASEL为低电平 地址 (A[6:0]) 44H 40H 42H 读命令 (A[6:0]+RWB) 89H 81H 85H 写命令 (A[6:0]+RWB) 88H 80H 84H -
寄存器列表

-
- 灵敏度控制寄存器 SenSet0(地址 00H) SenSetCOM (地址 01H)
SENCH0[7:0] CIN4 的灵敏度设置
SENCOM[7:0] 其余通道的灵敏度设置
共有 16 档灵敏度可以设置, 由低到高为:【04H】 【15H】 【25H】 【36H】 【47H】 【58H】 【68H】【79H】 【8AH】 【9BH】 【ACH】 【BCH】 【CDH】 【DEH】 【EFH】 【FFH】 其中 79H 为初始值。该寄存器涉及到手指触摸阈值及手指离开阈值,如无特殊运用,建议客户按照如上参数设置。CIN4 单独设置灵敏度是可以把这个按键当做接近感应电极来用,或者隔空唤醒功能,如果 用作普通按键,把SENCH0[7:0]设成和SENCOM[7:0]一样就可以了。
-
- **控制寄存器 **CTRL0(地址 02H) SLPCYC[2:0] 睡眠时, 采样周期间隔,设置越大,唤醒速度越慢,功耗越低。

-
-
控制寄存器 CTRL1(地址 03H)
CSEL3~CSEL0:内部基准通道电容的选择,默认值为 1000,对应的电容选择为8PF,该值一般 用来修正外部通道的触摸感应量,该值可以设定范围0100~1111,对应值电容选择为4PF~15PF, 如无特殊应用,建议设置默认值8PF。
-
-
-
按键信息寄存器 Output0 (地址 08H) Output1 (地址 09H)
CH[11:0] 分别对应 CIN[11:0]的按键情况。 无按键时为0, 有按键时为1。
-
-
-
**采样值寄存器 **SAMPH (地址 0AH) SAMPL (地址 0BH)
CS[3:0] 采样值对应的通道,采样时候对应是采样13个通道,而我们SC012B通道CIN0到CIN11 对应是内部通道1到12。即当读取到CS值为1的时候,对应的SAMP值即为对应CIN0的采样值。 SAMP[11:0] 采样值
-
-

- 如果在一段时间内(75秒左右)没有检测到按键并且SDA端口一直保持高电平,芯片会自动进入省电模式。 只要让SDA保持高电平时间不超过75秒,芯片就不会进入睡眠模式。在睡眠模式中,按键的采样间隔会变长, 电流消耗(Idd)会减小。如果检测到按键,芯片会马上离开睡眠模式,进入正常模式。

-
Ts 大约是固定的950us左右。
-
正常模式下,采样间隔Tsin 是固定的大约12.5毫秒。
-
睡眠模式下,采样间隔Tsis通过寄存器SLPCYC[2:0] 配置,采样间隔越长,对应电流消耗Idds越低,但是唤醒的速度会相对变慢。
三. 代码
硬件抽象层
HAL_i2c.c
#include "HAL_i2c.h"
/**
* @brief 初始化i2c
*
* @param 无
*
* @return 无
*/
void i2c_Init(void)
{
/* 配置i2c */
i2c_config_t i2c_config =
{
.master.clk_speed = I2C_MASTER_CLK_SPEED,
.mode = I2C_MODE_MASTER,
.scl_io_num = I2C_SCL_GPIO,
.scl_pullup_en = true,
.sda_io_num = I2C_SDA_GPIO,
.sda_pullup_en = true,
};
i2c_param_config(I2C_PORT, &i2c_config);
/* 安装i2c驱动 */
i2c_driver_install(I2C_PORT,
I2C_MODE_MASTER,
0,
0,
0);
}
/**
* @brief i2c发送数据
*
* @param 无
*
* @return 无
*/
void i2c_send_byte(uint8_t reg_addr,uint8_t data)
{
uint8_t tx_buff[2] = {reg_addr, data};
i2c_master_write_to_device(I2C_PORT,
I2C_SLAVE_ADDR,
tx_buff,
sizeof(tx_buff),
1000);
}
/**
* @brief i2c接收数据
*
* @param 无
*
* @return 无
*/
uint8_t i2c_receive_byte(uint8_t reg_addr)
{
uint8_t rx_buff;
i2c_master_write_read_device(I2C_PORT,
I2C_SLAVE_ADDR,
®_addr,
1,
&rx_buff,
1,
1000);
return rx_buff;
}
Dri_i2c.h
#ifndef HAL_I2C_H
#define HAL_I2C_H
#include <stdio.h>
#include "driver/gpio.h"
#include "driver/i2c.h"
/* i2c 端口号 */
#define I2C_PORT I2C_NUM_0
/* i2c 时钟频率 400k */
#define I2C_MASTER_CLK_SPEED 400000
/* i2c 引脚 */
#define I2C_SCL_GPIO GPIO_NUM_1
#define I2C_SDA_GPIO GPIO_NUM_2
/* i2c 从机地址 */
#define I2C_SLAVE_ADDR 0x42
/**
* @brief 初始化i2c
*
* @param 无
*
* @return 无
*/
void i2c_Init(void);
/**
* @brief i2c发送数据
*
* @param 无
*
* @return 无
*/
void i2c_send_byte(uint8_t reg_addr,uint8_t data);
/**
* @brief i2c接收数据
*
* @param 无
*
* @return 无
*/
uint8_t i2c_receive_byte(uint8_t reg_addr);
#endif
驱动层
Dri_SC12B.c
#include "Dri_SC12B.h"
/* 按下按键二值信号量 */
extern SemaphoreHandle_t g_xBinarySemaphoreTouchKey;
/**
* @brief 初始化SC12B
*
* @param 无
*
* @return 无
*/
void SC12B_Init(void)
{
/* 设置灵敏度 */
i2c_send_byte(SENSET0, SENSITIVITY_LEVEL_3);
i2c_send_byte(SENSETCOM, SENSITIVITY_LEVEL_3);
}
/**
* @brief 读取按键值
*
* @param 无
*
* @return 读到的按键
*/
touch_key_t SC12B_read_key(void)
{
uint16_t key = 0;
key = i2c_receive_byte(OUTPUT1);
key <<= 8;
key |= i2c_receive_byte(OUTPUT2);
switch (key)
{
case 0x8000:
return KEY_0;
break;
case 0x4000:
return KEY_1;
break;
case 0x2000:
return KEY_2;
break;
case 0x1000:
return KEY_3;
break;
case 0x0800:
return KEY_4;
break;
case 0x0400:
return KEY_5;
break;
case 0x0200:
return KEY_6;
break;
case 0x0100:
return KEY_7;
break;
case 0x0080:
return KEY_8;
break;
case 0x0040:
return KEY_9;
break;
case 0x0020:
return KEY_M;
break;
case 0x0010:
return KEY_SHARP;
break;
default:
return KEY_NO;
break;
}
}
Dri_SC12B.h
#ifndef INF_SC12B_H
#define INF_SC12B_H
#include <stdio.h>
#include "Dri_i2c.h"
/* SC12B 寄存器地址 */
#define SENSET0 (0x00) /* 灵敏度控制寄存器 */
#define SENSETCOM (0x01) /* 灵敏度控制寄存器 */
#define CTRL0 (0x02) /* 控制寄存器 */
#define CTRL1 (0x03) /* 控制寄存器 */
#define OUTPUT1 (0x08) /* 按键信息寄存器 */
#define OUTPUT2 (0x09) /* 按键信息寄存器 */
#define SAMPH (0x0A) /* 采样值寄存器 */
#define SAMPL (0x0B) /* 采样值寄存器 */
/**
* 灵敏度等级枚举(16档,按升序排列)
*
*/
typedef enum {
SENSITIVITY_LEVEL_MIN = 0x04, /* 最低等级 */
SENSITIVITY_LEVEL_2 = 0x15,
SENSITIVITY_LEVEL_3 = 0x25,
SENSITIVITY_LEVEL_4 = 0x36,
SENSITIVITY_LEVEL_5 = 0x47,
SENSITIVITY_LEVEL_6 = 0x58,
SENSITIVITY_LEVEL_7 = 0x68,
SENSITIVITY_LEVEL_8 = 0x79,
SENSITIVITY_LEVEL_9 = 0x8A,
SENSITIVITY_LEVEL_10 = 0x9B,
SENSITIVITY_LEVEL_11 = 0xAC,
SENSITIVITY_LEVEL_12 = 0xBC,
SENSITIVITY_LEVEL_13 = 0xCD,
SENSITIVITY_LEVEL_14 = 0xDE,
SENSITIVITY_LEVEL_15 = 0xEF,
SENSITIVITY_LEVEL_MAX = 0xFF /* 最高等级 */
} sensitivity_level_t;
/* 按键 */
typedef enum
{
KEY_0,
KEY_1,
KEY_2,
KEY_3,
KEY_7,
KEY_5,
KEY_6,
KEY_4,
KEY_9,
KEY_M,
KEY_SHARP,
KEY_8,
KEY_NO
}touch_key_t;
/**
* @brief 初始化SC12B
*
* @param 无
*
* @return 无
*/
void SC12B_Init(void);
/**
* @brief 读到的按键
*
* @param 无
*
* @return 读到的按键
*/
touch_key_t SC12B_read_key(void);
#endif

浙公网安备 33010602011771号