关于8H8K64TL触摸滑轮的脚位功能切换问题
<pre><code>一直在用STC的单片机,触摸功能用的很少,以前都是外加TTP223,一个电容就能调灵敏度,简单易用!后来用了8H8K64TL,才发现这家伙有触摸的功能,爽!最近项目想用触摸滑轮功能,看了冲哥的《触摸滑条,8H4K64TLCD, 触摸按键、段码LCD液晶、实时时钟演示程序》有些地方没看明白,在此请教一下各位大侠!</code></pre>
<p>unsigned char code TS_Map={0xFF,0xFF,0x06,0x05,0x04,0x07,0x08,0x09,0xFF,0xFF,0x02,0x03,0x0A,0x0B,0x00,0x01}; //触摸按键通道重映射。这个重映射,数组内的16进制数代表啥意思?是不是脚位的切换?但是有4个0XFF,我就整不明白了。</p>
<p>如果不是脚位切换,那要怎样才能切换?</p>
按照这个顺序往数组里写数据,空的填0xFF,因为0x00是有意义的不能使用,当然0x0F以上都代表无效
触摸滑轮程序当前的状态仅适用于学习研究,不建议用于批量产品
DebugLab 发表于 2024-12-23 10:13
按照这个顺序往数组里写数据,空的填0xFF,因为0x00是有意义的不能使用,当然0x0F以上都代表无效
触摸滑轮 ...
意思是触摸功能还存在BUG?还是触摸滑轮不成熟?可别吓我? Tank2535 发表于 2024-12-23 11:02
意思是触摸功能还存在BUG?还是触摸滑轮不成熟?可别吓我?不行我就换合泰了。 ...
单片机没有问题,我写的触摸滑轮算法自认为有待完善,你可以把其他的触摸滑轮算法移植过来,如果效果比我写的这个好的话 Tank2535 发表于 2024-12-23 11:02
意思是触摸功能还存在BUG?还是触摸滑轮不成熟?可别吓我?不行我就换合泰了。 ...
或者你自己写一个触摸滑轮算法 DebugLab 发表于 2024-12-23 11:10
单片机没有问题,我写的触摸滑轮算法自认为有待完善,你可以把其他的触摸滑轮算法移植过来,如果效果比我 ...
本来就是想移植冲哥的程序来测试一下看看效果如何,无耐,水平有限,有部分没看懂。 Tank2535 发表于 2024-12-23 11:31
本来就是想移植冲哥的程序来测试一下看看效果如何,无耐,水平有限,有部分没看懂。 ...
屏是冲哥卖的,这个程序是我写的,有问题可以问我 DebugLab 发表于 2024-12-23 11:36
屏是冲哥卖的,这个程序是我写的,有问题可以问我
感谢老大!我现在是RING的三个脚由原来的是TK3/TK2TK5改为TK8/TK9/TK2,unsigned char code TS_Map={0xFF,0xFF,0x07,0xff,0x04,0xff,0x08,0x09,0x05,0x06,0x02,0x03,0x0A,0x0B,0x00,0x01}; //触摸按键通道重映射。你前面说的,不知道是不是我理解有误,测试Ring值一直是0。也就是触摸滑轮没工作。 Tank2535 发表于 2024-12-23 11:42
感谢老大!我现在是RING的三个脚由原来的是TK3/TK2TK5改为TK8/TK9/TK2,unsigned char code TS_Map={ ...
检查工程是否未包含 STARTUP.A51 或 Memory Model 改成 xdata 模式了
如是,这里加个TS_Ring=0
DebugLab 发表于 2024-12-23 11:51
检查工程是否未包含 STARTUP.A51 或 Memory Model 改成 xdata 模式了
如是,这里加个TS_Ring=0
TS_Ring=0已加,Ring还是0.其他没看出啥问题。
#include <STC8H.H>
#include <intrins.h>
#include <absacc.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include "timer.h"
#include "smg.h"
#define TK12 P00 // 0 高阻
#define TK13 P01 // 0 高阻
#define TK14 P02 // 0 高阻
#define TK15 P03 // 0 高阻
// #define SEG12 P04 // 0 高阻
// #define SEG9 P05 // 0 高阻
// #define SEG8 P06 // 0 高阻
// #define SEG7 P07 // 0 高阻
#define RXD2 P10 // 1 双向
#define TXD2 P11 // 1 推挽
// #define NO P12 // 0 高阻
#define TK3 P13 // 0 高阻
#define TK4 P14 // 0 高阻
#define TK5 P15 // 0 高阻
#define XTALO P16 // 0 高阻
#define XTALI P17 // 0 高阻
// #define SEG26 P20 // 0 高阻
// #define SEG25 P21 // 0 高阻
// #define SEG24 P22 // 0 高阻
// #define SEG23 P23 // 0 高阻
// #define SEG22 P24 // 0 高阻
// #define SEG21 P25 // 0 高阻
// #define TK6 P26 // 0 高阻
// #define TK7 P27 // 0 高阻
#define RXD P30 // 1 双向
#define TXD P31 // 1 推挽
#define P32 P32 // 0 高阻
#define P33 P33 // 0 高阻
#define P34 P34 // 0 高阻
#define COM2 P35 // 0 高阻
#define COM3 P36 // 0 高阻
#define CMP+ P37 // 0 高阻
// #define P40 P40 // 0 高阻
// #define SEG30 P41 // 0 高阻
// #define SEG29 P42 // 0 高阻
// #define SEG28 P43 // 0 高阻
// #define SEG27 P44 // 0 高阻
// #define SEG18 P45 // 0 高阻
// #define SEG17 P46 // 0 高阻
// #define SEG4 P47 // 0 高阻
#define COM0 P50 // 0 高阻
#define COM1 P51 // 0 高阻
#define TK10 P52 // 0 高阻
#define TK11 P53 // 0 高阻
#define TK2 P54 // 0 高阻
// #define NO P55 // 0 高阻
// #define NO P56 // 0 高阻
// #define NO P57 // 0 高阻
// #define SEG36 P60 // 0 高阻
// #define SEG37 P61 // 0 高阻
// #define SEG38 P62 // 0 高阻
// #define LED_G P63 // 1 推挽
// #define DS P64 // 0 双向
// #define LED_R P65 // 1 推挽
// #define BUZ P66 // 0 推挽
// #define LED_B P67 // 1 推挽
// #define SEG35 P70 // 0 高阻
// #define SEG34 P71 // 0 高阻
// #define SEG33 P72 // 0 高阻
// #define SEG32 P73 // 0 高阻
// #define SEG3 P74 // 0 高阻
// #define SEG2 P75 // 0 高阻
// #define SEG1 P76 // 0 高阻
// #define SEG0 P77 // 0 高阻
#define FOSC 24000000UL //主时钟
#define BAUD 115200UL //波特率
#define TMRF 200UL //定时器频率
#define BRT (0x10000-FOSC/BAUD/4) //波特率值
#define TMR (0x10000-FOSC/TMRF/12) //定时器值
#define T_Buf_Len 64 //Uart1发送缓存长度
#define R_Buf_Len 64 //Uart1接收缓存长度
#define LED_ON 0 //LED开
#define LED_OFF 1 //LED关
#define TS_Channel 10 //触摸按键通道数
#define TS_Compare 0x0800 //触摸按键比较值
#define TS_Range 0x0400 //触摸按键回滞值
unsigned char RP; //Uart2接收指针
unsigned char TP; //Uart2发送指针
unsigned char Uart_R_Len; //Uart2接收长度
unsigned char Uart_T_Len; //Uart2发送长度
unsigned char xdata R_Buf; //Uart2接收缓存
unsigned char xdata T_Buf; //Uart2发送缓存
unsigned char code Seg_Map={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; //数码管段码(ABCDEFGH)
unsigned char D_Buf; //10个数字和小数点(ABCDEFGH)
//(7:3)5个-(2:0)星期(0=OFF 1=SUN 2=MON 6=FRI 7=SAT)
//(7:6)2个:(5:4)2个-(3)闹钟(2)AM(1)PM(0)FM
//(7)μV(6)mV(5)V(4)KV(3)℃(2)℉(1)%(0)RH
//(8)STC(1)AC(0)DC
unsigned char code TS_Map={0xFF,0xFF,0x07,0xff,0x04,0xff,0x08,0x09,0x05,0x06,0x02,0x03,0x0A,0x0B,0x00,0x01}; //触摸按键通道重映射
unsigned int xdata TS_Buf; //触摸按键数据(实际值、预处理值、最小值、最大值、结果)
unsigned char TS_Select; //触摸按键选择通道(查看TS_Buf,低4位为低维度,范围0x*0-0x*B;高4位为高维度,范围0x0*-0x4*)
unsigned char TS_Scan; //触摸按键扫描通道
bit TS_Flag; //触摸按键中断标志
unsigned char TS_Calibrate; //触摸按键校准状态
unsigned char TS_Pad; //触摸按钮状态
unsigned char TS_Ring; //触摸滑环状态
unsigned char TS_Slide; //触摸滑条状态
unsigned int Ring; //触摸滑环值
unsigned int Slide; //触摸滑条值
void UART_Send(unsigned int x)
{
TP=0;
Uart_T_Len=x;
S2CON|=S2TI;
}
//void Uart_Printf(unsigned char *v,...)
//{
// va_list ap;
// va_start(ap,v);
// while(Uart_T_Len);
// UART_Send(vsprintf(T_Buf,v,ap));
// va_end(ap);
//}
void UART_Return(unsigned char temp)
{
memcpy(T_Buf,R_Buf,temp);
UART_Send(temp);
}
unsigned int Compare(bit x,unsigned int a,unsigned int b)
{
return a==b?a:(x==0?(a<b?a:b):(a>b?a:b));
}
void Calibrate(void)
{
unsigned char i;
static unsigned char flag;
switch(TS_Calibrate)
{
case 0:
flag=0x0F;
break;
case 1:
if(flag&0x01)
{
flag&=0x0E;
TS_Buf=TS_Buf;
}
else
{
TS_Buf=Compare(0,TS_Buf,TS_Buf);
}
break;
case 2:
if(flag&0x02)
{
flag&=0x0D;
TS_Buf=TS_Buf;
}
else
{
TS_Buf=Compare(1,TS_Buf,TS_Buf);
}
break;
case 3:
if(flag&0x04)
{
flag&=0x0B;
for(i=0;i<TS_Channel;i++)
{
TS_Buf=TS_Buf;
}
}
else
{
for(i=0;i<TS_Channel;i++)
{
TS_Buf=Compare(0,TS_Buf,TS_Buf);
}
}
break;
case 4:
if(flag&0x08)
{
flag&=0x07;
for(i=0;i<TS_Channel;i++)
{
TS_Buf=TS_Buf;
}
}
else
{
for(i=0;i<TS_Channel;i++)
{
TS_Buf=Compare(1,TS_Buf,TS_Buf);
}
}
break;
default:
break;
}
}
void Touch_Pad(void)
{
unsigned char i;
unsigned int limit_l,limit_h;
limit_l=TS_Compare-TS_Range/2;
limit_h=TS_Compare+TS_Range/2;
for(i=0;i<5;i++)
{
if(TS_Buf<=limit_l)
{
TS_Pad&=~(0x01<<i);
}
if(TS_Buf>=limit_h)
{
TS_Pad|=0x01<<i;
}
}
}
void Touch_Ring(void)
{
unsigned char i;
unsigned int limit_l,limit_h;
limit_l=TS_Compare-TS_Range/2;
limit_h=TS_Compare+TS_Range/2;
TS_Ring = 0;
for(i=0;i<3;i++)
{
if(TS_Buf<=limit_l)
{
TS_Ring&=~(0x01<<i);
}
if(TS_Buf>=limit_h)
{
TS_Ring|=0x01<<i;
}
}
if(TS_Ring&0x07)
{
TS_Ring|=0x80;
if(TS_Ring==0x81|TS_Ring==0x82|TS_Ring==0x83|TS_Ring==0x84|TS_Ring==0x85|TS_Ring==0x86)
{
if(TS_Buf>=TS_Buf&&TS_Buf>=TS_Buf)
{
if(TS_Buf>=TS_Buf)
{
Ring=((TS_Buf-(TS_Buf*(TS_Buf/(TS_Buf*2))))*0x0555UL)/(TS_Buf+TS_Buf);
}
else
{
Ring=((TS_Buf+(TS_Buf*(TS_Buf/(TS_Buf*2))))*0x0555UL)/(TS_Buf+TS_Buf)+0x0AAA;
}
}
else if(TS_Buf>=TS_Buf&&TS_Buf>=TS_Buf)
{
if(TS_Buf>=TS_Buf)
{
Ring=((TS_Buf-(TS_Buf*(TS_Buf/(TS_Buf*2))))*0x0555UL)/(TS_Buf+TS_Buf)+0x0555;
}
else
{
Ring=((TS_Buf+(TS_Buf*(TS_Buf/(TS_Buf*2))))*0x0555UL)/(TS_Buf+TS_Buf);
}
}
else if(TS_Buf>=TS_Buf&&TS_Buf>=TS_Buf)
{
if(TS_Buf>=TS_Buf)
{
Ring=((TS_Buf-(TS_Buf*(TS_Buf/(TS_Buf*2))))*0x0555UL)/(TS_Buf+TS_Buf)+0x0AAA;
}
else
{
Ring=((TS_Buf+(TS_Buf*(TS_Buf/(TS_Buf*2))))*0x0555UL)/(TS_Buf+TS_Buf)+0x0555;
}
}
}
else
{
Ring=0;
}
}
else
{
TS_Ring&=0x7F;
Ring=0;
}
}
void Touch_Slide(void)
{
}
void Touch_Key(void)
{
unsigned char i;
if(TS_Flag)
{
TS_Flag=0;
for(i=0;i<TS_Channel;i++)
{
TS_Buf=TS_Buf*3+((0xFFFF-TS_Buf)>>2)>>2;
if(TS_Buf>TS_Buf)
{
TS_Buf=(TS_Buf>TS_Buf?(TS_Buf-TS_Buf):0)*0x1000UL/(TS_Buf-TS_Buf);
if(TS_Buf>0x0FFF)
{
TS_Buf=0x0FFF;
}
}
else
{
TS_Buf=0;
}
}
Calibrate();
Touch_Pad();
Touch_Ring();
Touch_Slide();
}
}
void Init(void)
{
P_SW2|=EAXFR;
P0M0 &= ~0x0f; P0M1 |= 0x0f;
P1M0=0x02;
P1M1=0xFC;
P2M0=0xFF;
P2M1=0x00;
P3M0 &= ~0x30; P3M1 |= 0x30;
P4M0=0xFF;
P4M1=0x00;
P5M0=0x00;
P5M1=0xFF;
P6M0=0xE8;
P6M1=0x07;
P7M0=0x00;
P7M1=0xFF;
// X32KCR=0xC0; //启动外部32768晶振,设置高增益
// while(!(X32KCR&0x01));
AUXR=0x04; //设置定时器0时钟为12T模式,设置定时器2为1T模式
TMOD=0x01; //设置定时器0为16位不自动重装载模式
TH0=TMR>>8; //设置定时器0初始值
TL0=TMR; //设置定时器0初始值
TF0=0; //清除TF0中断标志位
ET0=1; //启用定时器0中断
S2CON=0x10; //设置UART2模式为8位数据可变波特率
T2H=BRT>>8; //设置UART2波特率
T2L=BRT; //设置UART2波特率
AUXR|=T2R; //打开定时器2
IE2|=ES2; //启用UART2中断
// LCDCFG2=0x0F; //设置SEG脚位
// LCDCFG=0x80; //设置LCD时钟为外部32768Hz晶振,设置VLCD为0.65*VCC(3.25V)
// DBLEN=0x00; //设置死区时间
// COMLENL=0x3F; //设置COM时间
// COMLENM=0x00; //设置COM时间
// COMLENH=0x00; //设置COM时间
// BLINKRATE=0x40; //设置闪烁率
// COMON=0x0F; //COM使能
// SEGON1=0x9F; //SEG使能
// SEGON2=0x13; //SEG使能
// SEGON3=0xE6; //SEG使能
// SEGON4=0x7F; //SEG使能
// SEGON5=0x7F; //SEG使能
// LCDCR=0x01; //启用LCD,普通显示模式
TSCHEN1=0xFC; //TK00~TK07
TSCHEN2=0x07; //TK08~TK10
TSRT=0x00; //没有LED分时扫描
TSCFG1=0x73; //开关电容工作频率 = fosc/(2*(TSCFG1+1)),放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
TSCFG2=0x03; //配置触摸按键控制器的内部参考电压(AVCC的分压比),0(1/4)1(1/2)2(5/8)3(3/4)
TSCTRL=0x33; //重复扫描模式,完成一轮扫描暂停,低功耗模式时钟为外部32768晶振,关闭数字比较器,关闭低功耗唤醒,4次平均,B7: TSGO,B6: SINGLE,B5: TSWAIT,B4: TSWUCS,B3: TSDCEN,B2: TSWUEN,B1 B0: TSSAMP
TSCTRL|=0x80; //开始扫描
IE2|=0x80; //启用触摸中断
//
// LED_R=LED_ON;
// LED_G=LED_ON;
// LED_B=LED_ON;
// C0SEGV0=0x00;
// C0SEGV1=0x00;
// C0SEGV2=0x00;
// C0SEGV3=0x00;
// C0SEGV4=0x00;
// C1SEGV0=0x00;
// C1SEGV1=0x00;
// C1SEGV2=0x00;
// C1SEGV3=0x00;
// C1SEGV4=0x00;
// C2SEGV0=0x00;
// C2SEGV1=0x00;
// C2SEGV2=0x00;
// C2SEGV3=0x00;
// C2SEGV4=0x00;
// C3SEGV0=0x00;
// C3SEGV1=0x00;
// C3SEGV2=0x00;
// C3SEGV3=0x00;
// C3SEGV4=0x00;
memset(R_Buf,0x00,sizeof R_Buf);
memset(T_Buf,0x00,sizeof T_Buf);
memset(TS_Buf,0x00,sizeof TS_Buf);
TS_Buf=11830;
TS_Buf=11590;
TS_Buf=11040;
TS_Buf=10870;
TS_Buf=10760;
TS_Buf=13970;
TS_Buf=14080;
TS_Buf=14020;
TS_Buf=10690;
TS_Buf=10960;
TS_Buf=11180;
TS_Buf=11010;
TS_Buf=14820;
TS_Buf=14850;
TS_Buf=14740;
TS_Buf=14530;
TS_Buf=14690;
TS_Buf=15010;
TS_Buf=15040;
TS_Buf=15100;
TS_Buf=14460;
TS_Buf=13610;
TS_Buf=14090;
TS_Buf=14200;
TS_Select=0x44;
}
void main(void)
{
unsigned int Num = 6666;
Init();
Timer1_Init();
EA = 1;
while(1)
{
Touch_Key();
LEDBUF= Ring/1000;
LEDBUF= Ring/100%10;
LEDBUF= Ring/10%10;
LEDBUF= Ring%10;
// LCD_Display(Ring,(TS_Calibrate<<8)|TS_Select);
}
}
void Uart_Start(void)
{
TH0=TMR>>8;
TL0=TMR;
TR0=1;
}
void Uart_Stop(void)
{
TR0=0;
TH0=TMR>>8;
TL0=TMR;
RP=0;
memset(R_Buf,0x00,sizeof R_Buf);
}
void Timer0_Isr(void) interrupt TMR0_VECTOR
{
if(((R_Buf>>4)<=4)&&((R_Buf&0x0F)<=0x0B))
TS_Select=R_Buf;
else if(((R_Buf>>4)==0x05)&&((R_Buf&0x0F)<=0x04))
TS_Calibrate=R_Buf&0x07;
UART_Return(RP);
Uart_Stop();
}
void Uart2_Isr(void) interrupt UART2_VECTOR
{
if(S2CON&S2RI)
{
S2CON&=~S2RI;
Uart_Start();
R_Buf=S2BUF;
if(RP==R_Buf_Len-1)
{
Uart_Stop();
}
else if(TR0)
{
RP++;
}
}
if(S2CON&S2TI)
{
S2CON&=~S2TI;
if(TP==Uart_T_Len)
{
TP=0;
Uart_T_Len=0;
}
if(Uart_T_Len!=0)
{
S2BUF=(T_Buf);
TP++;
}
}
}
void TKSU_Isr(void) interrupt 13
{
unsigned char temp;
temp=TSSTA2;
if(temp&0x40) //数据溢出, 错误处理
{
TSSTA2|=0x40; //写1清零
}
else if(temp&0x80) //扫描完成
{
TS_Scan=temp&0x0f;
if(TS_Map!=0xFF) //如果通道正确
{
TS_Buf]=TSDAT; //保存某个通道的读数
TS_Flag=1;
}
}
TSSTA2|=0x80; //写1清零
}
页:
[1]
2