way 发表于 2024-7-9 15:03:18

STC8H1K08T-触摸按键无法进入中断,读不到到按键值 | 已解决

#include <intrins.h>
#include "config.h"
#include "touch.h"

u16      xdata TK_cnt;      // 键计数值
u32      xdata TK_zero;      // 0点读数
u16 T_KeyCmp ;
bit      B_ReadKeyOk;      //标志已转换完成16个键
u16 Count ;
u16 LastState = 0;                                                //8位变量         b0=1,代表k0上一次按下过

voiddelay_ms(u8 ms)
{
      u16 i;
      do
      {
                i = MAIN_Fosc / 10000;
                while(--i)      ;
      }while(--ms);
}

void KEY_T_Init(void)
{
      u8 i,j;
      P_SW2 |= 0x80;
      P1n_pure_input(0xf8);      //P1.3.4.5.6.7 Touch Key设置为高阻
      P5n_pure_input(0x10);      //P5.4 Touch Key设置为高阻、
      
      P1IE &= 0x07;                        //P1.3.4.5.6.7 禁止触摸按键的数字输入
      P5IE &= 0xef;                        //P5.4禁止触摸按键的数字输入

      TSRT = 0x00;                //没有LED分时扫描
      TSCHEN1 = 0xfc;//0xfc;      //开TK02~TK07
//      TSCHEN2 = 0x00;      //关TK08~TK15
//      TSCFG1= (7<<4) + 3;      //开关电容工作频率 = fosc/(2*(TSCFG1+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
//      TSCFG2= 2;                              //配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4)1(1/2)2(5/8)3(3/4)
      TSCFG1= (3<<4) + 6;      //开关电容工作频率 = fosc/(2*(TSCFG1+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
      TSCFG2= 1;//配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4)1(1/2)2(5/8)3(3/4)
      TSCTRL = 0xA0; //0xA0;                        //开始自动扫描, 无平均, B7: TSGO,B6: SINGLE,B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
      //      TSCTRL = (1<<7) + (1<<6);      //开始单次扫描, 无平均
      //      TSCTRL = (1<<7) + (1<<6)+3;      //开始单次扫描, 4次平均
      //      TSCTRL = (1<<7) + (1<<6)+1;      //开始单次扫描, 2次平均
      //      TSWUTC = 12;                //100ms唤醒一次
      IE2 |= 0x80;                        //使能触摸中断
      EA = 1;

//      TSCTRL = 0xA0;

      delay_ms(100);
      for(i=0;i<KEY_Num;i++)
                TK_zero=0;      
               
      while(j<8)
      {
                if( B_ReadKeyOk )
                {
                        for(i=0;i<KEY_Num;i++)
                              TK_zero += TK_cnt;
                        B_ReadKeyOk = 0;
                        j++;
                }
                delay_ms(50);
      }
      for(i=0;i<KEY_Num;i++)
      {
                TK_zero=(TK_zero>>3);
                //      printf("%u\t",(u16)TK_zero);
                T_KeyCmp = 4500;
      }
}

//========================================================================
// 函数名称: KEY_Deal
// 函数功能: 按键状态读取
// 入口参数: 无
// 函数返回: 无
// 当前版本: VER1.0
// 修改日期: 2023 - 1-1
// 当前作者:
// 其他备注:循环读取八个端口的状态,并将按下的时间赋值给 Count 数组,按下的状态赋值给LastState
//========================================================================
void KEY_Deal(void)                        //检查所有的按键状态 10ms执行一次
{
      u8 i = 0;
//    printf("(%u,%u,%u)\r\n",(u16)TK_cnt,(u16)TK_cnt,(u16)TK_cnt);
      for(i=0;i<KEY_Num;i++)                                        //循环8次 i的取值范围是0-7代表了P30-P37的状态查询
      {
                if( TK_cnt< (TK_zero-T_KeyCmp))                        //持续按下,变量+1
                {
                        if( Count<60000 )
                              Count ++;                        //按键按下,这个计数变量+1
                }
                else                                                      //按键松开了,变量清0
                {
                        if( Count>0 )                        //如果这个变量是按下过的
                        {
                              LastState |= (1<<i);      //这个变量相应的标志位置位
                        }
                        else
                        {
                              LastState &= ~(1<<i);      //这个变量相应的标志位清0
                        }
                        Count = 0;                              //按键按下,这个计数变量清0
                }
      }
}

//========================================================================
// 函数名称: KEY_ReadState
// 函数功能: 读取指定的按钮的状态
// 入口参数: @keynum : 按钮的端口号 例如P32端口,端口号就是2
// 函数返回: 看其他备注
// 当前版本: VER1.0
// 修改日期: 2023 - 1- 1
// 当前作者:
// 其他备注: 函数返回值如下
//      #define      KEY_NOPRESS                0                //按键未按下
//      #define      KEY_FILCKER                1                //消抖
//      #define      KEY_PRESS                2                //单击
//      #define      KEY_PRESSOVER      3                //单击结束
//      #define      KEY_LONGPRESS      4                //长按3秒
//      #define      KEY_LONGOVER      5                //长按结束
//      #define      KEY_RELAX                6                //按键松开

//========================================================================

u8 KEY_ReadState(u8 keynum)      //读取指定的按键的状态 10ms执行一次
{
      if( Count>0 )                                        //按键是按下的各种状态返回
      {
                if( Count<3 )                              //按下<30ms 返回消抖状态
                {
                        return KEY_FILCKER;      //消抖
                }
                else if( Count==3 )                        //按下正好30ms 返回单击
                {
                        return KEY_PRESS;      //单击
                }
                else if( Count<150 )                //按下不到3000ms 返回单击结束
                {
                        return KEY_PRESSOVER;      //单击结束
                }               
                else if( Count==150 )                //按下正好3000ms 返回长按状态
                {
                        return KEY_LONGPRESS;      //长按3秒
                }      
                else                                                                //长按结束
                {
                        return KEY_LONGOVER;      //长按结束
                }
      }
      else                                                                        //按键已经松开了,返回各种状态
      {
                if( LastState &( 1<<keynum ) )                //按键之前按下过
                {
                        return KEY_RELAX;      //按键松开
                }
                else                                                                //按键之前没有按下
                {
                        return KEY_NOPRESS;      //按键未按下
                }
      }
}

//========================================================================
// 函数: void TKSU_Interrupt(void)
// 描述: 触摸按键中断。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2021-02-01
// 备注:
//========================================================================
void TKSU_Interrupt(void) interrupt 13
{
      u8      j;
      
                OUT_Bell=1; //位
      //      u8 intf=P0INTF;
                j = TSSTA2; //触摸状态
                if(j & 0x40)      //数据溢出, 错误处理(略)
                {
                        TSSTA2 |= 0x40;      //写1清零
                }
                if(j & 0x80)      //扫描完成
                {
                        j &= 0x0f;
                        TSSTA2 |= 0x80;      //写1清零
                        TK_cnt = TSDAT;      //保存某个通道的读数
                        if( j==7 ) //
                              B_ReadKeyOk=1;
                }
      //      if( intf )
      //      {
      //                P0INTF=0;
      //      }   
      
}

乘风飞扬 发表于 2024-7-9 15:49:14

你的触摸按键使用13号中断向量地址,那么地址跳转指令有添加到项目里吗?
void TKSU_Interrupt(void) interrupt 13
官方提供的例子一般使用"isr.asm"文件进行中断地址映射处理。

way 发表于 2024-7-9 15:56:40

乘风飞扬 发表于 2024-7-9 15:49
你的触摸按键使用13号中断向量地址,那么地址跳转指令有添加到项目里吗?
void TKSU_Interrupt(void) inter ...

应该没有,地址跳转指令怎么添加到项目里??

way 发表于 2024-7-9 16:02:56

way 发表于 2024-7-9 15:56
应该没有,地址跳转指令怎么添加到项目里??

或者有STC8H1K08T触摸按键程序,发个给我下载试试

32位8051-AI 发表于 2024-7-9 16:09:12

way 发表于 2024-7-9 16:02
或者有STC8H1K08T触摸按键程序,发个给我下载试试

https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=5717&pid=46196
参考这个帖子范例

way 发表于 2024-7-9 16:14:02

32位8051-STCAI 发表于 2024-7-9 16:09
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=5717&pid=46196
参考这个帖子范例 ...

添加isr.asm后,可以进入中断了,感谢支持!{:handshake:};现在调按键功能,不懂再发贴{:lol:}
页: [1]
查看完整版本: STC8H1K08T-触摸按键无法进入中断,读不到到按键值 | 已解决