找回密码
 立即注册
查看: 1952|回复: 28

使用触控的同时,可以开启ADC中断吗?(已解决)

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:578
  • 最近打卡:2025-06-28 14:10:41

116

主题

2038

回帖

5889

积分

论坛元老

积分
5889
发表于 2023-12-31 15:25:43 | 显示全部楼层 |阅读模式
本帖最后由 xxkj2010 于 2023-12-31 15:47 编辑

单片机用STC8H1K17T,使用触控功能后开启ADC中断,则发现触摸失效,不知道触控中断是否与ADC中断是否冲突?

开启ADC中断导致触控失效.rar

25.98 KB, 下载次数: 124

回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:111
  • 最近打卡:2025-06-28 08:54:08

740

主题

1万

回帖

1万

积分

管理员

积分
17146
发表于 2023-12-31 15:29:03 | 显示全部楼层
ADC 和 触摸 是各自独立的
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:578
  • 最近打卡:2025-06-28 14:10:41

116

主题

2038

回帖

5889

积分

论坛元老

积分
5889
发表于 2023-12-31 15:34:14 | 显示全部楼层
  1. /*
  2. 单片机:STC8H1K17T
  3. 使用触摸引脚:TK3、TK6、TK7
  4. */
  5. #include        "STC8Hxxx.h"
  6. #include <intrins.h>
  7. #include <stdio.h>
  8. /*************        功能说明        *************
  9. 读取16个触摸按键
  10. 触摸按键的读数本来是16位的, 由于使用了滤波算法, 滤波后数据为14位的.
  11. 参考电容的选取, 未按键时读数是满量程的1/3~1/2比较好, 兼顾灵敏度, 量产时又允许一定的平偏差.
  12. 程序会做缓慢的0点跟踪, 所以本例不合适长按处理, 长按处理还要有别的算法.
  13. P1.0-->TK0,  P1.1-->TK1, P5.4-->TK2, P1.3-->TK3, P1.4-->TK4,  P1.5-->TK5, P1.6-->TK6, P1.7-->TK7,
  14. P5.0-->TK8,  P5.1-->TK9, P5.2-->TK1, P5.3-->TK1, P0.0-->TK1,  P0.1-->TK1, P0.2-->TK1, P0.3-->TK1,
  15. ******************************************/
  16. /*************        本地常量声明        **************/
  17. #define        DIS_BLACK        0x1A
  18. #define        DIS_                0x1B
  19. #define LED P54            //LED
  20. #define ws2812b_IO    P35      //WS2812信号输入口
  21. #define MAIN_Fosc            24000000L        //定义主时钟 11059200
  22. #define BAUD        (65536 - MAIN_Fosc/4/115200)     //定义串口波特率重装值
  23. bit fBusy;                                     //串口发送忙标志
  24. u16 AUXR_ISR_YN=0;
  25. /*************        本地变量声明        **************/
  26. u16        xdata TK_cnt[16];        // 键计数值
  27. u16        xdata TK_zero[16];        // 0点读数
  28. u16        KeyState;                //键状态
  29. u8        KeyCode;                //键码 1~16
  30. bit        B_TK_Lowpass;        //允许低通
  31. bit        B_ReadKeyOk;        //标志已转换完成16个键
  32. u8        TrigLimit;                //触发转换限时
  33. u8        KeyValue;                //显示参数的键号, 0~15
  34. u8        read_cnt;
  35. u8 ADCval;                                    //ADC测量结果
  36. /*************        本地函数声明        **************/
  37. void  delay_ms(u8 ms);
  38. u8                CheckKey(u16 j);
  39. /****************  外部函数声明和外部变量声明 *****************/
  40.         u16 code T_KeyState[16]   = {0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};
  41. //        u16 code T_KeyPress[16]   = {400,300,200,200, 400,300,200,200, 400,300,200,200, 400,300,200,200};        //读数无平均, 这个值是各键触摸后的变化值, 由于分布电容不同, 所以各键读数变化量不同
  42.         u16 code T_KeyPress[16]   = {200,150,100,100, 200,150,100,100, 200,150,100,100, 200,150,100,100};        //读数有平均, 这个值是各键触摸后的变化值, 由于分布电容不同, 所以各键读数变化量不同
  43. /**********************************************/
  44. void main(void)
  45. {
  46.         u8        i;
  47.         u16        j;
  48.                 fBusy = 0;
  49.         P_SW2 |= 0x80;        //允许访问XSFR(扩展特殊功能寄存器)
  50. //        XOSCCR = 0xc0;           //启动外部晶振
  51. //        while (!(XOSCCR & 1));   //等待时钟稳定
  52. //        CLKDIV = 0x00;           //时钟不分频
  53. //        CKSEL = 0x01;            //选择外部晶振
  54.         P0M0 = 0x00;        P0M1 = 0x00;
  55. //        P1M0 = 0x00;        P1M1 = 0x00;
  56. //        P3M0 = 0x00; P3M1 = 0x00;
  57.         P5M0 = 0x10; P5M1 = 0x00;        
  58.     P3M0 = 0x00; P3M1 = 0x08;                  //设置P33为ADC输入口
  59.     ADCTIM = 0x3f;                              //设置ADC内部时序
  60.     P_SW2 &= 0x7f;
  61.     ADCCFG = 0x0f;                              //设置ADC时钟为系统时钟/2/16
  62.     ADC_CONTR = 0x8B;                      //开启ADC电源,选择第11通道ADC
  63.     EADC = 1;                                   //使能ADC中断
  64. //    EA = 1;
  65.     ADC_CONTR |= 0x40;                          //启动AD转换
  66.                
  67.                
  68.     AUXR = 0x40;                                //使用定时器1作为串口波特率发生器
  69.     TMOD = 0x00;
  70.     TL1 = BAUD;
  71.     TH1 = BAUD >> 8;
  72.     TR1 = 1;
  73.     SCON = 0x50;
  74.     ES = 1;
  75.        
  76.         P1n_pure_input(0xff);        //Touch Key设置为高阻
  77. //        TSCHEN = 0xffff;        //TK0~TK15
  78.         TSCHEN1 = 0xff;                //TK0~TK7
  79. //        TSCHEN2 = 0xff;                //TK8~TK15
  80.         TSCFG1  = (7<<4) + 6;        //开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
  81.         TSCFG2  = 1;                //配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4)  1(1/2)  2(5/8)  3(3/4)
  82. //        TSCTRL = (1<<7) + (1<<6) +3;        //开始扫描, B7: TSGO,  B6: SINGLE,  B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
  83. //        TSRT = 0x00;                //没有LED分时扫描
  84.         IE2 |= 0x80;                //允许触摸按键中断
  85.         EA = 1;
  86.         delay_ms(50);
  87. //        B_TK_Lowpass = 0;        //禁止低通滤波
  88.         B_TK_Lowpass = 1;        //允许低通滤波
  89.         for(read_cnt=0; read_cnt<40; read_cnt++)                //读40次键, 将此值作为未触摸时的0点, 要求上电时不要触摸按键
  90.         {
  91.         //        TSCTRL = (1<<7) + (1<<6) +3;        //开始扫描, 4次平均, 读数大约为无平均的一半
  92.                 TSCTRL = (1<<7) + (1<<6) +1;        //开始扫描, 2次平均, 读数大约为无平均的一半
  93.         //        TSCTRL = (1<<7) + (1<<6);                //开始扫描, 只转换1次, 无平均
  94.                 B_ReadKeyOk = 0;
  95.                 for(i=0; i<100; i++)
  96.                 {
  97.                         if(B_ReadKeyOk)        break;
  98.                         delay_ms(1);
  99.                 }
  100.         }
  101.         for(i=0; i<16; i++)                TK_zero[i] = TK_cnt[i];        //保存0点
  102.        
  103.         B_TK_Lowpass = 1;        //允许低通
  104.         KeyState = 0;
  105.         read_cnt = 0;
  106.        
  107.         B_ReadKeyOk = 0;
  108.         KeyValue = 10;
  109.         KeyCode = 0;
  110.         delay_ms(2000);
  111.         printf("开始测试----\r\n");
  112.         while (1)
  113.         {
  114.                 delay_ms(1);
  115.                 if(AUXR_ISR_YN){printf("AUXR_ISR_YN=%d\r\n",AUXR_ISR_YN);AUXR_ISR_YN=0;}
  116.                 if(++TrigLimit >= 100)        //触发转换
  117.                 {
  118.                         TrigLimit = 0;
  119.                 //        TSCTRL = (1<<7) + (1<<6) +3;        //开始扫描, 4次平均, 读数大约为无平均的一半
  120.                         TSCTRL = (1<<7) + (1<<6) +1;        //开始扫描, 2次平均, 读数大约为无平均的一半
  121.                 //        TSCTRL = (1<<7) + (1<<6);                //开始扫描, 只转换1次, 无平均
  122.                 }
  123.                
  124.                 if(B_ReadKeyOk)                        // 16个键都转换完毕
  125.                 {
  126.                         B_ReadKeyOk = 0;
  127.                         TrigLimit = 100;
  128.                         //printf("B_ReadKeyOk!\r\n");
  129.                         j = KeyState;                //读入上一次键状态
  130.                         for(i=0; i<8; i++)
  131.                         {
  132.                                 if(TK_zero[i] > TK_cnt[i])        //计算与0点的差值
  133.                                 {
  134.                                         TK_zero[i]--;        //缓慢0点跟随
  135.                                         if((TK_zero[i] - TK_cnt[i]) >= T_KeyPress[i]/2)       
  136.                                                 KeyState |=  T_KeyState[i];        // 大于按键读数变量的1/2就是按下
  137.                                         else if((TK_zero[i] - TK_cnt[i]) <= T_KeyPress[i]/3)       
  138.                                                 KeyState &= ~T_KeyState[i];        // 小于按键读数变量的1/3就是释放
  139.                                 }
  140.                                 else
  141.                                 {
  142.                                         KeyState &= ~T_KeyState[i];
  143.                                         if((TK_cnt[i] - TK_zero[i]) > 100)       
  144.                                                 TK_zero[i] += 50;        //差别很大, 则快速回0点
  145.                                         else                        TK_zero[i] += 10;        //差别不大, 则慢速回0点
  146.                                 }
  147.                         }
  148.                         j = (j ^ KeyState) & KeyState;        //检测键是否按下
  149.                         if(j != 0)
  150.                         {
  151.                                 KeyCode = CheckKey(j);        //计算键码 1~8                               
  152.                                 printf("KeyCode:%d\r\n",(u16)KeyCode);
  153.                                 if(KeyCode == 4)
  154.                                 {
  155.                                         LED=!LED;
  156.                                         printf("ADC:0x%x\r\n",(u16)ADCval);
  157.                                 }
  158.                         }
  159.                 }
  160.         }
  161. }
  162. /**********************************************/
  163.   
  164. void  delay_ms(u8 ms)
  165. {
  166.         u16 i;
  167.         do
  168.         {
  169.                 i = MAIN_Fosc / 10000;
  170.                 while(--i)        ;
  171.         }while(--ms);
  172. }
  173. /****************** 检测 计算键码 **************************************/
  174. u8        CheckKey(u16 j)
  175. {
  176.         u8 i;
  177.         if(j == 0)        return 0;        //无键按下
  178.         for(i=0; i<8; i++)
  179.         {
  180.                 if(j & 0x0001)        break;
  181.                 j >>= 1;
  182.         }
  183.         return (i+1);        //键码1~8
  184. }
  185. u8        isr_index;
  186. void        AUXR_ISR(void) interrupt 13
  187. {
  188.         u8        j;
  189.        
  190.         switch(isr_index)
  191.         {
  192.                 case 32:                //0103H 波形发生器5 中断入口
  193.                                                 //用户中断处理代码
  194.                 break;
  195.                 case 33:                //010BH        波形发生器异常2 中断入口
  196.                                                 //用户中断处理代码
  197.                 break;
  198.                 case 34:                //0113H        波形发生器异常4 中断入口
  199.                                                 //用户中断处理代码
  200.                 break;
  201.                 case 35:                //011BH        触摸按键 中断入口
  202.                                                 //用户中断处理代码
  203.                         j = TSSTA2;
  204.                         if(j & 0x40)        //数据溢出, 错误处理(略)
  205.                         {
  206.                                 TSSTA2 |= 0x40;        //写1清零                               
  207.                         }
  208.                         if(j & 0x80)        //扫描完成
  209.                         {
  210.                                
  211.                                 j &= 0x0f;
  212.                                 TSSTA2 |= 0x80;        //写1清零
  213.                                 if(!B_TK_Lowpass)        TK_cnt[j] = TSDAT/4;        //保存某个通道的读数        无低通滤波
  214.                                 else        TK_cnt[j] = ((TK_cnt[j] * 3)>>2) + TSDAT/16;        //保存某个通道的读数        低通滤波
  215.                                 if(j == 7)        {B_ReadKeyOk = 1;        //读完一次循环
  216.                                         }
  217.                         }
  218.                 break;
  219.                 case 36:                //0123H        RTC 中断入口
  220.                                                 //用户中断处理代码
  221.                 break;
  222.                 case 37:                //012BH        P0口中断入口
  223.                                                 //用户中断处理代码
  224.                 break;
  225.                 case 38:                //0133H        P1口中断入口
  226.                                                 //用户中断处理代码
  227.                 break;
  228.                 case 39:                //013BH        P2口中断入口
  229.                                                 //用户中断处理代码
  230.                 break;
  231.                 case 40:                //0143H        P3口中断入口
  232.                                                 //用户中断处理代码
  233.                 break;
  234.                 case 41:                //014BH        P4口中断入口
  235.                                                 //用户中断处理代码
  236.                 break;
  237.                 case 42:                //0153H        P5口中断入口
  238.                                                 //用户中断处理代码
  239.                 break;
  240.                 case 43:                //015BH        P6口中断入口
  241.                                                 //用户中断处理代码
  242.                 break;
  243.                 case 44:                //0163H        P7口中断入口
  244.                                                 //用户中断处理代码
  245.                 break;
  246.                 case 45:                //016BH        P8口中断入口
  247.                                                 //用户中断处理代码
  248.                 break;
  249.                 case 46:                //0173H        P9口中断入口
  250.                                                 //用户中断处理代码
  251.                 break;
  252.                
  253.                 default:
  254.                 break;
  255.         }
  256. }
  257. void uart_isr() interrupt 4
  258. {
  259.     if (TI)
  260.     {
  261.         TI = 0;
  262.         fBusy = 0;
  263.     }
  264.    
  265.     if (RI)
  266.     {
  267.         RI = 0;
  268. //        CheckCustomCmd(SBUF);                   //检测命令序列
  269.     }
  270. }
  271. void ADC_Isr() interrupt 5
  272. {
  273.     ADC_CONTR &= ~0x20;                         //清中断标志
  274.     ADCval = ADC_RES;                               //读取ADC结果       
  275.     ADC_CONTR |= 0x40;                          //继续AD转换
  276. }
  277. char putchar(char dat)                          //重定义putchar系统函数
  278. {
  279.     while (fBusy);
  280.     fBusy = 1;
  281.     SBUF = dat;   
  282.     return dat;
  283. }
复制代码

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:578
  • 最近打卡:2025-06-28 14:10:41

116

主题

2038

回帖

5889

积分

论坛元老

积分
5889
发表于 2023-12-31 15:46:42 | 显示全部楼层
本帖最后由 xxkj2010 于 2023-12-31 15:47 编辑

哦,找到问题所在了。
是因为没有注释掉ADC例程中的P_SW2 &= 0x7f;
截图202312311546339429.jpg

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2024-11-20 08:30:47

0

主题

14

回帖

64

积分

注册会员

积分
64
发表于 2024-7-2 16:18:08 | 显示全部楼层
xxkj*** 发表于 2023-12-31 15:46
哦,找到问题所在了。
是因为没有注释掉ADC例程中的P_SW2 &= 0x7f;

有没有修改好的程序,固件,发一下,我也是测试触摸键失败
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:578
  • 最近打卡:2025-06-28 14:10:41

116

主题

2038

回帖

5889

积分

论坛元老

积分
5889
发表于 2024-7-2 19:15:36 | 显示全部楼层
love*** 发表于 2024-7-2 16:18
有没有修改好的程序,固件,发一下,我也是测试触摸键失败

这个试试,我是亲测过好用的。

触摸功能测试(用例程16个触摸按键16个灯-8个共阴-8个共阳数码管显示修改).rar

53.44 KB, 下载次数: 129

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:578
  • 最近打卡:2025-06-28 14:10:41

116

主题

2038

回帖

5889

积分

论坛元老

积分
5889
发表于 2024-7-2 19:16:38 | 显示全部楼层
love*** 发表于 2024-7-2 16:18
有没有修改好的程序,固件,发一下,我也是测试触摸键失败

经过测试对比,STC的触摸功能是最容易用的。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2024-11-20 08:30:47

0

主题

14

回帖

64

积分

注册会员

积分
64
发表于 2024-7-3 08:06:19 | 显示全部楼层
xxkj*** 发表于 2024-7-2 19:15
这个试试,我是亲测过好用的。

谢谢大神
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2024-11-20 08:30:47

0

主题

14

回帖

64

积分

注册会员

积分
64
发表于 2024-7-3 08:09:46 | 显示全部楼层
本帖最后由 lovelong 于 2024-7-3 08:46 编辑

  • 单片机:STC8H1K17T
把程序刷进去,测试,都没有反应
使用P5.4===TK2,,,P3.3---TK11这两个端口做为触摸键。。。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:578
  • 最近打卡:2025-06-28 14:10:41

116

主题

2038

回帖

5889

积分

论坛元老

积分
5889
发表于 2024-7-3 11:21:49 | 显示全部楼层
本帖最后由 xxkj2010 于 2024-7-3 11:24 编辑
love*** 发表于 2024-7-3 08:09单片机:STC8H1K17T
把程序刷进去,测试,都没有反应
使用P5.4===TK2,,,P3.3---TK11这两个端口做为触摸 ...

你的PCB设计有问题吗?
有关PCB设计,我当前也请教了论坛大神
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=5778

回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-28 21:39 , Processed in 0.351314 second(s), 105 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表