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

PIC16F18446定时器0设置问题

[复制链接]
2416|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hu9jj|  楼主 | 2019-6-9 09:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    我使用MCC配置了定时器0,时钟源选择Fosc/4,预分频为1024,后分频为5,按照计算定时时间为20.48ms。生成代码后未作修改,测试时却检测不到定时器0的中断,调试时发现已经进入了timer0的初始化,GIE总中断也打开了,T0IE中断也打开了,但在中断管理函数中却没有被执行,请问是不是还有哪里需要设置。另外我还开启了外部中断和串口通讯的中断,这些功能可以正常运行,就是定时器不起作用。
    下面是MCC生成的timer0.c文件:
#include <xc.h>
#include "tmr0.h"
#include "pin_manager.h"

extern uint8_t keys,keyok;
extern uint16_t ms;
/**
  Section: TMR0 APIs
*/

void (*TMR0_InterruptHandler)(void);

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

    // T0CS FOSC/4; T0CKPS 1:1024; T0ASYNC synchronised;
    T0CON1 = 0x4A;   //0100 1010  0x4A

    // TMR0H 0;
    TMR0H = 0x00;

    // 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 = 0x84;
}

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;
    IO_RA2_Toggle();
    // clear the TMR0 interrupt flag
    PIR0bits.TMR0IF = 0;
    // callback function - called every 49th pass
    //回调函数-每隔49次调用
    if (++CountCallBack >= TMR0_INTERRUPT_TICKER_FACTOR)
    {
        // ticker function call Ticker函数调用
        TMR0_CallBack();

        // reset ticker counter 重置票务计数器
        CountCallBack = 0;
    }

    // add your TMR0 interrupt custom code
    ms++;
    if(0==keyok){         //keyok=0表明无按键事件
        if(0==IO_RC2_GetValue()){
            if(keys<128)
                keys++;   //按键计数
        }
        else{
            if(keys>0)
                keyok = 1;//按键松开,建立事件标志
        }
    }
   
}

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()
}

    下面是中断处理函数,也是自动生成的,我在其中添加了翻转LED灯的语句,以便观察,同时在此设置断点,调试时不会执行到此处:
#include "interrupt_manager.h"
#include "mcc.h"
#include "pin_manager.h"

void __interrupt() INTERRUPT_InterruptManager (void)
{
    // interrupt handler
    IO_RA2_Toggle();
    if(PIE0bits.TMR0IE == 1 && PIR0bits.TMR0IF == 1)
    {
        TMR0_ISR();
    }
    else if(PIE0bits.INTE == 1 && PIR0bits.INTF == 1)
    {
        INT_ISR();
    }
    else
    {
        //Unhandled Interrupt
    }
}

    下面是主程序,按照初始化,开总中断,开定时器0中断,进入while循环的步骤执行,调试时能够顺利进入循环:
#include "mcc_generated_files/mcc.h"

uint8_t keys,keyok,mode,rxData;
uint16_t ms;

void delay_ms(uint16_t times);
/*
                         Main application
*/
void main(void)
{
    // initialize the device
    SYSTEM_Initialize();

    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:

    // Enable the Global Interrupts启用全局中断(INTCONbits.GIE = 1)。
    INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts启用外围设备中断(INTCONbits.PEIE = 1)
    INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
   
    IO_RA2_SetLow();
    for(mode=0;mode<6;mode++){
        delay_ms(500);
        IO_RA2_Toggle();
    }
    mode = 33;
    IO_RA2_SetHigh();
    //INTERRUPT_PeripheralInterruptDisable();
    TMR0_StartTimer();      //T0CON0bits.T0EN = 1;
   
    while (1)
    {
        // Add your application code
        if(keyok>0){
            EUSART1_Write(keys);
            keys = 0;
            keyok = 0;  //取消按键事件标志
        }
        if(ms>5){
            ms = 0;
            mode++;
            if(mode>120)
                mode = 33;
            EUSART1_Write(mode);
        }
        if(0==IO_RC2_GetValue()){
            IO_RA2_SetLow();
            delay_ms(200);
            IO_RA2_SetHigh();
        }
        // Logic to echo received data
        if(EUSART1_is_rx_ready())
        {
            IO_RA2_SetLow();
            rxData = EUSART1_Read();
            if(EUSART1_is_tx_ready())
            {
                EUSART1_Write(rxData);
            }
//            delay_ms(500);
            IO_RA2_SetHigh();
        }
    }
}

void delay_ms(uint16_t times)
{
    uint16_t t,r;
    for(t=times;t>0;t--)
        for(r=110;r>0;r--);
}
    这是整个项目打包:
alarm.rar (1006.95 KB)

使用特权

评论回复
沙发
hu9jj|  楼主 | 2019-6-9 17:15 | 只看该作者
找到原因了,原来是定时器0的时钟源选择与系统配置的不一致,修改成系统配置之后就正常了。
就此结贴。

使用特权

评论回复
板凳
CoolSilicon| | 2019-6-10 08:21 | 只看该作者

使用特权

评论回复
地板
奔波儿熊| | 2019-6-10 17:09 | 只看该作者
楼主现在成长迅速啊

使用特权

评论回复
5
hu9jj|  楼主 | 2019-6-10 22:05 | 只看该作者
奔波儿熊 发表于 2019-6-10 17:09
楼主现在成长迅速啊

谢谢鼓励!拿到了板子,想尽快熟悉,只有反复操练。

使用特权

评论回复
6
643757107| | 2019-6-11 19:44 | 只看该作者
前后一致很重要啊

使用特权

评论回复
7
hu9jj|  楼主 | 2019-6-11 21:21 | 只看该作者
643757107 发表于 2019-6-11 19:44
前后一致很重要啊

是啊,就因为这个问题,浪费了几天时间。

使用特权

评论回复
8
zljiu| | 2019-6-12 15:12 | 只看该作者
楼主用的是中断吗

使用特权

评论回复
9
coshi| | 2019-6-12 15:17 | 只看该作者
楼主能说说怎么找到的原因吗 我也好借鉴一下

使用特权

评论回复
10
hu9jj|  楼主 | 2019-6-12 16:05 | 只看该作者
zljiu 发表于 2019-6-12 15:12
楼主用的是中断吗

是的,通过定时器产生的中断来处理按键。

使用特权

评论回复
11
hu9jj|  楼主 | 2019-6-12 16:07 | 只看该作者
coshi 发表于 2019-6-12 15:17
楼主能说说怎么找到的原因吗 我也好借鉴一下

原因在2楼已经说过了,是时钟源选择与系统配置不一致。具体可参考我的这个帖子:https://bbs.21ic.com/icview-2821656-1-1.html

使用特权

评论回复
12
zljiu| | 2019-6-19 12:35 | 只看该作者
hu9jj 发表于 2019-6-12 16:05
是的,通过定时器产生的中断来处理按键。

好的 非常感谢解答

使用特权

评论回复
13
coshi| | 2019-6-19 12:41 | 只看该作者
hu9jj 发表于 2019-6-12 16:07
原因在2楼已经说过了,是时钟源选择与系统配置不一致。具体可参考我的这个帖子:https://bbs.21ic.com/icv ...

好的 非常感谢

使用特权

评论回复
14
cyb999| | 2020-8-7 09:11 | 只看该作者
楼主楼主,系统如果用INTOSC是不是Tim0就不能正常工作了,Tim0的时钟源没有这个选择

使用特权

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

本版积分规则

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

144

主题

1031

帖子

11

粉丝