- 打卡等级:偶尔看看I
- 打卡总天数:10
- 最近打卡:2025-06-27 13:45:29
已绑定手机
注册会员
- 积分
- 170
|
用STC8H1K08T做了个触摸唤醒显示的模块
我该怎么更改程序,让系统自动去更新零点呢?
以下是程序,逻辑是:上电初始化零点后显示,N秒后关闭显示屏单片机进入睡眠,手指触摸后唤醒单片机重新显示。
#define yuzhi 900
u16 xdata TK_cnt[16]; // 按键计数值, 16位
u16 xdata TK_zero[16]; // 按键0点值, 16位
u16 KeyState; // 按键状态, 每个bit对应一个键, 1为按下, 0为释放
bit B_KeyPress=1;
void main (void)
{
u8 i=0;
u8 count1 = 0;
u8 count2 = 0;
u8 temp=0;
u8 flag=1;
u32 PowerOnTime=0;
ADC_NTCInit();
TouchKey_Init();
// USER_ISPInit();
LED_Init();
//ADC 触摸按键等GPIO初始化
P1M0 = 0x40; P1M1 = 0x30; //P1.4高阻 P1.5高阻 P1.6推挽
display_single_digit(0,0,0);
while(1)
{
if(B_KeyPress==1)
{
TSCTRL = (1<<3) + (1<<2) + 0;
//关闭触摸模块, 允许16位数字比较器, 允许低功耗唤醒。
//B7: TSGO, B6: SINGLE, B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
//0000 1100
TR0 = 1;
ET0 = 1;
ADC_ON;
delay_ms(10);
temp=(u8)NTC_Temperature();
count1=(u8)(temp/10%10);
count2=(u8)(temp%10);
delay_ms(10);
display_single_digit(0,count2,1);
display_single_digit(1,count1,0);
delay_ms(10);
ADC_OFF;
B_KeyPress=0;
flag=0;
}
// for(i=0; i<10; i++) //扫描10次键, 将此值作为未触摸时的0点, 要求上电时不要触摸按键
// {
//// TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, 4次平均
// TSCTRL = (1<<7) + (1<<6); //开始扫描, 无平均 1100 0000
//// delay_ms(1); //延时一下, 等待扫描完成
// }
//
// TK_zero[4] = TK_cnt[4]; //保存0点
// TSTH04 = TK_zero[4] - yuzhi/2; //设置唤醒门槛值 = 0点(未触摸)值 - 触摸变化值/2
//
PowerOnTime++;
delay_ms(1);
// TSTH04 = TSDAT - 10000/2; //设置唤醒门槛值 = 0点(未触摸)值 - 触摸变化值/2
if(PowerOnTime>=1000)
{
//TSCTRL=00001100
// TSCTRL = (1<<3) + (1<<2) + 0; //关闭触摸模块, 允许16位数字比较器, 允许低功耗唤醒。 B7: TSGO, B6: SINGLE, B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
TR0 = 0; //先关闭数码管定时器,再配置高阻
ET0 = 0;
P1M0 = 0x00; P1M1 = 0x20; //P15配置为高阻模式 并置为0
P3M0 = 0x7c; P3M1 = 0x00; //P32 P33 P34 P35 P36配置为推挽输出,并置为0
P5M0 = 0x00; P5M1 = 0x00;
// P15=1; //不能拉低,不然电池会往里面灌电流
P32=0;P33=0;P34=0;P35=0;P36=0;
ADC_CONTR=0x7f; //关闭ADC电源
_nop_();
_nop_();
PCON |= 0x02; //睡眠
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
// delay_ms(20); //消抖
//初始化一下触摸按键 ADC等GPIO
P1M0 = 0x40; P1M1 = 0x30; //P1.4高阻 P1.5高阻 P1.6推挽
ADC_CONTR = 0x85; //唤醒后需要重新使能一下ADC转换
// TSCHEN1 = 0x10; //唤醒后重新使能一下触摸按键
// TSCHEN2 = 0x00;
// TR0 = 1;
// ET0 = 1;
flag=1;
PowerOnTime=0;
// TR0 = 1;
// ET0 = 1;
//
TSCTRL = (1<<7) + (1<<3) + (1<<2) + 0;
//开始扫描, 无平均,
// B7: TSGO, B6: SINGLE, B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
//1000 1100
}
}
}
void TouchKey_Init(void)
{
u8 i;
P_SW2 |= 0x80; //允许访问扩展寄存器xsfr
// P1M0 = 0x00; P1M1 = 0x10; //P1.4为高阻
// 开启触摸按键功能
TSCHEN1 = 0x10; //使能触摸按键
TSCHEN2 = 0x00; //
TSCFG1 = (5<<4) + 3; //B6~B4:开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), B2~B0:放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最好大于等于3(1000)
//0111 0110
TSCFG2 = 0x00; // 配置触摸按键控制器的内部参考电压(AVCC的分压比)
//3/4AVCC
TSRT = 0x00; //没有LED分时扫描
TSWUTC =55; //1ms扫描一次 唤醒频率 = F32K/(32*8*TSWUTC[7:0]) = 128/TSWUTC[7:0] Hz, TSWUTC = 1~255
IE2 |= 0x80; //允许触摸按键中断
EA = 1; //允许全局中断
IRC32KCR = 0x80; //启用内部时钟32K IRC
while (!(IRC32KCR & 1)); //等待时钟稳定
delay_ms(10); //延时一下
for(i=0; i<10; i++) //扫描10次键, 将此值作为未触摸时的0点, 要求上电时不要触摸按键
{
// TSCTRL = (1<<7) + (1<<6) +3; //开始扫描, 4次平均
TSCTRL = (1<<7) + (1<<6); //开始扫描, 无平均 1100 0000
delay_ms(20); //延时一下, 等待扫描完成
}
TK_zero[4] = TK_cnt[4]; //保存0点
TSTH04 = TK_zero[4] - yuzhi/2; //设置唤醒门槛值 = 0点(未触摸)值 - 触摸变化值/2
WakeUpkey = 0;
// B_KeyPress = 0;
}
//========================================================================
// 函数: void TKSU_ISR(void) interrupt TKSU_VECTOR
// 描述: 触摸按键中断服务函数 扫描完成后或者数据溢出后进入本次中断
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2025-10-11
// 备注:
void TKSU_ISR(void) interrupt TKSU_VECTOR
{
u8 j;
j = TSSTA2; //触摸按键状态寄存器
if(j & 0x40) //数据溢出, 错误处理(略)
{
TSSTA2 |= 0x40; //写1清零
}
if(j & 0x80) //扫描完成 判断 TSIF位
{
TSSTA2 |= 0x80; //写1清零
j &= 0x0f;
WakeUpkey = j;
B_KeyPress = 1;
TK_cnt[j] = TSDAT; //保存某个通道的读数
}
}
|
|