触摸唤醒
void main(){
u8 i = 0;
EAXSFR(); /* 扩展寄存器访问使能 */
EA = 1;
CLK_Init();
//LCD_config();// LCD先初始化否则会打乱后面外设的初始化
Enable_Init();
BAT1_HIGH();
RED_LOW();
//ADC_config();
//DMA_config();
UART_config();
TouchKey_Init();
IRC32KCR = 0x80; //启动内部32K IRC
while (!(IRC32KCR & 1)); //等待时钟稳定
delay_ms(50);
for(i=0; i<10; i++) //扫描10次键, 将此值作为未触摸时的0点, 要求上电时不要触摸按键
{
// // TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, 4次平均
TSCTRL = (1<<7) + (1<<6); //开始扫描, 无平均
delay_ms(50); //延时一下, 等待扫描完成
}
TK_zero = TK_cnt; //保存0点
sprintf(buffer, "zero:%d\r\n", TK_cnt);
PrintString1(buffer);
sprintf(buffer, "T_KeyPress/2:%d\r\n", T_KeyPress/2);
PrintString1(buffer);
TSTH12 = TK_zero - T_KeyPress/2; //设置唤醒门槛值 = 0点(未触摸)值 - 触摸变化值/2
sprintf(buffer, "TSTH12:%d\r\n", TSTH12);
PrintString1(buffer);
while(1)
{
// 1、进入低功耗前IO口配置
BAT1_LOW();
RED_HIGH();
// 2、关闭外设
// 3、关闭触摸模块
TSCTRL = (1<<3) + (1<<2) + 0; //关闭触摸模块, 允许16位数字比较器, 允许低功耗唤醒。 B7: TSGO,B6: SINGLE,B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
printf("sleep\r\n");
PCON |= 0x02;
NOP(5);
TSCTRL = (1<<7) + (1<<3) + (1<<2) + 0;
EAXSFR(); /* 扩展寄存器访问使能 */
CLK_Init();
printf("sleepout\r\n");
BAT1_HIGH();
RED_LOW();
}
}
通过P00-触摸12通道来进行触摸唤醒,
TSTH12 打印出来是7000左右,
触摸按键按下串口观察触摸值是2500左右,
可是为什么无法唤醒呢?
// 1、触摸引脚设置为高阻输入
P0M0 &= ~0x01; P0M1 |= 0x01;
// 2、触摸通道使能
//TSCHEN1 = 0x08;
TSCHEN2 = 0x10;
// 3、不开启LED驱动分时多任务功能
TSRT = 0x00;
// 4、设置按键开关频率,参考电压以及放电时间
TSCFG1= (7<<4) + 7;
TSCFG2= 2;
// 5、开启触摸按键
//TSCTRL = 0xa0;
// 6、设置唤醒频率
TSWUTC = 128; //唤醒频率 = F32K/(32*8*TSWUTC) = 128/TSWUTC Hz, TSWUTC = 1~255
// 7、开启中断
IE2 |= 0x80;
触摸按键的初始化,代码是按照唤醒例程写的 神农鼎 发表于 2026-6-12 09:27
u8 i = 0;
EAXSFR(); /* 扩展寄存器访问使能 */
EA = 1;
CLK_Init();
//LCD_config();// LCD先初始化否则会打乱后面外设的初始化
Enable_Init();
BAT1_HIGH();
RED_LOW();
//ADC_config();
//DMA_config();
UART_config();
TouchKey_Init();
IRC32KCR = 0x80; //启动内部32K IRC
while (!(IRC32KCR & 1)); //等待时钟稳定
delay_ms(50);
for(i=0; i<10; i++) //扫描10次键, 将此值作为未触摸时的0点, 要求上电时不要触摸按键
{
// // TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, 4次平均
TSCTRL = (1<<7) + (1<<6); //开始扫描, 无平均
delay_ms(50); //延时一下, 等待扫描完成
}
TK_zero = TK_cnt; //保存0点
sprintf(buffer, "zero:%d\r\n", TK_cnt);
PrintString1(buffer);
sprintf(buffer, "T_KeyPress/2:%d\r\n", T_KeyPress/2);
PrintString1(buffer);
TSTH12 = TK_zero - T_KeyPress/2; //设置唤醒门槛值 = 0点(未触摸)值 - 触摸变化值/2
sprintf(buffer, "TSTH12:%d\r\n", TSTH12);
PrintString1(buffer);
while(1)
{
// 1、进入低功耗前IO口配置
BAT1_LOW();
RED_HIGH();
// 2、关闭外设
// 3、关闭触摸模块
TSCTRL = 0x00;
delay_ms(50);
TSCTRL = (1<<3) + (1<<2) + 0; //关闭触摸模块, 允许16位数字比较器, 允许低功耗唤醒。 B7: TSGO,B6: SINGLE,B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
printf("sleep\r\n");
PCON |= 0x02;
NOP(5);
TSCTRL = (1<<7) + (1<<3) + (1<<2) + 0;
EAXSFR(); /* 扩展寄存器访问使能 */
CLK_Init();
printf("sleepout\r\n");
BAT1_HIGH();
RED_LOW();
}
好像也没有AI说的哪些错误啊 初始化在TSCTRL的B7为1时已经完成初始化,在进入睡眠前已经将TSGO置0, 用的内部32K, 先不管其他IO口功耗问题,都是按照示例写的 无法唤醒 mppqgqha 发表于 2026-6-12 09:50
u8 i = 0;
EAXSFR(); /* 扩展寄存器访问使能 */
可能需要调整中断配置
设置对应唤醒逻辑 狂热主宰 发表于 2026-6-12 11:03
可能需要调整中断配置
设置对应唤醒逻辑
跳转到13号中断,唤醒逻辑指的什么,触摸小于阀值就唤醒,需要什么逻辑
上电后要先做10次以上触摸转换,将此时的读数(最好是平均值或低通滤波值)作为0点值,再写入唤醒值。
举例:
键按下后读数变化(减小量)为1600。
上电后连续读32次取平均值,假设为20000。
则唤醒值TSTH12 = 20000 - 1600/2; //唤醒值取0点值-变化量/2
程序要有缓慢的零点跟踪,睡眠前写入TSTH12。
梁工 发表于 2026-6-12 11:19
上电后要先做10次以上触摸转换,将此时的读数(最好是平均值或低通滤波值)作为0点值,再写入唤醒值。
举 ...
可能需要定时校准零点
多久比较合适 狂热主宰 发表于 2026-6-12 12:01
可能需要定时校准零点
多久比较合适
缓慢跟随即可,比如100ms间隔+-1.
页:
[1]
2