[活动专区]

【赛元95F】之六:TK_LCD_TIMER 触摸按键LCD显示倒计时器

[复制链接]
1717|13
手机看帖
扫描二维码
随时随地手机跟帖
lisingch|  楼主 | 2020-4-8 12:12 | 显示全部楼层 |阅读模式
本帖最后由 lisingch 于 2020-4-8 12:19 编辑

一、项目名称
TK_LCD_TIMER-触摸按键LCD显示倒计时器

二、项目简介
      TK_LCD_TIMER触摸按键LCD显示倒计时器,以赛元微电子为本次活动提供的SC95F8617 demo板及相关资料为基础进行学习、开发、验证。最终完成的样品使用了赛元微电子为本次活动配送的SC95F8617样片做为主控,并利用片上的31路触摸按键中的三路(TK24、TK25、TK26)做为触摸按键,其中的两路触摸按键(TK24、TK26)用于设置倒计时时间,另外一路触摸按键(TK25)用于启动与暂停,启动前双色LED为红色常亮状态;倒计时器计时时间通过4位LCD显示(显示00~99),倒计时器计时时间范围为“00”~“99”分钟;倒计时器“启动”后红色LED熄灭,绿色LED以500ms间隔闪烁,呈现“秒”状态,倒计时器计时时间到后绿色LED熄灭,红色LED常亮并伴有蜂鸣器声音报警。

三、系统框图
新建图片_副本.jpg

四、硬件电路设计及制作
1、原理图及PCB
      电路比较简单没有画电路图,根据《赛元高灵敏度触控按键MCU PCB设计要点》的指导,使用“Sprint-Layout 6.0”直接绘制PCB。绘制中触摸按键的引线宽度使用了推荐的0.3;“Cadj”使用了一只0805的103电容;电源滤波电容使用了一只10uF/10V钽电解和一只0805的104电容;触摸按键使用了三只0805的510匹配电阻并尽可能靠近MCU。由于使用的是单面PCB,为了避免背面连线及方便布线,使得TK走线的长度并不相同,也没有做GND的敷铜处理。《赛元高灵敏度触控按键MCU PCB设计要点》对于PCB设计起到了至关重要的作用;
2020-04-08_012116.png
2020-04-08_012145.png
2020-04-08_012243.png
2020-04-08_012348.png
2020-04-08_012403.png
2020-04-08_012429.png
2020-04-08_012451.png

完成后的PCB尺寸为65X65,四个角受壳体限制而切割成了圆角。通过热转印方法制板并使用环保腐蚀剂腐蚀;
SCH.JPG
IMG20200326183006.jpg
IMG20200326195216.jpg
IMG20200326195237.jpg
IMG20200326195708.jpg
IMG20200326195732.jpg
IMG20200327173212.jpg

2、制作用到的元器件
a、外壳。这个小盒子很多朋友都认识,就不多介绍了;
b、主控MCU。“高可靠,超高速,低功耗,双模触控Flash MCU ”,这里使用的SC95F8617(LQFP48)是“SC95F861X”系列中最高端的一款;
IMG20200324135933.jpg

c、LCD显示屏。手上的这片LCD屏用在这里尺寸显得有点小。从资料上看是1/4DUYT、1/3BIAS的4位显示屏。另外给LCD屏配了个2.0间距的12孔母座,避免了焊接对屏的意外损坏同时也便于屏的安装;
IMG20200324135832.jpg
IMG20200324162707.jpg
液晶.jpg

d、触摸弹簧键。从废电磁炉里拆的一共有6个,触摸面直径13;高度17略低,用铜丝在曲别针上绕了三个小弹簧作为加长件以弥补高度的不足;
IMG20200324135748.jpg
IMG20200324134004.jpg

e、蜂鸣器。拆机件5v有源蜂鸣器;
IMG20200324164038.jpg

f、电池及充电板。锂电池是拆机的容量不知,但是带有保护板还比较新;充电部分使用了一片TP4056成品充电板;
IMG20200324151026.jpg

g、三色发光LED。三围尺寸3.7x3.5x2.8,颜色非常艳丽的RGB三色LED,实际只用了R\G二色;
IMG20200324171708.jpg
2020-04-02_185455.png

h、水银开关。用于电源通断控制;
IMG20200324164008.jpg

i、器件合影(除阻、容,PCB外)
IMG20200324164314.jpg
IMG20200324171806.jpg

3、焊接及组装
      水银开关暂时没有焊接,调试正常后再行补焊。为保持壳体外观的完整与美观只开了一个充电孔。在触摸按键的表面贴了一张纸片画了个小标识;
IMG20200327193101.jpg
IMG20200327193118.jpg
IMG20200327193132.jpg
IMG20200327193414.jpg
IMG20200327193429.jpg
IMG20200327193442.jpg
IMG20200327201228.jpg
IMG20200327201350.jpg
IMG20200327201449.jpg
IMG20200327203044.jpg

五、调试
      整体工程分成了几个模块,主要包括定时器、LCD驱动、TK触摸、双色LED驱动、蜂鸣器驱动等。程序文件均参考了官方提供的DEMO程序,有些就是直接修改引用,调试方法亦参考了官方的相关文档内容。本人所做的工作只是简单的编排、组合。
2020-04-02_234925.png
1、计时时基
      这部分采用了SC95F8617内部的定时器资源TIMER1在内建高精度32MHz时钟频率下中断产生500ms时基。定时器配置文件中同时配置了TIMER0,由其产生10ms时基配合LCD正常工作。这部分代码比较简单;
//T0用于配合LCD工作、T1产生500ms计数时基
void Timer_Config(void)
{
        TMCON = 0X03;                                                            //T0、T1时钟均为Fsys = 32MHz
        TMOD  = 0x11;                 //T0、T1均为工作方式1
        
        TL0 = (65536 - 32000)%256;    //溢出时间:32000*(1/32000000)= 0.001s(1ms);
        TH0 = (65536 - 32000)/256;
        
        TL1 = (65536 - 32000)%256;    //溢出时间:32000*(1/32000000)= 0.001s(1ms);
        TH1 = (65536 - 32000)/256;
        
        TR0 = 0;               
        TR1 = 0;        
        
        ET0 = 1;                                                                                        //T0使能中断
        ET1 = 1;                                                                                        //T1使能中断
        
        TR0 = 1;                                                                                        //启动T0
        //TR1 = 1;                                                                                        //T1启动由TK25控制
}


void T0_INT(void) interrupt 1//定时器0中断处理
{
        TL0 = (65536 - 32000)%256;   
        TH0 = (65536 - 32000)/256;
        
        T0_10ms++;
        if(T0_10ms >= 10)
        {
                T0_10ms = 0;
                T0_10ms_Flag = 1;        
        }
}

void T1_INT(void) interrupt 3//定时器1中断处理
{
        TL1 = (65536 - 32000)%256;   
        TH1 = (65536 - 32000)/256;
        
        T1_500ms++;
        
        if(T1_500ms >= 500)
        {
                T1_500ms = 0;
                T1_500ms_Flag = 1;        
        }
}

2、LCD驱动
      SC95F8617内部集成了硬件的LCD/LED显示驱动电路,可用于LCD和LED的显示驱动。
2020-04-08_103439.png
2020-04-02_211703.png
2020-04-02_211731.png

      通过DDRCON的DMOD位选择驱动类型。本案所选用的LCD为支持1/4DUYT、1/3BIAS工作模式的4位显示屏,结合PCB的布线可以看到LCD的COM1~4与MCU的CO~3相对应;8个SEG引脚连接到MCU的S4~11,因此DUTY[1:0]=11、VLCD[3:0]=0111(VLCD=VDD*3/4),符合1/3Bias LCD波形描述。OTCON寄存器对可根据LCD面积大小确定内部分压电阻,同时可以确定LCD的复用管脚及电压偏置类型。接下来就是在PnVO中将所复用端口的显示输出功能打开。本案中4位的LCD实际上只使用了中间的两位做为设定的时间显示(00~99),首位与末位只显示了LCD的“g”段,没有任何意义只是“装饰”。通过向LCD的对应RAM地址写入相应的信号便可控制LCD屏相应段位的显示。
2020-04-02_210804.png
2020-04-02_212450.png
下面是LCD配置代码,其它完整代码可参看附件:
void LCD_Port_Config(void)
{
        DDRCON = 0xB7;  //LCD模式、1/4占空比、VLCD=VDD*3/4、开显示驱动扫描

        P1VO = 0xFF;    //开P1口显示驱动输出S4~S11
        P3VO = 0x0F;    //开P3口显示驱动输出C0~C3
        OTCON = 0x06;   //设定内部分压电阻总电阻值为200KΩ
                                                                        //1/4偏置电压;S4~S27为segment,C0~C3为common
}

3、TK触摸按键
      赛元SC95F8617的双模触控是一套非常实用并且独具特色的外设,搭配官方的各种类型的触摸库及“Touch Key Tool Menu”软件,让触摸按键的调试及应用变成了一件非常开心愉快的事儿。
      TK功能的正确应用及调试流程在《赛元SC95F系列TouchKey MCU 应用指南v0.0.1》有非常详尽的描述,阅读学习这篇文档将为调试应用提供强有力的支持。 SC95F8617支持多达31路双模电容触控电路,可根据应用配置为高灵敏度模式或高可靠模式的触摸按键。高可靠模式具有很强的抗干扰能力,可通过10V动态CS测试。 本案即使用了其中的三路(TK24、TK25、TK26)配置为高灵敏度模式的三个弹簧按键,使用官方提供的“SC95F8X1X_HighSensitive_Lib_T1_S_V0.0.2.LIB”库,按照《赛元SC95F系列TouchKey MCU 应用指南v0.0.1》中的方法进行调试,非常简单轻松上手。
2020-04-08_002803.png
2020-04-08_002947.png
2020-04-08_003025.png
2020-04-08_003057.png

      调试首先要进行触控按键的静态调试,利用“SOC Pro51”将调试固件“SC95F8X1X_HighSensitiveTKStaticDebug_V0.0.1.hex”下载到SC95F8617,然后打开“Touch Key Tool Menu”选择“高灵敏度触控”进行操作,最后将生成的“S_TouchKeyCFG.h”替换工程目录下的同名文件……这些过程非常简单,在些就不再赘述。
2020-03-27_222037.png
2020-03-27_222329.png
2020-03-27_222333.png
2020-03-27_222429.png
2020-04-04_172147.png

生成的“S_TouchKeyCFG.h”文件可能还要根据实际情况进行小调整,如文档中的描述:
2020-04-02_234403.png

在本案中调试时由于受调试接口的物理影响没有盖上盖,实际应用中造成TK26灵敏度降低,最后偷懒直接在“S_TouchKeyCFG.h”将"TK25"的数据复制到“TK26”处直接进行了代用;
2020-04-02_234724.png

这部分的代码直接引用了官方DEMO,只是重写了一个按键处理函数;
//触摸按键处理
void TK_Process(void)
{
        static signed char Set_Timer_num = 0;        //设置定时时间
        static unsigned char T1_60S_num = 0;        //分钟计数
        static unsigned char key_enter_stop_flag = 0;//“确定/停止”键按下标志
        
        if(T0_10ms_Flag)
        {
                T0_10ms_Flag = 0;
                Lcd_Display();
        }
        LcdDataTab[0] = 10;        //显示“-”
        LcdDataTab[1] = (Set_Timer_num / 10);        //分钟十位
        LcdDataTab[2] = (Set_Timer_num % 10);        //分钟个位;
        LcdDataTab[3] = 10;        //显示“-”
        
        if(T1_500ms_Flag)
        {
                T1_500ms_Flag = 0;
                LED_Green = ~LED_Green;               
               
                if(++T1_60S_num >= 120)
                {
                        T1_60S_num = 0;
                        
                        if(--Set_Timer_num == 0)
                        {
                                TR1 = 0;                                
                                LED_Green = 1;
                                LED_Red = 0;
                                beep(8);
                        }
                }                                                
        }
        
        switch(exKeyValue)
        {
                case 1: if(key_dec && key_enter_stop_flag==0)
                                                {
                                                        beep(1);
                                                        Set_Timer_num--;
                                                        if(Set_Timer_num < 0)
                                                        {
                                                                Set_Timer_num = 99;
                                                        }
                                                        key_dec = 0;
                                                }                                       
                                                break;                        
                                                
                case 2: if(key_enter_stop && key_enter_stop_flag == 0)  
                                                {
                                                        beep(1);
                                                        key_enter_stop = 0;
                                                        key_enter_stop_flag = 1;
                                                        TR1 = 1;                //启动定时器1
                                                        LED_Red = 1;
                                                        LED_Green = 1;
                                                }        
                                                else if(key_enter_stop && key_enter_stop_flag)
                                                {
                                                        beep(1);
                                                        key_enter_stop = 0;
                                                        key_enter_stop_flag = 0;
                                                        TR1 = 0;               
                                                        LED_Red = 0;
                                                        LED_Green = 1;
                                                }
                                                break;        
                                                
                case 3: if(key_inc && key_enter_stop_flag==0)
                                                {
                                                        beep(1);
                                                        Set_Timer_num++;
                                                        if(Set_Timer_num >= 99)
                                                        {
                                                                Set_Timer_num = 0;
                                                        }
                                                        key_inc = 0;
                                                }break;
                                                                                                                        
                default: break;
        }        
}

4、蜂鸣器及LED
      很简单的代码,嵌入至相应部位就可以了。

5、程序联调
      所谓联调无非就是将上述几部分的代码进行组合,通过“Sys_Scan()”函数中的触摸按键处理函数TK_Process()实现了代码的“组合串连”。程序联调成功后样机脱离SC-LINK运行时发现TK26触摸按键不是很灵敏,其它两个还好。估计是由于MCU的调试端口没有引出,调试时盒盖无法闭合,触摸按键生成的参数与实际有偏差。最后偷了个懒,直接将TK25的数据替换了TK26的数据后正常(如前文描述)。
详细程序代码请参看文末的工程文件。
void main(void)
{
        unsigned char LcdDisplayNum = 0;
        LED_Port_Config();  //红、绿LED初始化
        BEEP_Port_Config();        //蜂鸣器端口初始化
        LCD_Port_Config();  //LCD端口配置
        Timer_Config();                        //T0、T1初始配置
        TouchKeyInit();                        //调用库函数,初始化TouchKey        
        LED_Red   = 0;                        //上电后红色LED点亮        
        EA = 1;                                                        //开总中断
        beep(1);        
/***************用于TK动态调试******************/
        #ifdef __TOUCHKEY_DEBUG__
        SOCAPI_DeBugTouchKey_Init();
        #endif
/************************************************/        
        
        while(1)
        {        
                Sys_Scan();                //TK按键扫描        
        }
}

6、调试过程
由于使用了3.7V锂电池供电且没有稳压措施,所以将“LVR”设置为了“2.9V”
2020-03-27_221837.png
IMG20200327203621.jpg
IMG20200328123643.jpg
IMG20200329192835.jpg
IMG20200329193108.jpg
IMG20200329193040.jpg
IMG20200329193107.jpg
六、成果演示。
拍了一个小视频。见附件。

七、存在问题及改进计划
1、存在问题
a、发光LED限流电阻阻值稍小,造成LED亮度过高刺眼;
b、水银开关过于灵敏,稍有振动即会出现“开、关”变化造成系统重启;
c、LCD显示面积太小;
d、TK按键PCB没有按官方建议进行铺地处理;
e、调试接口在盒子内,调试时盒盖只能局部模拟闭合状态,TK调试参数的参数与实际有少许出入。

2、改进计划
a、SC95F8617用在这有点可惜,可换成LQFP32封装的SC95F8615P32R已经足够了;
b、LCD选择面积稍大的产品,改进用户体验;
c、将水银开关取消,锂电池经过一片LDO芯片ME6211C33M5G后向输出稳定的3.3V供电电压;
d、增加发光LED限流电阻值用以减少工作电流降低功耗,
e、将调试接口引出,确保触摸按键的物理状态与实际工作状态一致;
f、TK触摸按键改为使用SC95F8X1X低功耗触控库“SC95F8X1X_HighSensitive_Lib_T1_S_V0.0.2.LIB”,通过“TK25”将整机从“Power Down”模式唤醒进入正常运行模式,这个还是很期待的。如《赛元SC95F8XXX低功耗触控库使用说明v0.2》描述:
2020-04-08_004904.png
g、增加一路ADC对锂电池电压进行监控,当锂电池电压降到设定值时在LCD上显示“Lo”,提示充电。

八、项目总结
       通过对这个很小的案例的全程操作,对SC95F8617的双模触控电路以及LCD显示驱动有了进一步的了解和认识,过程中学到了很多的知识。借此再次向我们提供本次学习机会的赛元微电子及21ic表示衷心地感谢!也希望借此机会与朋友们共同学习进步。

九、附件
附件里是完整的项目工程文件和最终的演示视频,方便与朋友们交流,同时也期望朋友们指出存在的错误并请多多指教。
(视频文件有点大分成了两个文件,但内容并没有什么。)
_TK_LCD_TIMER.rar (103.47 KB)

使用特权

评论回复

相关帖子

wade任| | 2020-4-8 16:29 | 显示全部楼层
顶一下。像你这么认真做东西的已经不多了。
期待你的新作。

使用特权

评论回复
lisingch|  楼主 | 2020-4-8 18:12 | 显示全部楼层
wade任 发表于 2020-4-8 16:29
顶一下。像你这么认真做东西的已经不多了。
期待你的新作。

感谢支持、表扬!相互学习

使用特权

评论回复
qwe123zxc| | 2020-4-8 20:04 | 显示全部楼层
介绍的这么详细,整个步骤一步一步地说明,而且还无私地把程序都发出来了,心里面真是感慨万分,想到自己网上寻找学习资料的艰辛,浪费了超长的时间,也才仅仅学到了基础,因为实在是不好找应用的全程序。

使用特权

评论回复
lisingch|  楼主 | 2020-4-8 21:10 | 显示全部楼层
qwe123zxc 发表于 2020-4-8 20:04
介绍的这么详细,整个步骤一步一步地说明,而且还无私地把程序都发出来了,心里面真是感慨万分,想到自己网 ...

谢谢捧场!多多交流相互学习

使用特权

评论回复
鑫越电子| | 2020-4-10 08:28 | 显示全部楼层
学习学习,希望楼主多分享???

使用特权

评论回复
lisingch|  楼主 | 2020-4-10 11:46 | 显示全部楼层
感谢支持!相互学习。

使用特权

评论回复
Spring1380| | 2020-4-13 11:51 | 显示全部楼层
学习!!!!!!!!!!!!!!!!

使用特权

评论回复
lisingch|  楼主 | 2020-4-13 12:20 | 显示全部楼层
Spring1380 发表于 2020-4-13 11:51
学习!!!!!!!!!!!!!!!!

多多交流。

使用特权

评论回复
fyljx666| | 2020-4-21 16:50 | 显示全部楼层
下载学习了,谢谢

使用特权

评论回复
CS801380| | 2020-5-7 17:25 | 显示全部楼层
好东西!!!!!!!!!!!!!!!!!!!!!!!!

使用特权

评论回复
paotangsan| | 2020-5-13 16:35 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
labasi| | 2020-5-13 16:35 | 显示全部楼层
介绍的非常详细

使用特权

评论回复
化骨龙| | 2020-6-19 16:48 | 显示全部楼层
学习学习

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

14978

帖子

17

粉丝