找回密码
 立即注册
查看: 127|回复: 3

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

[复制链接]
  • TA的每日心情
    开心
    5 小时前
  • 签到天数: 169 天

    [LV.7]常住居民III

    67

    主题

    852

    回帖

    2856

    积分

    金牌会员

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

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

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

    25.98 KB, 下载次数: 1

    回复 送花

    使用道具 举报

    该用户从未签到

    551

    主题

    9427

    回帖

    1万

    积分

    管理员

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

    使用道具 举报

  • TA的每日心情
    开心
    5 小时前
  • 签到天数: 169 天

    [LV.7]常住居民III

    67

    主题

    852

    回帖

    2856

    积分

    金牌会员

    积分
    2856
     楼主| 发表于 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. }
    复制代码

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 小时前
  • 签到天数: 169 天

    [LV.7]常住居民III

    67

    主题

    852

    回帖

    2856

    积分

    金牌会员

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

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

    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-14 12:56 , Processed in 0.079741 second(s), 43 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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