8H1K17T触摸按键
// 头文件#include "STC8H.H" // 引入STC8系列单片机的头文件
#include "intrins.h" // 引入Keil的内部函数头文件
// 宏定义
// 数据类型
#defineu32 unsigned long // 定义32位无符号整数类型
#defineu16 unsigned int // 定义16位无符号整数类型
#defineu8 unsigned char // 定义8位无符号整数类型
// 数据存储
#define MAIN_Fosc 20000000L // 定义主时钟
// 引脚定义
sbit TK0= P1^0;
sbit LED= P3^7;
// 声明
// 数组
u16 xdata TK_cnt[16]; // 按键计数值, 16位
u16 xdata TK_zero[16];// 按键0点值, 16位
// K0 K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 K13 K14 K15
// 触摸后的变化值
u16 code T_KeyPress[16]={ 700,2000,900, 800, 900, 1000, 1100, 1400,1000,1200, 900,1200,750, 900, 1300,1800};
// 16个键对应的状态, 0为未触摸,1为触摸
u16 code T_KeyState[16]={0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};
// 函数
void delay_ms(u8 ms);
void ReturnValue(u8 channel, u16 value);
// 变量
bit B_TK_Lowpass; // 低通允许, 1允许, 0禁止
u8read_cnt; // 读次数
u16 KeyState; // 按键状态, 每个bit对应一个键, 1为按下, 0为释放
// 函数模块
// 主函数
void main(void)
{
u8i;
u16 j;
P1M0 &= ~0x01; P1M1 |= 0x01; // P10为高阻输入
P3M0 |= 0x80; P3M1 &= ~0x80; // P37为推挽输出
LED = 0;
P_SW2 |= 0x80; // 允许访问扩展寄存器xsfr
EA = 1; // 开总中断
TSCHEN1 = 0x01; // TK0~TK7
TSCHEN2 = 0x00; // TK8~TK15
TSCFG1= (7<<4) + 6; // B6~B4:开关电容工作频率 = fosc/(2*(TSCFG1+1)), B2~B0:放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最好大于等于3(1000)
TSCFG2= 1; // B1~B0:配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4)1(1/2)2(5/8)3(3/4)
TSRT = 0x00; // 没有LED分时扫描
IE2 |= 0x80; // 允许触摸按键中断
delay_ms(50); // 延时一下
B_TK_Lowpass = 0; // 禁止低通滤波
for(read_cnt=0; read_cnt<10; read_cnt++) // 扫描10次键, 将此值作为未触摸时的0点, 要求上电时不要触摸按键
{
TSCTRL = (1<<7) + (1<<6); // 开始扫描, 无平均
delay_ms(50); // 延时一下, 等待扫描完成
}
for(i=0; i<16; i++) TK_zero = TK_cnt; // 保存0点
B_TK_Lowpass = 1; // 允许低通滤波
KeyState = 0;
read_cnt = 0;
while (1)
{
TSCTRL = (1<<7) + (1<<6); // 开始扫描, 无平均
delay_ms(20); // 延时一下, 根据实际扫描速度调整
if(++read_cnt >= 3)
{
read_cnt = 0;
j = KeyState;
for(i=0; i<16; i++)
{
if(TK_zero> TK_cnt) // 0点值比当前值大, 则键按下, 缓慢0点跟踪
{
TK_zero--; // 缓慢0点跟随
if((TK_zero - TK_cnt) >= T_KeyPress/2) KeyState |=T_KeyState; // 变化值大于最大变化值的1/2, 则判断键已触摸
else if((TK_zero - TK_cnt) <= T_KeyPress/3) KeyState &= ~T_KeyState; // 变化值小于最大变化值的1/3, 则判断键已释放
}
else // 0点值比当前值小, 则键释放
{
KeyState &= ~T_KeyState; // 键状态: 释放
if((TK_cnt - TK_zero) > 100)TK_zero += 100; // 差别很大, 则快速回0点
else TK_zero += 10; // 差别不大, 则慢速回0点
}
}
j = (j ^ KeyState) & KeyState; // LED指示处理
B = (u8)j;
if(B0)LED = ~LED;
}
}
}
// 描述: 延时函数。
void delay_ms(u8 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 10000;
while(--i);
}
while(--ms);
}
// 描述: 触摸按键中断服务函数
void TKSU_ISR(void) interrupt TKSU_VECTOR
{
u8j;
j = TSSTA2;
if(j & 0x40) // 数据溢出, 错误处理(略)
{
TSSTA2 |= 0x40; // 写1清零
}
if(j & 0x80) // 扫描完成
{
j &= 0x0f;
TSSTA2 |= 0x80; // 写1清零
if(!B_TK_Lowpass) TK_cnt = TSDAT; // 保存某个通道的读数 1.1us @24MHz
else TK_cnt = (TK_cnt >> 1) + (TSDAT >> 1); // 保存某个通道的读数 1/2低通滤波 4.6us @24MHz, 低通a=0.25, 未按键读数20000, 按键读数21600, 则要11个次采样点(100Hz采样110ms)读数才到21500.
}
}
这是我根据例程修改成单通道控制单个LED 的触摸按键程序
这样配置没问题么 为什么在实际使用的过程中触摸按键不是很灵敏
尊敬的开发者,您好:
感谢您对STC8H1K17T触摸按键应用的关注。以下是对该芯片在触摸按键功能实现中的技术说明与建议,供您参考。
一、概述
STC8H1K17T是STC推出的一款基于增强型8051内核的高性能单片机,具备丰富的外设资源,包括多通道ADC、PWM、定时器及触摸按键检测功能。其内置的触摸按键模块支持电容式触摸检测,适用于低功耗、高灵敏度的触控应用场景。
二、触摸按键功能简介
STC8H1K17T支持通过内部ADC通道进行触摸按键检测。其原理是利用电容变化引起的电压波动来判断是否有按键被按下。具体流程如下:
1. 初始化配置:设置相关寄存器,启用触摸检测功能。
2. 采集数据:通过ADC读取触摸引脚的电压值。
3. 阈值判断:根据预设的基准值判断是否触发按键。
4. 去抖处理:防止误触发,提升稳定性。
三、代码示例与说明
以下为基于Keil C51环境的简化代码示例,用于演示如何使用STC8H1K17T实现触摸按键功能:
c
include "STC8HH.h"
include "intrinsh.h"
define u32 unsigned int
define u8unsigned char
// 定义触摸引脚(例如P3.0)
define TOUCHPIN P30
// 触摸阈值设定
define TOUCHTHRESHOLD 100
// ADC配置函数
void ADCInit(void) {
ADCCON1 = 0x80; // 选择ADC通道0,开启ADC
ADCCON3 = 0x00; // 设置采样时间等参数
}
// 读取ADC值
u16 ReadADC(void) {
ADCCON1 |= 0x01; // 启动一次转换
while (ADCCON1 & 0x01); // 等待转换完成
return ADCDATA;
}
// 检测触摸按键
bit CheckTouch(void) {
u16 adcval = ReadADC();
if (adcval > TOUCHTHRESHOLD) {
return 1;// 触发
} else {
return 0;// 未触发
}
}
// 主函数
void main(void) {
ADCInit();
while (1) {
if (CheckTouch()) {
// 执行按键响应逻辑
}
nop();// 延时去抖
}
}
四、注意事项
1. 引脚配置:确保触摸引脚已正确配置为输入模式,并连接外部电容或金属片作为触摸感应点。
2. 校准与调参:实际应用中需根据硬件环境调整TOUCHTHRESHOLD值,以获得最佳灵敏度与稳定性。
3. 去抖处理:建议采用软件延时或硬件滤波方式减少误触发。
4. 电源与地线:良好的电源和接地设计对触摸检测性能至关重要。
五、优化建议
使用多通道ADC并行检测多个触摸点,提高系统灵活性。
结合中断机制实现更高效的按键响应。
在低功耗模式下合理管理ADC唤醒机制,以延长电池寿命。
如您在开发过程中遇到具体问题,欢迎进一步沟通。我们将持续为您提供技术支持与文档资料,助力项目顺利推进。
此致
敬礼!
国芯人工智能团队
2025年4月
[本文内容由国芯人工智能辅助生成,仅供参考] 看到了您使用了带零点跟踪的例程,例程都是测试通过的不应存在问题,那么问题应该是硬件导致的,比如绝缘介质过厚、PCB设计不合理等原因,先按照您的硬件实物调试,尝试根据触摸后的变化值修改T_KeyPress,如果仍未解决,需要上传PCB图或实物照片具体分析 我现在修改了K0 的T_KeyPress 但是不是大就是小了
如图箭头所指向的位置触碰后触摸就会起作用 但是灵敏度很奇怪 触摸按键可以了
例程是OK的
触摸充放电的电容引脚差错了 20 和 16脚封装看错
例程改一下触摸通道和LED的引脚就可以使用了
页:
[1]