打印
[PIC®/AVR®/dsPIC®产品]

【4月晒板卡】+PIC16F18446开启定时器并实现多功能按键

[复制链接]
3078|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hu9jj|  楼主 | 2019-6-10 15:53 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 hu9jj 于 2019-6-10 15:53 编辑

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

一、定时器0的开启
    进入MCC对定时器0进行配置,这是最方便快捷的设置方法。进入MCC(见下图),这里我就用默认的设置,没有变动。

    选择定时器0,预分频选择为1:64,后分频为1:5,定时器选择8位,时钟源选择的与上面系统配置一致的“HFINTOSC”,这里特别提醒,我之前时钟源选择的是Fosc/4,但调试时却反复不成功,最后将时钟源改为与系统配置相同的才调试成功。这是main函数中的代码:
    我设置的定时时间为20.48毫秒,但在之后的实际调试时发现定时时间远低于20毫秒,后来是修改了预分频和后分频才勉强达到要求。

    下面是自动生成的timer0.c代码,在调试过程中我将预分频改为1:128,后分频改为1:10。
/**
  TMR0 Generated Driver File

  @Company
    Microchip Technology Inc.

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

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

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

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

/**
  Section: Included Files
*/

#include <xc.h>
#include "tmr0.h"
#include "pin_manager.h"

extern char keys,keyok;
extern int ms;
/**
  Section: TMR0 APIs
*/

void (*TMR0_InterruptHandler)(void);

void TMR0_Initialize(void)
{
    // Set TMR0 to the options selected in the User Interface

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

    // TMR0H 31;
    TMR0H = 0x1F;

    // TMR0L 0;
    TMR0L = 0x00;

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

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

    // Set Default Interrupt Handler
    TMR0_SetInterruptHandler(TMR0_DefaultInterruptHandler);

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

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

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

uint8_t TMR0_ReadTimer(void)
{
    uint8_t readVal;

    // read Timer0, low register only
    readVal = TMR0L;

    return readVal;
}

void TMR0_WriteTimer(uint8_t timerVal)
{
    // Write to Timer0 registers, low register only
    TMR0L = timerVal;
}

void TMR0_Reload(uint8_t periodVal)
{
   // Write to Timer0 registers, high register only
   TMR0H = periodVal;
}

void TMR0_ISR(void)
{
    static volatile uint16_t CountCallBack = 0;
    ms++;
    if(0==IO_RC2_GetValue()){
        if(0==keyok & keys<255)
            keys++;
    }
    else{
        if(keys>0)
            keyok = 1;
    }
    // clear the TMR0 interrupt flag
    PIR0bits.TMR0IF = 0;
    // callback function - called every 8th pass
    if (++CountCallBack >= TMR0_INTERRUPT_TICKER_FACTOR)
    {
        // ticker function call
        TMR0_CallBack();

        // reset ticker counter
        CountCallBack = 0;
    }

    // add your TMR0 interrupt custom code
}

void TMR0_CallBack(void)
{
    // Add your custom callback code here

    if(TMR0_InterruptHandler)
    {
        TMR0_InterruptHandler();
    }
}

void TMR0_SetInterruptHandler(void (* InterruptHandler)(void)){
    TMR0_InterruptHandler = InterruptHandler;
}

void TMR0_DefaultInterruptHandler(void){
    // add your TMR0 interrupt custom code
    // or set custom function using TMR0_SetInterruptHandler()
}

/**
  End of File
*/

   
二、多功能按键

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

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

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








使用特权

评论回复
沙发
lcczg| | 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。

使用特权

评论回复
板凳
hu9jj|  楼主 | 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 | 只看该作者
楼主著作甚丰啊

使用特权

评论回复
5
奔波儿熊| | 2019-6-11 11:28 | 只看该作者
支持一下

使用特权

评论回复
6
hu9jj|  楼主 | 2019-6-11 14:03 | 只看该作者
小卡 发表于 2019-6-11 10:34
楼主著作甚丰啊

那里,都是一些记录入门的过程而已。

使用特权

评论回复
7
hu9jj|  楼主 | 2019-6-11 14:03 | 只看该作者

谢谢支持!

使用特权

评论回复
8
oxygenzz| | 2019-6-11 18:13 | 只看该作者
楼主的帖子都非常赞!
再接再厉,希望见到楼主更多的分享!

使用特权

评论回复
9
643757107| | 2019-6-11 20:34 | 只看该作者
这个有意思,定期实现多功能按键。

使用特权

评论回复
10
cyb999| | 2020-8-6 14:46 | 只看该作者
楼主,我用的板子是PIC16LF1508,系统时钟选择LFINTOSC,但是MCC设置定时器0时只有FOSC/4和TOCKI可以选择,这样子可以怎么解决吗?

使用特权

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

本版积分规则

认证:Microchip
简介:让我们来为您提供帮助。我们可提供各种资源来帮助您解决一切问题。是否需要与我们的客户支持团队联系?您可以通过电话、在线聊天功能或电子邮件与他们联系。

144

主题

1031

帖子

11

粉丝