数码之家

 找回密码
 立即注册
搜索
查看: 5065|回复: 12

STC8H单片机硬件触摸按键的简单实现(2)——代码分享

[复制链接]
发表于 2022-11-10 11:06:51 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 慕名而来 于 2022-11-10 12:48 编辑

昨天发帖:STC8H单片机硬件触摸按键的简单实现(1)——官方例程与配置软件https://www.mydigit.cn/thread-353279-1-1.html(出处: 数码之家),说了一下STC8H单片机硬件触摸按键编程的前期准备——查看串口数据、确定按键状态值,接下来完成这段应用程序。
长居本坛的朋友或许知道,我基本上只玩STC的51单片机,虽然也弄了十几年了,但经常只是做些时钟、万年历这些单片机地皮级的应用,C编程一直都是座门墩的水平始终没能登堂入室,很多时候都是在做用例程、改例程、简化例程的所谓编程,真的不会自己起头写代码,这段触摸按键代码也不例外,只是以最简单的代码实现了最基本的使用功能,因为应用模式为按键自动重复检测模式,所以,这段代码整合的其他工程里应用时是否会出现分时冲突还不知道,我也试图测试单次检测模式但没能实现,在此也希望高手指点。


  1. /**********************************************************************
  2. //如有转载请注明出处
  3. //代码原创:wannenggong 2022-11-10
  4. //单片机型号:STC8H4K64TL,电源电压3.3V,使用外接RX8025T-32768信号源做外部晶振
  5. //接线方式:P1.1口经1K电阻连接金属触摸片,P1.0口经470Ω电阻连接LED到正电源
  6. //触摸按键工作模式:自动重复扫描
  7. //实验目标:触摸按键时LED亮起,不触摸按键时LED熄灭
  8. ***********************************************************************/
  9. #include "STC8H.h" //包含了u8、u16、u32的定义
  10. #include <intrins.h>
  11. sbit wng_led=P1^0;

  12. //------------------------------------------
  13. void key_init()
  14. {
  15.     P_SW2 |= 0x80;                                //允许访问XFR
  16.     TSRT = 0x00;                                //不开启LED驱动分时功能
  17.     TSCHEN1 = 0x02;                                //仅使能TK01(P1.1)
  18.     TSCHEN2 = 0x00;                                //其他按键没有使用
  19.     TSCFG1  = (7<<4) + 3;                //开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
  20.     TSCFG2  = 2;                                //配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4)  1(1/2)  2(5/8)  3(3/4)
  21.         TSWUTC = 0x0c;                                //32768/(32*8*0x0c)=10Hz=100ms唤醒一次
  22.         TSCTRL = 0xB0;                                //使用外部晶振
  23. //        TSCTRL = 0xA0;                                //使用内部晶振
  24. //----TSCTRL寄存器详解如下--------------
  25. //B7:TSGO=1使能触摸按键
  26. //B6:SINGLE=1单次扫描模式、=0自动重复扫描
  27. //B5:TSWAIT=1完成一轮扫描后、TSIF 被硬件置 1,此时触摸按键控制器会暂停扫描,直到 TSIF 标志位被清 0后才开始下一轮的扫描
  28. //B4:TSWUCS=0使用内部32K晶振
  29. //B3:TSDCEN=0不使能16位比较器
  30. //B2:TSWUEN=1使能低功耗唤醒功能
  31. //B1B0:TSSAMP=11单次按键扫描4次
  32. //--------------------------------------
  33.     P_SW2 &= ~0x80;                   //禁止访问XFR
  34.     //IE2 |= 0x80;
  35. }
  36. //----键值读取函数--------------------
  37. u8 Read_Key_value(void)
  38. {
  39.     u8 j,wng_data;
  40.     u16 i, wng_value=0;
  41.     P_SW2 |= 0x80;               
  42.     for(i=0; i<100; i++)
  43.     {
  44.         j = TSSTA2;
  45.         if(j & 0x40)        //数据溢出
  46.         {
  47.             TSSTA2 |= 0x40; //写1清零
  48.             wng_value=0xee;        //返回错误码0xee
  49.         }

  50.         if(j & 0x80)        //扫描完成
  51.         {
  52.             TSSTA2 |= 0x80; //写1清零
  53.             wng_value=TSDAT;
  54.             wng_data=wng_value>>12;        //获取高8位数据的高4位用于判断
  55.         }
  56.     }
  57.     P_SW2 &= ~0x80;               

  58.     return (wng_data);
  59. }
  60. //----按键函数------------------------------
  61. void key01()
  62. {
  63.     u8 wng;
  64.     wng=Read_Key_value();
  65.     if(wng==0xee)
  66.         return;
  67.     else
  68.     {
  69.         if(wng<0x03)                //选取一个中值用来判断按键状态
  70.             wng_led=0;
  71.         else if(wng>0x03)
  72.             wng_led=1;
  73.     }

  74. }
  75. //------------------------------------------
  76. void main(void)
  77. {

  78.     P1M1=0x00;
  79.     P1M0=0x00;
  80.     P3M1=0x00;
  81.     P3M0=0x00;
  82.     P5M1=0x00;
  83.     P5M0=0x00;
  84.     key_init();
  85.     wng_led=1;
  86.     while(1)
  87.     {
  88.         key01();
  89.                
  90.     }
  91. }
复制代码




打赏

参与人数 1家元 +5 收起 理由
phoric + 5

查看全部打赏

发表于 2022-11-10 11:29:55 | 显示全部楼层
本帖最后由 zhang_yy007 于 2022-11-10 11:34 编辑

这个原理就是通过ADC读取电压变化  然后判断是否触摸吧  需要根据数据手册查看寄存器的配置是否够准确  这个自己慢慢研究一下就可以了你这水平不行呀,人家用的是内部时钟自动调用,你怕有影响加入中断调一下时序就可以了
回复 支持 反对

使用道具 举报

发表于 2022-11-10 11:31:06 | 显示全部楼层
谢谢分享,可以实现双击和单击吗?长按短按?
回复 支持 反对

使用道具 举报

发表于 2022-11-10 11:55:24 来自手机浏览器 | 显示全部楼层
zhang_yy007 发表于 2022-11-10 11:29
这个原理就是通过ADC读取电压变化  然后判断是否触摸吧  需要根据数据手册查看寄存器的配置是否够准确  这 ...

从框图看,这颗芯片用的是电荷搬移原理,检测的是搬移时间。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-10 12:02:28 | 显示全部楼层
zhang_yy007 发表于 2022-11-10 11:29
这个原理就是通过ADC读取电压变化  然后判断是否触摸吧  需要根据数据手册查看寄存器的配置是否够准确  这 ...

多谢指点,关于32786KHz时钟使用内部时钟还是外部时钟只是因为我用来测试代码的板子上已经集成了RX8025T所以最终就用外部时钟了,我这次实验没用到中断,有时间测试一下中断调整时序的方法。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-10 12:04:36 | 显示全部楼层
fsss007 发表于 2022-11-10 11:31
谢谢分享,可以实现双击和单击吗?长按短按?

只是实现了按键的基本功能,还没有进行其他测试,有兴趣的话可以玩一玩而后大家分享经验。
回复 支持 反对

使用道具 举报

发表于 2022-11-10 12:11:13 | 显示全部楼层
过来学习一下
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2022-11-10 15:48:15 | 显示全部楼层
谢谢楼主的分享,STC8H4K64TL芯片的外部RTC并且在TFT上显示,正常运行。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-19 12:16:00 | 显示全部楼层
本帖最后由 慕名而来 于 2022-11-19 12:27 编辑

一直在弄这个硬件触摸按键,但总是不能透彻,我真的想知道STC8H这个是怎样触发“触摸”中断的,或者说它究竟有没有“触摸触发中断的功能”,问题详见下图:




希望有了解STC触摸按键应用的朋友能够指点一下,先谢了!


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-19 12:21:05 | 显示全部楼层
慕名而来 发表于 2022-11-19 12:16
一直在弄这个硬件触摸按键,但总是不能透彻,我真的想知道STC8H这个是怎样触发“触摸”中断的,或者说它究 ...

下面是我参照的代码,也就是上一篇附近中的代码:

  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* --- Mobile: (86)13922805190 ----------------------------------------*/
  5. /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
  6. /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
  7. /* --- Web: www.STCMCU.com --------------------------------------------*/
  8. /* --- Web: www.STCMCUDATA.com  ---------------------------------------*/
  9. /* --- QQ:  800003751 -------------------------------------------------*/
  10. /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
  11. /*---------------------------------------------------------------------*/

  12. #include <intrins.h>
  13. #include "STC8Hxxxxx.h"

  14. /*************        功能说明        **************

  15. 通过串口(P3.0 P3.1)发送指令配置触摸按键, 以及获取触摸按键数值.

  16. P1.0(TK00)   P1.1(TK01)   P5.4(TK02)   P1.3(TK03)   P1.4(TK04)   P1.5(TK05)   P1.6(TK06)   P1.7(TK07)
  17. P5.0(TK08)   P5.1(TK09)   P5.2(TK10)   P5.3(TK11)   P0.0(TK12)   P0.1(TK13)   P0.2(TK14)   P0.3(TK15)

  18. 串口默认设置: 115200,N,8,1.

  19. 上电后先读键,将此时的读数作为零点.

  20. 下载时, 选择时钟 22.1184MHz (用户可自行修改频率).

  21. ******************************************/


  22. /*************        本地常量声明        **************/

  23. //不同型号芯片特殊参数在存储器中保存的地址不同,详情请参考规格书7.3章节
  24. #define ID_ROMADDR          ((unsigned char code *)0xfdf9)
  25. #define VREF_ROMADDR        (*(unsigned int code *)0xfdf7)
  26. #define F32K_ROMADDR        (*(unsigned int code *)0xfdf5)

  27. #define T22M_ROMADDR        (*(unsigned char code *)0xfdf4)  //22.1184MHz (27M频段)
  28. #define T24M_ROMADDR        (*(unsigned char code *)0xfdf3)  //24MHz (27M频段)
  29. #define T20M_ROMADDR        (*(unsigned char code *)0xfdf2)  //20MHz (27M频段)
  30. #define T27M_ROMADDR        (*(unsigned char code *)0xfdf1)  //27MHz (27M频段)
  31. #define T30M_ROMADDR        (*(unsigned char code *)0xfdf0)  //30MHz (27M频段)
  32. #define T33M_ROMADDR        (*(unsigned char code *)0xfdef)  //33MHz (27M频段)
  33. #define T35M_ROMADDR        (*(unsigned char code *)0xfdee)  //35MHz (44M频段)
  34. #define T36M_ROMADDR        (*(unsigned char code *)0xfded)  //36MHz (44M频段)
  35. #define T40M_ROMADDR        (*(unsigned char code *)0xfdec)  //40MHz (44M频段)
  36. #define VRT6M_ROMADDR       (*(unsigned char code *)0xfdea)  //VRTRIM_6MHz
  37. #define VRT10M_ROMADDR      (*(unsigned char code *)0xfde9)  //VRTRIM_10MHz
  38. #define VRT27M_ROMADDR      (*(unsigned char code *)0xfde8)  //VRTRIM_27MHz
  39. #define VRT44M_ROMADDR      (*(unsigned char code *)0xfde7)  //VRTRIM_44MHz

  40. #define Baudrate            115200L

  41. #define SYNC1                0x55
  42. #define SYNC2                0x54

  43. typedef enum
  44. {
  45.         CMD_SYNC1 = 0,/*0*/
  46.         CMD_SYNC2,                /*1*/
  47.         CMD_TYPE,                        /*2*/
  48.         CMD_TSCHEN1,        /*3*/
  49.         CMD_TSCHEN2,        /*4*/
  50.         CMD_TSCFG1,                /*5*/
  51.         CMD_TSCFG2,                /*6*/
  52.         CMD_TSCTRL,                /*7*/
  53.         CMD_TSRT,                        /*8*/
  54.         CMD_SFREQ1,                /*9*/
  55.         CMD_SFREQ2,                /*10*/
  56.         CMD_TSWUTC,                /*11*/

  57.         CMD_TSTH00H,
  58.         CMD_TSTH00L,
  59.         CMD_TSTH01H,
  60.         CMD_TSTH01L,
  61.         CMD_TSTH02H,
  62.         CMD_TSTH02L,
  63.         CMD_TSTH03H,
  64.         CMD_TSTH03L,
  65.         CMD_TSTH04H,
  66.         CMD_TSTH04L,
  67.         CMD_TSTH05H,
  68.         CMD_TSTH05L,
  69.         CMD_TSTH06H,
  70.         CMD_TSTH06L,
  71.         CMD_TSTH07H,
  72.         CMD_TSTH07L,
  73.         CMD_TSTH08H,
  74.         CMD_TSTH08L,
  75.         CMD_TSTH09H,
  76.         CMD_TSTH09L,
  77.         CMD_TSTH10H,
  78.         CMD_TSTH10L,
  79.         CMD_TSTH11H,
  80.         CMD_TSTH11L,
  81.         CMD_TSTH12H,
  82.         CMD_TSTH12L,
  83.         CMD_TSTH13H,
  84.         CMD_TSTH13L,
  85.         CMD_TSTH14H,
  86.         CMD_TSTH14L,
  87.         CMD_TSTH15H,
  88.         CMD_TSTH15L,

  89.         CMD_CS,
  90.         CMD_LEN,
  91. }CMD_IndexType;

  92. typedef enum
  93. {
  94.         IRC_500K = 0,                /*0*/
  95.         IRC_1M,
  96.         IRC_2M,
  97.         IRC_3M,
  98.         IRC_5M,
  99.         IRC_6M,
  100.         IRC_8M,
  101.         IRC_10M,
  102.         IRC_11M,
  103.         IRC_12M,
  104.         IRC_15M,
  105.         IRC_18M,
  106.         IRC_20M,
  107.         IRC_22M,
  108.         IRC_24M,
  109.         IRC_27M,
  110.         IRC_30M,
  111.         IRC_33M,
  112.         IRC_35M,
  113.         IRC_36M,
  114. }IRC_IndexType;

  115. /*************        IO口定义        **************/
  116. sbit        P_RUN_LED = P3^4;

  117. sbit        P_K0_LED  = P2^5;
  118. sbit        P_K1_LED  = P0^7;
  119. sbit        P_K2_LED  = P4^1;
  120. sbit        P_K3_LED  = P2^1;
  121. sbit        P_K4_LED  = P2^2;
  122. sbit        P_K5_LED  = P4^6;
  123. sbit        P_K6_LED  = P2^4;
  124. sbit        P_K7_LED  = P0^5;
  125. sbit        P_K8_LED  = P4^2;
  126. sbit        P_K9_LED  = P4^3;
  127. sbit        P_K10_LED = P2^3;
  128. sbit        P_K11_LED = P4^5;
  129. sbit        P_K12_LED = P2^0;
  130. sbit        P_K13_LED = P2^7;
  131. sbit        P_K14_LED = P2^6;
  132. sbit        P_K15_LED = P0^6;

  133. /*************        本地变量声明        **************/
  134. u8 CLK_ID = IRC_22M;
  135. u32 MAIN_Fosc =        22118400L;        //定义主时钟

  136. bit        B_TX1_Busy;                // 发送忙标志
  137. bit        B_Zero_Flag;
  138. bit B_1ms;        //1ms标志

  139. u16        ChannelSet;

  140. u8  TK_TimeOut;
  141. u8        read_cnt;
  142. u16        tpFlag;
  143. u16        JudgeFlag;

  144. u16        xdata TK_cnt[16];
  145. u16        xdata TK_zero[16];

  146. u16        xdata TK_differ[16];
  147. u16        xdata TK_lowest[16];

  148. u8        xdata Zero_Add_Cnt[16];
  149. u8        xdata Zero_Sub_Cnt[16];
  150. u8        xdata TK_counter[16];

  151. u8        xdata SendBuffer[CMD_LEN];
  152. u8  xdata RX1_Buffer[CMD_LEN];   //接收缓冲

  153. u8  RX1_TimeOut;
  154. u8  RX1_Cnt;    //接收计数
  155. u16 ScanFreq;   //扫描频次

  156.                //TP0   TP1   TP2  TP3  TP4  TP5  TP6  TP7   TP8  TP9   TP10 TP11 TP12 TP13 TP14 TP15                      差值 / 2
  157. u16 code DIFF[]={1100, 1400, 800, 600, 600, 850, 850, 1200, 850, 1000, 800, 900, 550, 600, 900, 1200};   //检测阈值=(未触摸值-触摸值)/2

  158. /*************        本地函数声明        **************/

  159. void        Timer0_init(u32 clk);
  160. void        UART1_config(u32 clk, u32 brt);        //clk: 系统主频 brt: 通信波特率
  161. void         UART1_PrintString(u8 *puts);
  162. void         UART1_TxByte(u8 dat);
  163. void  JudgeKey(u8 tkn);
  164. void        RX1_Check(void);
  165. void        ReadZeroData(void);
  166. u8 GetCheckSum(u8 *buf, u8 len);

  167. /****************  外部函数声明和外部变量声明 *****************/


  168. /******************** 主函数 **************************/
  169. void main(void)
  170. {
  171.         u8        i;
  172.        
  173.         P0M1 = 0x0f;   P0M0 = 0xe0;   //设置P0.0~P0.3为高阻输入; P0.5~P0.7为推挽输出
  174.         P1M1 = 0xff;   P1M0 = 0x00;   //设置为高阻输入
  175.         P2M1 = 0x00;   P2M0 = 0xff;   //设置为推挽输出
  176.         P3M1 = 0x00;   P3M0 = 0x10;   //设置P3.4为推挽输出
  177.         P4M1 = 0x00;   P4M0 = 0x6e;   //设置P4.1~P4.3,P4.5,P4.6为推挽输出
  178.         P5M1 = 0x0f;   P5M0 = 0x00;   //设置P5.0~P5.3为高阻输入

  179.         P_RUN_LED = 1;
  180.         P_K0_LED = 0;        P_K4_LED = 0;        P_K8_LED = 0;        P_K12_LED = 0;
  181.         P_K1_LED = 0;        P_K5_LED = 0;        P_K9_LED = 0;        P_K13_LED = 0;
  182.         P_K2_LED = 0;        P_K6_LED = 0;        P_K10_LED = 0;        P_K14_LED = 0;
  183.         P_K3_LED = 0;        P_K7_LED = 0;        P_K11_LED = 0;        P_K15_LED = 0;
  184.         Timer0_init(MAIN_Fosc/1000);        //Timer 0 中断频率, 1000次/秒

  185.         P_SW2 |= 0x80;        //允许访问XSF
  186. //        MCLKOCR = 0x02;        //从P5.4输出主频/2

  187.         TSRT = 0x00;                //没有LED分时扫描
  188.         TSCHEN1 = 0x46;        //TK00~TK07
  189.         TSCHEN2 = 0x00;        //TK08~TK15
  190.         TSCFG1  = 0x7f;//(7<<4) + 3;        //开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
  191.         TSCFG2  = 0x02;                                //配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4)  1(1/2)  2(5/8)  3(3/4)
  192.         TSCTRL = 0xA0;                        //开始自动扫描, 无平均, B7: TSGO,  B6: SINGLE,  B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
  193. //        TSCTRL = (1<<7) + (1<<6);        //开始单次扫描, 无平均
  194. //        TSCTRL = (1<<7) + (1<<6)+3;        //开始单次扫描, 4次平均
  195. //        TSCTRL = (1<<7) + (1<<6)+1;        //开始单次扫描, 2次平均
  196.         TSWUTC = 0;//12;                //100ms唤醒一次
  197.         IE2 |= 0x80;                        //使能触摸中断
  198. //        P_SW2 &= ~0x80;                //禁止访问xsf
  199.         UART1_config(MAIN_Fosc, Baudrate);
  200.         EA = 1;                //允许全局中断
  201.         UART1_PrintString("STC8H4K64Txx 触摸按键测试程序\r\n");

  202.         for(i=0; i<16; i++)
  203.         {
  204.                 TK_differ[i] = DIFF[i];          //设置初始差值
  205.                 TK_lowest[i] = DIFF[i]*3;        //设置初始下限值, 检测下限 = 阈值*3
  206.                 TK_counter[i] = 0;
  207.                 Zero_Sub_Cnt[i] = 0;
  208.                 Zero_Add_Cnt[i] = 0;
  209.         }
  210.         tpFlag = 0;
  211.         JudgeFlag = 0;
  212.         read_cnt=0;
  213.         TK_TimeOut = 0;
  214.         B_Zero_Flag = 1;
  215.         ChannelSet = ((u16)TSCHEN2 << 8) | TSCHEN1;

  216.         ScanFreq = 50;                //设置有效触摸按键持续检测时间
  217.         SendBuffer[0] = SYNC1;        //初始化同步头
  218.         SendBuffer[1] = SYNC2;

  219.         while (1)
  220.         {
  221.                 ReadZeroData();



  222. /*               
  223.                 if(B_1ms)
  224.                 {
  225.                         B_1ms = 0;

  226.                         for(i=0;i<16;i++)
  227.                         {
  228.                                 JudgeKey(i);        //判断键值
  229.                         }

  230.                         B = (u8)tpFlag;
  231.                         if(B0)        P_K0_LED = ~P_K0_LED;
  232.                         if(B1)        P_K1_LED = ~P_K1_LED;
  233.                         if(B2)        P_K2_LED = ~P_K2_LED;
  234.                         if(B3)        P_K3_LED = ~P_K3_LED;
  235.                         if(B4)        P_K4_LED = ~P_K4_LED;
  236.                         if(B5)        P_K5_LED = ~P_K5_LED;
  237.                         if(B6)        P_K6_LED = ~P_K6_LED;
  238.                         if(B7)        P_K7_LED = ~P_K7_LED;
  239.                         B = (u8)(tpFlag >> 8);
  240.                         if(B0)        P_K8_LED  = ~P_K8_LED;
  241.                         if(B1)        P_K9_LED  = ~P_K9_LED;
  242.                         if(B2)        P_K10_LED = ~P_K10_LED;
  243.                         if(B3)        P_K11_LED = ~P_K11_LED;
  244.                         if(B4)        P_K12_LED = ~P_K12_LED;
  245.                         if(B5)        P_K13_LED = ~P_K13_LED;
  246.                         if(B6)        P_K14_LED = ~P_K14_LED;
  247.                         if(B7)        P_K15_LED = ~P_K15_LED;

  248.                         tpFlag = 0;
  249.                        
  250.                         if(RX1_TimeOut > 0)
  251.                         {
  252.                                 if(--RX1_TimeOut == 0)  //超时,则串口接收结束
  253.                                 {
  254.                                         if(RX1_Cnt > 0)
  255.                                         {
  256.                                                 RX1_Check();    //处理串口1接收数据
  257.                                         }
  258.                                         RX1_Cnt = 0;
  259.                                 }
  260.                         }
  261.                 }


  262. */
  263. }
  264. }

  265. //========================================================================
  266. // 函数: void JudgeKey(u8 tkn)
  267. // 描述: 判断键值是否有效。
  268. // 参数: tkn: 按键序号.
  269. // 返回: none.
  270. // 版本: VER1.0
  271. // 日期: 2010-12-15
  272. // 备注:
  273. //========================================================================
  274. void JudgeKey(u8 tkn)
  275. {
  276.         if(tkn > 15) return;                //序号错误
  277.        
  278.         if(ChannelSet & (1<<tkn))
  279.         {
  280.                 if(TK_cnt[tkn] > TK_zero[tkn])
  281.                 {
  282.                         Zero_Sub_Cnt[tkn] = 0;
  283.                         if(Zero_Add_Cnt[tkn] < 10)
  284.                         {
  285.                                 Zero_Add_Cnt[tkn]++;
  286.                         }
  287.                         else
  288.                         {
  289.                                 TK_zero[tkn] += 1;                //零点追踪
  290.                         }
  291.                        
  292.                         if(TK_counter[tkn] > 0)
  293.                         {
  294.                                 TK_counter[tkn]--;
  295.                         }
  296.                         else
  297.                         {
  298.                                 JudgeFlag &= ~(1<<tkn);        //清除触摸标志
  299.                                 tpFlag &= ~(1<<tkn);        //清除触摸标志
  300.                         }
  301.                 }
  302.                 else if(TK_cnt[tkn] <= (TK_zero[tkn]-TK_differ[tkn]))        //判断键的阈值.
  303.                 {
  304.                         Zero_Sub_Cnt[tkn] = 0;
  305.                         Zero_Add_Cnt[tkn] = 0;
  306.                         if(TK_cnt[tkn] <= (TK_zero[tkn]-TK_lowest[tkn]))        //键值超过下限.
  307.                         {
  308.                                 //超出正常触摸值范围,判定为干扰输入
  309.                                 TK_counter[tkn] = 0;
  310.                         }
  311.                         else if((JudgeFlag & (1<<tkn)) == 0)
  312.                         {
  313.                                 TK_counter[tkn]++;
  314.                                 if(TK_counter[tkn] > ScanFreq)
  315.                                 {
  316.                                         JudgeFlag |= (1<<tkn);        //设置触摸标志
  317.                                         tpFlag |= (1<<tkn);
  318.                                 }
  319.                         }
  320.                 }
  321.                 else
  322.                 {
  323.                         Zero_Add_Cnt[tkn] = 0;
  324.                         if(Zero_Sub_Cnt[tkn] < 100 )        //延缓零点追踪
  325.                         {
  326.                                 Zero_Sub_Cnt[tkn]++;
  327.                         }
  328.                         else
  329.                         {
  330.                                 if(TK_cnt[tkn] < TK_zero[tkn])        //延缓零点追踪
  331.                                 {
  332.                                         TK_zero[tkn] -= 1;                //零点追踪
  333.                                         Zero_Sub_Cnt[tkn] = 0;
  334.                                 }
  335.                         }

  336.                         if(TK_counter[tkn] > 0)
  337.                         {
  338.                                 TK_counter[tkn]--;
  339.                         }
  340.                         else
  341.                         {
  342.                                 JudgeFlag &= ~(1<<tkn);        //清除触摸标志
  343.                                 tpFlag &= ~(1<<tkn);        //清除触摸标志
  344.                         }
  345.                 }
  346.         }
  347. }

  348. //========================================================================
  349. // 函数: void ReadZeroData(void)
  350. // 描述: 获取触摸按键的零值。
  351. // 参数: none.
  352. // 返回: none.
  353. // 版本: VER1.0
  354. // 日期: 2021-02-02
  355. // 备注:
  356. //========================================================================
  357. void ReadZeroData(void)
  358. {
  359.         u8 i;
  360.         if(B_Zero_Flag)
  361.         {
  362.                 TK_TimeOut++;
  363.                 if(TK_TimeOut > 250)        //扫描超时
  364.                 {
  365.                         TK_TimeOut = 0;
  366.                         read_cnt++;
  367.                 }
  368.                
  369.                 if(read_cnt > 100)
  370.                 {
  371.                         for(i=0; i<16; i++)
  372.                         {
  373.                                 TK_zero[i] = TK_cnt[i];        //保存0点
  374.                                 TK_counter[i] = 0;
  375.                         }
  376.                         B_Zero_Flag = 0;
  377.                 }
  378.         }
  379. }

  380. //========================================================================
  381. // 函数: void        UART1_config(u32 clk, u32 brt)
  382. // 描述: UART1初始化函数。
  383. // 参数: clk: 系统主频.
  384. //       brt: 通信波特率.
  385. // 返回: none.
  386. // 版本: VER1.0
  387. // 日期: 2021-7-29
  388. // 备注:
  389. //========================================================================
  390. void        UART1_config(u32 clk, u32 brt)
  391. {
  392.         brt = 65536UL - (clk / 4) / brt;
  393.         TR1 = 0;
  394.         AUXR &= ~0x01;                //S1 BRT Use Timer1;
  395.         AUXR |=  (1<<6);        //Timer1 set as 1T mode
  396.         TMOD &= ~(1<<6);        //Timer1 set As Timer
  397.         TMOD &= ~0x30;                //Timer1_16bitAutoReload;
  398.         TH1 = (u8)(brt >> 8);
  399.         TL1 = (u8)brt;
  400.         ET1 = 0;                        // 禁止Timer1中断
  401.         INTCLKO &= ~0x02;        // Timer1不输出高速时钟
  402.         TR1  = 1;                        // 运行Timer1

  403.         P_SW1 &= 0x3f;
  404.         P_SW1 |= 0x00;      //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4

  405.         SCON = (SCON & 0x3f) | (1<<6);        // 8位数据, 1位起始位, 1位停止位, 无校验
  406. //        PS  = 1;        //高优先级中断
  407.         ES  = 1;        //允许中断
  408.         REN = 1;        //允许接收

  409.         B_TX1_Busy = 0;
  410.         RX1_Cnt = 0;
  411. }

  412. //========================================================================
  413. // 函数: void UART1_TxByte(u8 dat)
  414. // 描述: 串口1发送一个字节函数
  415. // 参数: dat: 要发送的数据.
  416. // 返回: none.
  417. // 版本: VER1.0
  418. // 日期: 2018-4-2
  419. // 备注:
  420. //========================================================================
  421. void UART1_TxByte(u8 dat)
  422. {
  423.         B_TX1_Busy = 1;                        //标志发送忙
  424.         SBUF = dat;                                        //发一个字节
  425.         while(B_TX1_Busy);        //等待发送完成
  426. }

  427. //========================================================================
  428. // 函数: void UART1_PrintString(u8 *puts)
  429. // 描述: 串口1字符串打印函数
  430. // 参数: puts: 字符串指针.
  431. // 返回: none.
  432. // 版本: VER1.0
  433. // 日期: 2018-4-2
  434. // 备注:
  435. //========================================================================
  436. void UART1_PrintString(u8 *puts)
  437. {
  438.         for (; *puts != 0;        puts++)
  439.         {
  440.                 UART1_TxByte(*puts);
  441.         }
  442. }

  443. //========================================================================
  444. // 函数: void UART1_int (void) interrupt UART1_VECTOR
  445. // 描述: 串口1中断函数
  446. // 参数: none.
  447. // 返回: none.
  448. // 版本: VER1.0
  449. // 日期: 2018-4-2
  450. // 备注:
  451. //========================================================================
  452. void UART1_int (void) interrupt UART1_VECTOR
  453. {
  454.         if(RI)
  455.         {
  456.                 RI = 0;
  457.                 if(RX1_Cnt >= CMD_LEN) RX1_Cnt = 0;
  458.                 RX1_Buffer[RX1_Cnt] = SBUF;
  459.                 RX1_Cnt++;
  460.                 RX1_TimeOut = 5;
  461.         }

  462.         if(TI)
  463.         {
  464.                 TI = 0;
  465.                 B_TX1_Busy = 0;
  466.         }
  467. }

  468. //========================================================================
  469. // 函数: void Timer0_init(void)
  470. // 描述: timer0初始化函数.
  471. // 参数: none.
  472. // 返回: none.
  473. // 版本: V1.0, 2015-1-12
  474. //========================================================================
  475. void Timer0_init(u32 clk)
  476. {
  477.         TR0 = 0;    //停止计数

  478.         ET0 = 1;    //允许中断
  479. //  PT0 = 1;    //高优先级中断
  480.         TMOD &= ~0x03;
  481.         TMOD |= 0;  //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
  482. //  TMOD |=  0x04;  //对外计数或分频
  483.         TMOD &= ~0x04;  //定时
  484. //  INTCLKO |=  0x01;  //输出时钟
  485.         INTCLKO &= ~0x01;  //不输出时钟

  486.         if (clk < 65536UL)
  487.         {
  488.                 AUXR |=  0x80;  //1T mode
  489.                 TH0 = (u8)((65536UL - clk) / 256);
  490.                 TL0 = (u8)((65536UL - clk) % 256);
  491.         }
  492.         else
  493.         {
  494.                 AUXR &= ~0x80;  //12T mode
  495.                 TH0 = (u8)((65536UL - clk/12) / 256);
  496.                 TL0 = (u8)((65536UL - clk/12) % 256);
  497.         }

  498.         TR0 = 1;    //开始运行
  499. }

  500. //========================================================================
  501. // 函数: void timer0_int (void) interrupt TIMER0_VECTOR
  502. // 描述:  timer0中断函数.
  503. // 参数: none.
  504. // 返回: none.
  505. // 版本: V1.0, 2015-1-12
  506. //========================================================================
  507. void timer0_int (void) interrupt 1
  508. {
  509.         B_1ms = 1;      //1ms标志
  510. }

  511. //========================================================================
  512. // 函数: void SetMCLK(u8 clk)
  513. // 描述: 设置主频
  514. // 参数: clk: 主频序号
  515. // 返回: none.
  516. // 版本: VER1.0
  517. // 日期: 2020-10-21
  518. // 备注:
  519. //========================================================================
  520. void SetMCLK(u8 clk) //设置主频
  521. {
  522.         if(clk > IRC_36M) return;        //Error
  523.         CLK_ID = clk;
  524.         switch(clk)
  525.         {
  526.         case IRC_500K:
  527.                 //选择500KHz
  528.                 //P_SW2 = 0x80;
  529.                 CLKDIV = 0x04;
  530.                 IRTRIM = T24M_ROMADDR;
  531.                 VRTRIM = VRT27M_ROMADDR;
  532.                 IRCBAND = 0x02;
  533.                 CLKDIV = 48;
  534.                 MAIN_Fosc =        500000L;        //定义主时钟
  535.                 break;

  536.         case IRC_1M:
  537.                 //选择1MHz
  538.                 //P_SW2 = 0x80;
  539.                 CLKDIV = 0x04;
  540.                 IRTRIM = T24M_ROMADDR;
  541.                 VRTRIM = VRT27M_ROMADDR;
  542.                 IRCBAND = 0x02;
  543.                 CLKDIV = 24;
  544.                 MAIN_Fosc =        1000000L;        //定义主时钟
  545.                 break;

  546.         case IRC_2M:
  547.                 //选择2MHz
  548.                 //P_SW2 = 0x80;
  549.                 CLKDIV = 0x04;
  550.                 IRTRIM = T24M_ROMADDR;
  551.                 VRTRIM = VRT27M_ROMADDR;
  552.                 IRCBAND = 0x02;
  553.                 CLKDIV = 12;
  554.                 MAIN_Fosc =        2000000L;        //定义主时钟
  555.                 break;

  556.         case IRC_3M:
  557.                 //选择3MHz
  558.                 //P_SW2 = 0x80;
  559.                 CLKDIV = 0x04;
  560.                 IRTRIM = T24M_ROMADDR;
  561.                 VRTRIM = VRT27M_ROMADDR;
  562.                 IRCBAND = 0x02;
  563.                 CLKDIV = 8;
  564.                 MAIN_Fosc =        3000000L;        //定义主时钟
  565.                 break;

  566.         case IRC_5M:
  567.                 //选择5.5296MHz
  568.                 //P_SW2 = 0x80;
  569.                 CLKDIV = 0x04;
  570.                 IRTRIM = T22M_ROMADDR;
  571.                 VRTRIM = VRT27M_ROMADDR;
  572.                 IRCBAND = 0x02;
  573.                 CLKDIV = 4;
  574.                 MAIN_Fosc =        5529600L;        //定义主时钟
  575.                 break;

  576.         case IRC_6M:
  577.                 //选择6MHz
  578.                 //P_SW2 = 0x80;
  579.                 CLKDIV = 0x04;
  580.                 IRTRIM = T24M_ROMADDR;
  581.                 VRTRIM = VRT27M_ROMADDR;
  582.                 IRCBAND = 0x02;
  583.                 CLKDIV = 4;
  584.                 MAIN_Fosc =        6000000L;        //定义主时钟
  585.                 break;

  586.         case IRC_8M:
  587.                 //选择8MHz
  588.                 //P_SW2 = 0x80;
  589.                 CLKDIV = 0x04;
  590.                 IRTRIM = T24M_ROMADDR;
  591.                 VRTRIM = VRT27M_ROMADDR;
  592.                 IRCBAND = 0x02;
  593.                 CLKDIV = 3;
  594.                 MAIN_Fosc =        8000000L;        //定义主时钟
  595.                 break;

  596.         case IRC_10M:
  597.                 //选择10MHz
  598.                 //P_SW2 = 0x80;
  599.                 CLKDIV = 0x04;
  600.                 IRTRIM = T20M_ROMADDR;
  601.                 VRTRIM = VRT27M_ROMADDR;
  602.                 IRCBAND = 0x02;
  603.                 CLKDIV = 2;
  604.                 MAIN_Fosc =        10000000L;        //定义主时钟
  605.                 break;

  606.         case IRC_11M:
  607.                 //选择11.0592MHz
  608.                 //P_SW2 = 0x80;
  609.                 CLKDIV = 0x04;
  610.                 IRTRIM = T22M_ROMADDR;
  611.                 VRTRIM = VRT27M_ROMADDR;
  612.                 IRCBAND = 0x02;
  613.                 CLKDIV = 2;
  614.                 MAIN_Fosc =        11059200L;        //定义主时钟
  615.                 break;

  616.         case IRC_12M:
  617.                 //选择12MHz
  618.                 //P_SW2 = 0x80;
  619.                 CLKDIV = 0x04;
  620.                 IRTRIM = T24M_ROMADDR;
  621.                 VRTRIM = VRT27M_ROMADDR;
  622.                 IRCBAND = 0x02;
  623.                 CLKDIV = 2;
  624.                 MAIN_Fosc =        12000000L;        //定义主时钟
  625.                 break;

  626.         case IRC_15M:
  627.                 //选择15MHz
  628.                 //P_SW2 = 0x80;
  629.                 CLKDIV = 0x04;
  630.                 IRTRIM = T30M_ROMADDR;
  631.                 VRTRIM = VRT27M_ROMADDR;
  632.                 IRCBAND = 0x02;
  633.                 CLKDIV = 2;
  634.                 MAIN_Fosc =        15000000L;        //定义主时钟
  635.                 break;

  636.         case IRC_18M:
  637.                 //选择18.432MHz
  638.                 //P_SW2 = 0x80;
  639.                 CLKDIV = 0x04;
  640.                 IRTRIM = T36M_ROMADDR;
  641.                 VRTRIM = VRT44M_ROMADDR;
  642.                 IRCBAND = 0x03;
  643.                 CLKDIV = 2;
  644.                 MAIN_Fosc =        18432000L;        //定义主时钟
  645.                 break;

  646.         case IRC_20M:
  647.                 //选择20MHz
  648.                 //P_SW2 = 0x80;
  649.                 CLKDIV = 0x04;
  650.                 IRTRIM = T20M_ROMADDR;
  651.                 VRTRIM = VRT27M_ROMADDR;
  652.                 IRCBAND = 0x02;
  653.                 CLKDIV = 0;
  654.                 MAIN_Fosc =        20000000L;        //定义主时钟
  655.                 break;

  656.         case IRC_24M:
  657.                 //选择24MHz
  658.                 //P_SW2 = 0x80;
  659.                 CLKDIV = 0x04;
  660.                 IRTRIM = T24M_ROMADDR;
  661.                 VRTRIM = VRT27M_ROMADDR;
  662.                 IRCBAND = 0x02;
  663.                 CLKDIV = 0;
  664.                 MAIN_Fosc =        24000000L;        //定义主时钟
  665.                 break;

  666.         case IRC_27M:
  667.                 //选择27MHz
  668.                 //P_SW2 = 0x80;
  669.                 CLKDIV = 0x04;
  670.                 IRTRIM = T27M_ROMADDR;
  671.                 VRTRIM = VRT27M_ROMADDR;
  672.                 IRCBAND = 0x02;
  673.                 CLKDIV = 0;
  674.                 MAIN_Fosc =        27000000L;        //定义主时钟
  675.                 break;

  676.         case IRC_30M:
  677.                 //选择30MHz
  678.                 //P_SW2 = 0x80;
  679.                 CLKDIV = 0x04;
  680.                 IRTRIM = T30M_ROMADDR;
  681.                 VRTRIM = VRT27M_ROMADDR;
  682.                 IRCBAND = 0x02;
  683.                 CLKDIV = 0;
  684.                 MAIN_Fosc =        30000000L;        //定义主时钟
  685.                 break;

  686.         case IRC_33M:
  687.                 //选择33.1176MHz
  688.                 //P_SW2 = 0x80;
  689.                 CLKDIV = 0x04;
  690.                 IRTRIM = T33M_ROMADDR;
  691.                 VRTRIM = VRT27M_ROMADDR;
  692.                 IRCBAND = 0x02;
  693.                 CLKDIV = 0;
  694.                 MAIN_Fosc =        33117600L;        //定义主时钟
  695.                 break;

  696.         case IRC_35M:
  697.                 //选择35MHz
  698.                 //P_SW2 = 0x80;
  699.                 CLKDIV = 0x04;
  700.                 IRTRIM = T35M_ROMADDR;
  701.                 VRTRIM = VRT44M_ROMADDR;
  702.                 IRCBAND = 0x03;
  703.                 CLKDIV = 0;
  704.                 MAIN_Fosc =        35000000L;        //定义主时钟
  705.                 break;

  706.         case IRC_36M:
  707.                 //选择36.864MHz
  708.                 //P_SW2 = 0x80;
  709.                 CLKDIV = 0x04;
  710.                 IRTRIM = T36M_ROMADDR;
  711.                 VRTRIM = VRT44M_ROMADDR;
  712.                 IRCBAND = 0x03;
  713.                 CLKDIV = 0;
  714.                 MAIN_Fosc =        36864000L;        //定义主时钟
  715.                 break;

  716.         default:
  717.                 //选择22.1184MHz
  718.                 //P_SW2 = 0x80;
  719.                 CLKDIV = 0x04;
  720.                 IRTRIM = T22M_ROMADDR;
  721.                 VRTRIM = VRT27M_ROMADDR;
  722.                 IRCBAND = 0x02;
  723.                 CLKDIV = 0;
  724.                 MAIN_Fosc =        22118400L;        //定义主时钟
  725.                 break;
  726.         }
  727.         Timer0_init(MAIN_Fosc/1000);
  728.         UART1_config(MAIN_Fosc, Baudrate);                // brt: 通信波特率.
  729. }

  730. //========================================================================
  731. // 函数: u8 GetCheckSum(u8 *buf, u8 len)
  732. // 描述: 获取校验码
  733. // 参数: buf:  字符串指针, len: 字节数
  734. // 返回: none.
  735. // 版本: VER1.0
  736. // 日期: 2020-7-6
  737. // 备注:
  738. //========================================================================
  739. u8 GetCheckSum(u8 *buf, u8 len) //获取校验码
  740. {
  741.     u8 i;
  742.     u8 cs=0;
  743.     for (i = 0; i < len; i++)
  744.     {
  745.         cs += buf[i];
  746.     }
  747.     return cs;
  748. }

  749. //========================================================================
  750. // 函数: void RX1_Check(void)
  751. // 描述: 串口获取命令处理函数
  752. // 参数: none.
  753. // 返回: none.
  754. // 版本: VER1.0
  755. // 日期: 2020-7-6
  756. // 备注:
  757. //========================================================================
  758. void RX1_Check(void)
  759. {
  760.         u8  i;
  761.         u16  tmpValue;

  762.         if((RX1_Cnt >= 5) && (RX1_Buffer[CMD_SYNC1] == SYNC1) && (RX1_Buffer[CMD_SYNC2] == SYNC2))   //最短命令为10个字节
  763.         {
  764.                 if(RX1_Buffer[CMD_TYPE] == 0x01)        //上位机发送设置指令通信协议
  765.                 {
  766.                         if(RX1_Buffer[CMD_CS] == GetCheckSum(RX1_Buffer,CMD_CS))
  767.                         {
  768.                                 P_SW2 |= 0x80;        //允许访问XSF
  769.                                 IE2 &= 0x7F;                //停止触摸中断
  770.                                 TSCTRL = 0;                        //停止自动扫描
  771.                                 TSSTA2 |= 0xc0;        //清除标志位
  772.                                 TSRT = RX1_Buffer[CMD_TSRT];                        //LED分时扫描
  773.                                 TSCHEN1 = RX1_Buffer[CMD_TSCHEN1];        //TK00~TK07
  774.                                 TSCHEN2 = RX1_Buffer[CMD_TSCHEN2];        //TK08~TK15
  775.                                 TSCFG1 = RX1_Buffer[CMD_TSCFG1];                //开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
  776.                                 TSCFG2 = RX1_Buffer[CMD_TSCFG2];                //配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4)  1(1/2)  2(5/8)  3(3/4)
  777.                                 TSCTRL = RX1_Buffer[CMD_TSCTRL];        //开始自动扫描, 无平均, B7: TSGO,  B6: SINGLE,  B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
  778.                                 TSWUTC = RX1_Buffer[CMD_TSWUTC];
  779.                                 ScanFreq = ((u16)RX1_Buffer[CMD_SFREQ1] << 8) + RX1_Buffer[CMD_SFREQ2];
  780.                                 ChannelSet = ((u16)TSCHEN2 << 8) | TSCHEN1;
  781.                                 IE2 |= 0x80;                //使能触摸中断
  782. //                                P_SW2 &= ~0x80;                //禁止访问xsf
  783.                                
  784.                                 for(i=0;i<16;i++)
  785.                                 {
  786.                                         tmpValue = (RX1_Buffer[CMD_TSTH00H+(i*2)] << 8) + RX1_Buffer[CMD_TSTH00L+(i*2)];
  787.                                         if(tmpValue > 200)        //判断差值是否有效
  788.                                         {
  789.                                                 TK_differ[i] = tmpValue >> 1;        //阈值 = 差值/2
  790.                                                 TK_lowest[i] = TK_differ[i] * 3;
  791.                                         }
  792.                                 }
  793.                                
  794.                                 read_cnt=0;
  795.                                 TK_TimeOut = 0;
  796.                                 B_Zero_Flag = 1;        //重新获取0点
  797.                         }
  798.                 }
  799.                 else if((RX1_Buffer[CMD_TYPE] == 0x02) && (RX1_Buffer[4] == GetCheckSum(RX1_Buffer,4)))
  800.                 {
  801.                         if(RX1_Buffer[3] < 16)                //MCU回复触摸按键数据
  802.                         {
  803.                                 SendBuffer[2] = 0x03;
  804.                                 SendBuffer[3] = RX1_Buffer[3];
  805.                                 SendBuffer[4] = (u8)(TK_cnt[RX1_Buffer[3]] >> 8);
  806.                                 SendBuffer[5] = (u8)TK_cnt[RX1_Buffer[3]];
  807.                                 SendBuffer[6] = (u8)(TK_zero[RX1_Buffer[3]] >> 8);
  808.                                 SendBuffer[7] = (u8)TK_zero[RX1_Buffer[3]];
  809.                                 SendBuffer[8] = GetCheckSum(SendBuffer,8);
  810.                                
  811.                                 for(i=0;i<9;i++)
  812.                                 {
  813.                                         UART1_TxByte(SendBuffer[i]);
  814.                                 }
  815.                         }
  816.                         else if(RX1_Buffer[3] == 0xfd)        //MCU回复主频设置
  817.                         {
  818.                                 SendBuffer[2] = 0x03;
  819.                                 SendBuffer[3] = RX1_Buffer[3];
  820.                                 SendBuffer[4] = CLK_ID;
  821.                                 SendBuffer[5] = GetCheckSum(SendBuffer,5);
  822.                                
  823.                                 for(i=0;i<6;i++)
  824.                                 {
  825.                                         UART1_TxByte(SendBuffer[i]);
  826.                                 }
  827.                         }
  828.                         else if(RX1_Buffer[3] == 0xfe)        //MCU回复设置状态
  829.                         {
  830.                                 P_SW2 |= 0x80;        //允许访问XSF
  831.                                 SendBuffer[CMD_TYPE] = 0x04;
  832.                                 SendBuffer[CMD_TSCHEN1] = TSCHEN1;
  833.                                 SendBuffer[CMD_TSCHEN2] = TSCHEN2;
  834.                                 SendBuffer[CMD_TSCFG1] = TSCFG1;
  835.                                 SendBuffer[CMD_TSCFG2] = TSCFG2;
  836.                                 SendBuffer[CMD_TSCTRL] = TSCTRL;
  837.                                 SendBuffer[CMD_TSRT] = TSRT;
  838.                                 SendBuffer[CMD_SFREQ1] = (u8)(ScanFreq >> 8);
  839.                                 SendBuffer[CMD_SFREQ2] = (u8)ScanFreq;
  840.                                 SendBuffer[CMD_TSWUTC] = TSWUTC;
  841. //                                P_SW2 &= ~0x80;                //禁止访问xsf

  842.                                 for(i=0;i<16;i++)
  843.                                 {
  844.                                         tmpValue = TK_differ[i] << 1;                //差值 = 阈值*2
  845.                                         SendBuffer[CMD_TSTH00H+(i*2)] = (u8)(tmpValue >> 8);
  846.                                         SendBuffer[CMD_TSTH00L+(i*2)] = (u8)tmpValue;
  847.                                 }
  848.                                 SendBuffer[CMD_CS] = GetCheckSum(SendBuffer,CMD_CS);

  849.                                 for(i=0;i<CMD_LEN;i++)
  850.                                 {
  851.                                         UART1_TxByte(SendBuffer[i]);
  852.                                 }
  853.                         }
  854.                 }
  855.                 else if((RX1_Buffer[CMD_TYPE] == 0x05) && (RX1_Buffer[4] == GetCheckSum(RX1_Buffer,4)))        //上位机发送设置主频指令
  856.                 {
  857.                         SetMCLK(RX1_Buffer[3]);
  858.                 }
  859.         }
  860. }

  861. //========================================================================
  862. // 函数: void TKSU_Interrupt(void)
  863. // 描述: 触摸按键中断。
  864. // 参数: none.
  865. // 返回: none.
  866. // 版本: VER1.0
  867. // 日期: 2021-02-01
  868. // 备注:
  869. //========================================================================
  870. void TKSU_Interrupt(void) interrupt 13
  871. {
  872.         u8        j;
  873.         j = TSSTA2;
  874.         if(j & 0x40)        //数据溢出, 错误处理(略)
  875.         {
  876.                 TSSTA2 |= 0x40;        //写1清零
  877.         }
  878.         if(j & 0x80)        //扫描完成
  879.         {
  880.                 j &= 0x0f;
  881.                 TK_cnt[j] = TSDAT;        //保存某个通道的读数
  882.                 TSSTA2 |= 0x80;        //写1清零
  883.                 read_cnt++;                //读次数+1, 用于延时或读键计数
  884.                 TK_TimeOut = 0;
  885.         }
  886. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2024-8-17 21:18:29 | 显示全部楼层
芯片说明书写得太难懂了,我也没搞懂触摸中断的工作方式
回复 支持 反对

使用道具 举报

发表于 2024-12-1 15:02:14 | 显示全部楼层
芯片资料说的太难懂了,也不好找
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-3 11:32 , Processed in 0.156000 second(s), 13 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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