This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TimerValueGet 函数在中断中不可用

Other Parts Discussed in Thread: TM4C123GH6PM

我将TIMER0配置为周期减计数模式, 在中断中读取当前计数值

  

如图, 判断F4管脚上升沿之后, 读取TIMER0计数器的当前值, 发现读不到。

之前配置的TIMER0模式, LOAD值是50M, 所以上图中那个数肯定不对的。

事实上, 我在main函数的一个循环中不停打印TimerValueGet 函数得到的值,可以看到正确读出, 数值确实在周期减少。

使用芯片是tm4c123gh6pm, TIMER0是两个16位计时器拼起来的, 调用TimerValueGet 函数时, 第二个值给TIMER_A 这个宏即可(uer guide是这么说的, 我在main函数中也是这么用的)。

现在的问题是, 这个函数在主函数中可以正常传参数, 在中断中不行。

  • 还有一个问题是, 只有32位timer配置为周期减计数才能正常工作。

    one shot 减计数就停在初始值不变,

    加计数也停在初始值不变。

    64位不管怎样都不变

  • 1.你选用的是计数模式还是计时模式

    2.你需要给你的上升沿计数呢,还是计算两个电平之间的时间呢

    3.看你的设置是为计数模式,那么你触发的应该是匹配中断,上你全部的程序,或者你把自己需要的脉络理清楚

  • 上你的流程图,看看寄存器的配置对不对,还有,你要抓寄存器中的值,有时候库函数中改变的寄存器你不知道

  • 1 计时模式

    2 测量脉宽, 在五毫秒以内, 频率50hz

    3 第一张图就是中断处理, 现象是timer value get函数返回值传不到变量里。 第二张是timer配置部分,可以看到初始值50M, 向下计数。

  • 1 计时模式

    2 测量脉宽, 脉宽5毫秒以内, 频率50Hz。

    3 思路是上升沿记录当前TIMER值, 下降沿再记录, 两者相减。 现在问题是TIMER VALUE GET这个函数的返回值读不到。 第一张图是中断处理函数, 那个数明显不对。 第二张图是TIMER配置。

  • 你的思路是不对的,两者相减,不是这么单纯的减的

    给你看看官方给的图,你就明白了

    /*************

    然后GPTM 让GPTM 原始中断状态(GPTMRIS) 寄存器中的CnERIS 位有效,并保持该值直到向GPTM 中断清除(GPTMICR) 寄存器执行写操作将其清零。如果在GPTM 中断屏蔽(GPTMIMR) 寄存器中启用捕获模式事件中断,GPTM 还会将GPTM 屏蔽的中断状态(GPTMMIS)寄存器中的CnEMIS 位置位。这种模式下,GPTMTnR 和GPTMTnPS 寄存器将保存发生选定输入事件的时间。

    ***************/

    我看在中断中第一次值变了,以后就没变,你清中断标志了没

  • 给你一个别人的例程看看

    /*******************************************
    开发坏境:CCSv5
    程序功能:利用定时器的计时捕获模式制作简易频率计
    程序说明:可测方波频率,其它波形应先整形成方波再测频率。最高和最低可测频率
                     为1HZ-100KHZ(很久前测的,现在记不太清了,差不多就是这个范围,
                     具体以实际测量为准)
    编程者:Linchpin
    ********************************************/
    #include <stdint.h>
    #include <stdbool.h>
    #include <math.h>
    #include "inc/tm4c123gh6pm.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/timer.h"
    #include "driverlib/fpu.h"
    #include "driverlib/sysctl.h"
    #include "grlib/grlib.h"
    #include "driverlib/adc.h"
    #include "inc/hw_gpio.h"
    #define uchar unsigned char
    #define uint unsigned int
    //16位捕获引脚PB6,32位捕获引脚PC4
    void delay_Nms(uint n);
    void Ini_Lcd(void);
    void write_com(uchar com);
    void write_dat(uchar dat);
    uchar const disps[]={"波的频率为:"};
    
    int main(void)
    {
        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
            //5分频,使用PLL,外部晶振16M,system时钟源选择 main osc。系统时钟40MHZ
        SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);
                //使能TIMER0
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
            //使能GPIOF和GPIOC外设
            GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
            GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_4);
            GPIOPinConfigure(GPIO_PC4_WT0CCP0);    //#define GPIO_PC4_WT0CCP0   0x00021007
            GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_4);
        TimerConfigure(WTIMER0_BASE,TIMER_CFG_A_CAP_TIME_UP|TIMER_CFG_SPLIT_PAIR);//计时捕获模式,上升沿捕获
            TimerControlEvent(WTIMER0_BASE,TIMER_A,TIMER_EVENT_POS_EDGE);
            IntEnable(INT_WTIMER0A);
            //使能TIMER0A
            TimerIntEnable(WTIMER0_BASE, TIMER_CAPA_EVENT);
            //定时器A捕获事件触发中断
            IntMasterEnable();
        //master interrupt enable API for all interrupts
            TimerEnable(WTIMER0_BASE, TIMER_A);
        //TIMER0A开始计数,当计数值等于TimerLoadSet,触发中断
        while(1)
            {
            }
    }
    
    void WTimer0IntHandler(void)
    {
    
            uchar c[10],d[3],flag=0;
            long int t[12],j;
            double f,time=0;
            int i=0;
    
            TimerIntClear(WTIMER0_BASE, TIMER_CAPA_EVENT);
        t=TimerValueGet64(WTIMER0_BASE);
            i++;
            time=labs(t[1]-t[0]);
        if(i==2) {i=0;}
            flag++;
            if(flag==3)//显示
            {
                    f=40000000.0/time;
                    int a,aa,bb,m=0,k=0;
                    double b;
                    a= (int)f;//a= 1234
                    b= f - a;//b= 0.5678
                    for(j=a;j>0;j=j/10)
                    {
                            c[k++]=j%10;
                    }
                    bb=(int)(b*1000);
    
                    for(j=bb;m<3;j=j/10)
                    {
                            d[m++]=j%10;
                    }
    
                    Ini_Lcd();
                    for(aa=0;aa<12;aa++)
                    {
                             write_dat(disps[aa]);
                    }
                    write_com(0x90);
                    for(j=k-1;j>=0;j--)
                    {        write_dat(c[j]+48);}
                    write_dat('.');
                    for(j=2;j>=0;j--)
                    {        write_dat(d[j]+48);}
                    write_dat('H');
                    write_dat('Z');
        }
    
    }
    
    
    
    /*******************************************
    函数名称:delay_Nms
    功    能:延时N个ms的时间
    参    数:无
    返回值  :无
    ********************************************/
    void delay_Nms(uint n)
    {
        uint i = 0;
        for(i = n;i > 0;i--)
                SysCtlDelay(SysCtlClockGet() / 3000);
    }
    /*******************************************
    函数名称:Ini_Lcd
    功    能:初始化液晶模块
    参    数:无
    返回值  :无
    ********************************************/
    void Ini_Lcd(void)
    {
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);//使能GPIOA
            GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);//PA2,3,4设为输出
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//使能GPIOB
        GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                            GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);//PB设为输出
        delay_Nms(15);                     //延时等待液晶完成复位
            GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
            delay_Nms(5);
            write_com(0x30);  /*功能设置:一次送8位数据,基本指令集*/
    
            delay_Nms(1);
        write_com(0x08);  /*DDRAM地址归位*/
            delay_Nms(1);
            write_com(0x0c);  /*显示设定:开显示,不显示光标,不做当前显示位反白闪动*/
            delay_Nms(1);
            write_com(0x01);  /*清屏,将DDRAM的位址计数器调整为“00H”*/
            delay_Nms(1);
            write_com(0x06);  /*功能设置,点设定:显示字符/光标从左到右移位,DDRAM地址加1*/
            delay_Nms(5);
            write_com(0x80);
    }
    
    /**************************************************
    *名称:void write_com(uchar com)
    *功能:向1602写指令
    *入口参数:com
    *出口参数:无
    **************************************************/
    void write_com(uchar com)
    {
        GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_2|GPIO_PIN_3, 0x00000);//RS=0,RW=0
            GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                            GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, com);    //PB=com
            delay_Nms(5);
        GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, GPIO_PIN_4);   //E=1
        delay_Nms(5);
        GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, 0x00000);   //E=0
    }
    
    /**************************************************
    *名称:void write_dat(uchar dat)
    *功能:向1602写数据
    *入口参数:dat
    *出口参数:无
    **************************************************/
    void write_dat(uchar dat)
    {
            GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_2 );//RS=1,RW=0
            GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                                    GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, dat);  //PB=dat
            delay_Nms(5);
            GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4,GPIO_PIN_4);   //E=1
            delay_Nms(5);
            GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
    }