[8/16位qy002千赢国际] 【4月晒板卡】+PIC16F18446开启定时器并实现多功能按键

[复制链接]
702|8
 楼主 | 2019-6-10 15:53 | 显示全部楼层 |阅读模式
本帖最后由 hu9jj 于 2019-6-10 15:53 编辑

    PIC16F18446开发板上只有一个用户按钮,通过开启定时器可以记录用户按键的时间长短,从而达到识别同功能。另外,通过定时器对变量增一的操作,可以控制LED灯闪烁,避免用延时函数造成qy002千赢国际效率不高。

一、定时器0的开启
    进入MCC对定时器0进行配置,这是最方便快捷的设置方法。进入MCC(见下图),这里我就用默认的设置,没有变动。
MCC_SYSTEM.jpg
    选择定时器0,预分频选择为1:64,后分频为1:5,定时器选择8位,时钟源选择的与上面系统配置一致的“HFINTOSC”,这里特别提醒,我之前时钟源选择的是Fosc/4,但调试时却反复不成功,最后将时钟源改为与系统配置相同的才调试成功。这是main函数中的代码:
    我设置的定时时间为20.48毫秒,但在之后的实际调试时发现定时时间远低于20毫秒,后来是修改了预分频和后分频才勉强达到要求。
MCC_timer0.jpg
    下面是自动生成的timer0.c代码,在调试过程中我将预分频改为1:128,后分频改为1:10。
  1. /**
  2.   TMR0 Generated Driver File

  3.   @Company
  4.     Microchip Technology Inc.

  5.   [url=home.php?mod=space&uid=288409]@file[/url] Name
  6.     tmr0.c

  7.   @Summary
  8.     This is the generated driver implementation file for the TMR0 driver using PIC10 / PIC12 / PIC16 / PIC18 MCUs

  9.   @Description
  10.     This source file provides APIs for TMR0.
  11.     Generation Information :
  12.         Product Revision  :  PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.76
  13.         Device            :  PIC16F18446
  14.         Driver Version    :  3.10
  15.     The generated drivers are tested against the following:
  16.         Compiler          :  XC8 2.00
  17.         MPLAB                   :  MPLAB X 5.10
  18. */

  19. /*
  20.     (c) 2018 Microchip Technology Inc. and its subsidiaries.
  21.    
  22.     Subject to your compliance with these terms, you may use Microchip software and any
  23.     derivatives exclusively with Microchip products. It is your responsibility to comply with third party
  24.     license terms applicable to your use of third party software (including open source software) that
  25.     may accompany Microchip software.
  26.    
  27.     THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
  28.     EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY
  29.     IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS
  30.     FOR A PARTICULAR PURPOSE.
  31.    
  32.     IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
  33.     INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
  34.     WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP
  35.     HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO
  36.     THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL
  37.     CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT
  38.     OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS
  39.     SOFTWARE.
  40. */

  41. /**
  42.   Section: Included Files
  43. */

  44. #include <xc.h>
  45. #include "tmr0.h"
  46. #include "pin_manager.h"

  47. extern char keys,keyok;
  48. extern int ms;
  49. /**
  50.   Section: TMR0 APIs
  51. */

  52. void (*TMR0_InterruptHandler)(void);

  53. void TMR0_Initialize(void)
  54. {
  55.     // Set TMR0 to the options selected in the User Interface

  56.     // T0CS HFINTOSC; T0CKPS 1:64; T0ASYNC synchronised;
  57.     T0CON1 = 0x67;   //0x66  T0CKPS=1:128

  58.     // TMR0H 31;
  59.     TMR0H = 0x1F;

  60.     // TMR0L 0;
  61.     TMR0L = 0x00;

  62.     // Clear Interrupt flag before enabling the interrupt
  63.     PIR0bits.TMR0IF = 0;

  64.     // Enabling TMR0 interrupt.
  65.     PIE0bits.TMR0IE = 1;

  66.     // Set Default Interrupt Handler
  67.     TMR0_SetInterruptHandler(TMR0_DefaultInterruptHandler);

  68.     // T0OUTPS 1:5; T0EN enabled; T016BIT 8-bit;
  69.     T0CON0 = 0x89;  //0x84  T0OUTPS=1:10
  70. }

  71. void TMR0_StartTimer(void)
  72. {
  73.     // Start the Timer by writing to TMR0ON bit
  74.     T0CON0bits.T0EN = 1;
  75. }

  76. void TMR0_StopTimer(void)
  77. {
  78.     // Stop the Timer by writing to TMR0ON bit
  79.     T0CON0bits.T0EN = 0;
  80. }

  81. uint8_t TMR0_ReadTimer(void)
  82. {
  83.     uint8_t readVal;

  84.     // read Timer0, low register only
  85.     readVal = TMR0L;

  86.     return readVal;
  87. }

  88. void TMR0_WriteTimer(uint8_t timerVal)
  89. {
  90.     // Write to Timer0 registers, low register only
  91.     TMR0L = timerVal;
  92. }

  93. void TMR0_Reload(uint8_t periodVal)
  94. {
  95.    // Write to Timer0 registers, high register only
  96.    TMR0H = periodVal;
  97. }

  98. void TMR0_ISR(void)
  99. {
  100.     static volatile uint16_t CountCallBack = 0;
  101.     ms++;
  102.     if(0==IO_RC2_GetValue()){
  103.         if(0==keyok & keys<255)
  104.             keys++;
  105.     }
  106.     else{
  107.         if(keys>0)
  108.             keyok = 1;
  109.     }
  110.     // clear the TMR0 interrupt flag
  111.     PIR0bits.TMR0IF = 0;
  112.     // callback function - called every 8th pass
  113.     if (++CountCallBack >= TMR0_INTERRUPT_TICKER_FACTOR)
  114.     {
  115.         // ticker function call
  116.         TMR0_CallBack();

  117.         // reset ticker counter
  118.         CountCallBack = 0;
  119.     }

  120.     // add your TMR0 interrupt custom code
  121. }

  122. void TMR0_CallBack(void)
  123. {
  124.     // Add your custom callback code here

  125.     if(TMR0_InterruptHandler)
  126.     {
  127.         TMR0_InterruptHandler();
  128.     }
  129. }

  130. void TMR0_SetInterruptHandler(void (* InterruptHandler)(void)){
  131.     TMR0_InterruptHandler = InterruptHandler;
  132. }

  133. void TMR0_DefaultInterruptHandler(void){
  134.     // add your TMR0 interrupt custom code
  135.     // or set custom function using TMR0_SetInterruptHandler()
  136. }

  137. /**
  138.   End of File
  139. */
复制代码

   
二、多功能按键

开启了定时器0后,我通过定时器0对按键功能进行了扩展,使得可以分辨用户按键时间的长短,达到扩展按键功能的目的。

我是通过两个全局变量,变量keyok置位表示用户有按键事件,变量keys则表示按下的时间长短。在我的例子中,快速点击按键返回的值大约10以内,按下4~5秒释放后大约为250左右,根据这个返回值就可以划分为若干个范围,根据我的测试至少可以分为四种按键状态,分别是:快速点击(keys<20)、短按(20<keys<50)、长按(50<keys<150)、超长按(keys>150)。

我测试时是通过串口通讯将按键值发送到电脑端来观看,下图是串口调试助手获得的按键数据:



key_timer.jpg




使用特权 评论回复
| 2019-6-10 17:55 | 显示全部楼层
楼主,配置窗口里callback function rate 是8, 8乘以定时器中断时间2.56ms(这个是你测得的快的多的值)= 20.28ms. 在代码// ticker function call
        TMR0_CallBack(); 处应该是你想要的20.28ms. 感觉常数TMR0_INTERRUPT_TICKER_FACTOR 是 8。
使用特权 评论回复
 楼主 | 2019-6-10 22:04 | 显示全部楼层
lcczg 发表于 2019-6-10 17:55
楼主,配置窗口里callback function rate 是8, 8乘以定时器中断时间2.56ms(这个是你测得的快的多的值)= 20. ...

谢谢提醒,应该是这个原因,我直接将代码写在TMR0_ISR()里面,所以就快得多了。不过我修改了预分频系数和后分频系数,基本上也达到了目的。
使用特权 评论回复
| 2019-6-11 10:34 | 显示全部楼层
楼主著作甚丰啊
使用特权 评论回复
| 2019-6-11 11:28 | 显示全部楼层
支持一下
使用特权 评论回复
 楼主 | 2019-6-11 14:03 | 显示全部楼层
小卡 发表于 2019-6-11 10:34
楼主著作甚丰啊

那里,都是一些记录入门的过程而已。
使用特权 评论回复
 楼主 | 2019-6-11 14:03 | 显示全部楼层

谢谢支持!
使用特权 评论回复
| 2019-6-11 18:13 | 显示全部楼层
楼主的帖子都非常赞!
再接再厉,希望见到楼主更多的分享!
使用特权 评论回复
| 2019-6-11 20:34 | 显示全部楼层
这个有意思,定期实现多功能按键。
使用特权 评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册
本版积分规则
我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表