STC8H触摸按键的简单应用与经验分享
本帖最后由 乐此不疲 于 2023-2-12 14:56 编辑以往十几年一直在玩STC各型单片机,最近很长一段时间一直在玩STC新型单片机的新功能,测试了STC8H4K64TL单片机的I2C、RTC、触摸按键功能,也测试了STC32G的LCM_DMA应用(16BIT并口驱动SSD1963屏),上述的学习过程中曾多次在此请教问题,每次求问都得到了相应的指点、在此再表谢意!为了回馈各位的帮助发帖分享编程新手的关于STC8H单片机触摸按键的应用心得,也希望能帮到与我一样的菜鸟朋友。
以上是闲话
------✄-------------------------------------✄---------------
以下是正文
STC8H的触摸按键的基本功能通过官网例程加持是很容易实现的,只要配置好触摸按键的相关寄存器、根据按键触摸状态与非触摸状态的键值变化是很容易实现触摸按键的开/关功能的,以下实验使用的是STC8H4K64TL-20pin芯片,通过I/0模拟3线SPI总线控制一块ILI9481-480*320*3.5"TFT屏,用到了P1.1、P1.6、P5.4三个触摸按键端口。
因为我是在实验板自身显示单元的屏幕上实时显示测试结果的,如果你的实验板有显示单元可以通过自己的显示函数实现测试结果的显示,如果没有挂载显示单元的话请开启单片机的串口通讯功能通过stc-isp软件的串口助手窗口来实现监测。
注释:下述贴出的代码是在我的工程中摘录的片段,因为涉及公共变量的声明问题只能配合解读、不保证编译能够通过。
一、STC8H单片机触摸按键的基础代码
1.配置按键寄存器:(触摸按键初始化函数,请在主循环前声明此函数)
void key_init()
{
TSRT = 0x00; //没有LED分时扫描
TSCHEN1 |= 0x46;//使能TK6-P1.6、TK2-P5.4、TK1-P1.1三个按键
TSCFG1= (7<<4) + 7; //开关电容放电时间(系统时钟周期数7500)
TSCFG2= 1; //配置触摸按键控制器的内部参考电压AVCC的分压比为1/2
TSCTRL = 0x80; //启动触摸按键控制、使用内部32K时钟
TK_ON(); //使能触摸按键中断(IE2 |=(1<<7))
EA=1; //开启所有中断使能
}
上述寄存器配置请详情还请阅读数据手册的23.5.1-23.5.8章节。
2.按键扫描函数(中断函数):
void key_int()interrupt 35//keil2编译环境以根据STC数据手册给出的方案通过第三方软件扩展了中断号
{
u8 j;
j = TSSTA2;
if(j & 0x40)
TSSTA2 |= 0x40; //数据溢出,写1将TSIF清零
if(j & 0x80)
{
TSSTA2 |= 0x80; //扫描完成写1将TSIF清零
TKn=j&0x0f;
//----键值存储--------------------------------------
switch(TKn)
{
case 0x01:
tk = TSDAT;
break;//1通道键值
case 0x02:
tk = TSDAT;
break;//2通道键值
case 0x06:
tk = TSDAT;
break;//6通道键值
}
//----以下是按键状态判断-----------------------------
if((TKn==6)&&(tk>value_H))//N1非触摸状态
{
N1=1;
}
if((TKn==6)&&(tk<value_L)) //N1触摸状态
{
N1=0;
}
if((TKn==2)&&(tk>value_H)) //N2非触摸状态
{
N2=1;
}
if((TKn==2)&&(tk<value_L)) //N2触摸状态
{
N2=0;
}
if((TKn==1)&&(tk>value_H)) //N3非触摸状态
{
N3=1;
}
if((TKn==1)&&(tk<value_L)) //N3触摸状态
{
N3=0;
}
}
}
中断函数里的两个参数value_H、value_L是两个数据,为了获得这两个数据我又编写了两个函数如下:
(1)、4位十六进制数据变换、显示函数void display_num(u16 x, u16 y, u16 num);
此函数是针对自己的字模库量身编写的,没有参考价值就不贴代码了!!!
(2)、触摸键值显示函数
void display_value()
{
if(TKn==0)
{
tk = TSDAT; //0通道键值
}
if(TKn==1)
{
tk = TSDAT; //1通道键值
}
if(TKn==2)
{
tk = TSDAT; //2通道键值
}
display_num(0, 250, tk);
display_num(150, 250, tk);
display_num(300, 250, tk);
}
程序运行后,可以实时显示三个按键的十六进制即时数据,根据对数据的观察可以得到没有触摸时键值和触摸后的键值,再根据显示值设定一个较小的非触摸键值value_H和一个较大的触摸键值value_L并宏定义好就可以继续玩耍了,因为只是简单验证,至于实际工程应用标准编程的零点值存储、零点值跟踪、门槛值配置这些我没深入研究就不做讨论了,如果需要的话请详细阅读数据手册。
二、按键功能的实现方法
1.单独按键实现开/关功能:
上述给出的按键初始化和中断这两个函数就可以实现触摸按键的基本功能,对于单个按键(例如TK6按键)控制一个(P3.4口)LED灯的点亮与熄灭的控制而言可以简化一下中断函数即可实现
void key_int()interrupt 35
{
u8 j;
j = TSSTA2;
if(j & 0x40)
TSSTA2 |= 0x40; //数据溢出,写1将TSIF清零
if(j & 0x80)
{
TSSTA2 |= 0x80; //扫描完成写1将TSIF清零
TKn=j&0x0f;
if((TKn==6)&&(TSDAT<value_L)) //触摸状态
{
P34=~P34; //请在主循环前初始化此端口P34=1,低电平点亮LED
}
}
}
中断函数修改完成后,主函数的主循环空运行的状态下,触摸按键就可以看到控制效果。
2、按键加减操作的实现:
触摸按键的加减操作可以参考常用的单片机独立按键(机械按键)代码来实现,触摸按键实现这个功能的话可以使用前述未修改的中断函数,下面是利用N1按键实现的代码
void Choice_set()
{
if(N1==0)
{
rr++;
if(rr>9)//用于屏幕上一位数据的显示
rr=0;
}
while(!N1);
}
只要在主循环中调用这函数就能实现数据的加操作,如果主循环中同时添加字符显示函数就可以看到数据的变化每次触摸按键时数据不变离开手后数据增加1。
到此,STC8H触摸按键这点儿经验就分享完成了,由于经验浅薄有兴趣的新手可以看看、高手就直接绕行好了,其实即使新手也会发现这种通过死循环来判断按键释放的方法是不靠谱的,函数void Choice_set()这样的按键编程虽然可以实现操作功能,但也只能用于演示、在此也只能作为抛砖引玉了,我也在此真心向高手求救关于触摸按键加减操作的靠谱的实现方法,也希望有兴趣的朋友能够交流经验完善功能。
占楼顶贴,!!!!! 官网例程中的触摸例程,在哪啊?下载的库函数包里,没有找到啊? seekerwang 发表于 2023-2-24 14:42
官网例程中的触摸例程,在哪啊?下载的库函数包里,没有找到啊?
可以在官网软件工具下面下载
我的万年历工程中已经整合进去触摸按键功能了,长、短按键功能都基本实现了,此后可以杜绝轻触按键失灵、更换的弊病了。 乐此不疲 发表于 2023-2-25 10:58
我的万年历工程中已经整合进去触摸按键功能了,长、短按键功能都基本实现了,此后可以杜绝轻触按键失灵、更 ...
请教长短按怎么实现的 ,说一下思路可以么 mt1122 发表于 2023-9-18 20:36
请教长短按怎么实现的 ,说一下思路可以么
好长时间没登陆这里了,下面简单说下我的按键设计和长短按键的实现方法与你和同样感兴趣的朋友交流也请高手指正。
方法如下:如果主程序通过判断进入按键操作程序时、则启动定时器开始秒计时(全局变量s累加),在转入相关按键(加操作或减操作)操作程序后首先将s值保存到另一个变量tn中(tn=s;//保存计时初值),而后在查询按键状态的同时也判断s-tn,根据自己的设定值比对判断结果来判定按键时间的长短。以上或许说的很绕,但肯定比看代码容易理解,因为年初写的代码现在我自己也是看来好久才理顺明白的。
这个还没用过
页:
[1]