13412|22

164

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【TIVA C Launchpad 学习笔记二】利用定时器的计时捕获模式制作简易频率计 [复制链接]

/*******************************************
开发坏境:CCSv5
程序功能:利用定时器的计时捕获模式制作简易频率计
程序说明:可测方波频率,其它波形应先整形成方波再测频率。最高和最低可测频率
                 为1HZ-100KHZ(很久前测的,现在记不太清了,差不多就是这个范围,
                 具体以实际测量为准)
编程者:Linchpin
********************************************/
#include
#include
#include
#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[i]=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
}

最新回复

谢谢分享   详情 回复 发表于 2018-7-1 10:52
 
点赞 关注(1)

回复
举报

18

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
从头像和传的这几个内容目测是501的~ .~...

点评

啥意思?  详情 回复 发表于 2014-6-16 12:42
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
印象中Edge-Time模式测得范围和精度都更好,430 16M的频率能测到10-600k的范围。

点评

再往下0.1HZ,再往上1MHZ好像也可以做到,但是代码中还有些bug,有时候会测不准。 因为给的题目中要求比较低,所以我也就没往极限做。事实上能做到更高的  详情 回复 发表于 2014-6-16 12:41
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

4
 
ChangC 发表于 2014-6-16 00:17
印象中Edge-Time模式测得范围和精度都更好,430 16M的频率能测到10-600k的范围。

再往下0.1HZ,再往上1MHZ好像也可以做到,但是代码中还有些bug,有时候会测不准。
因为给的题目中要求比较低,所以我也就没往极限做。事实上能做到更高的

点评

刚刚试了一下,主频40M的时候,上限能测到550k左右;主频80M的时候,能测到950k左右~  详情 回复 发表于 2014-6-16 18:30
中断服务函数里头的变量不能这么声明~ .~... (这样的话进不了中断,觉得应该作全局变量声明)。其他的我跑了一下,没啥大问题(删了一些冗余的东西,然后取了个平均,用生成的方波试了一下,精度在+-1这样,上限还没  详情 回复 发表于 2014-6-16 17:46
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

5
 
ChangC 发表于 2014-6-16 00:04
从头像和传的这几个内容目测是501的~ .~...

啥意思?

点评

这难道不是西电的跳楼塔吗~ .~... (难道我狗眼瞎了...)  详情 回复 发表于 2014-6-16 17:31
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

6
 

这难道不是西电的跳楼塔吗~ .~... (难道我狗眼瞎了...)

点评

是西电的,但不是那个实验室的哦。  详情 回复 发表于 2014-6-16 23:17
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

7
 
Linchpin 发表于 2014-6-16 12:41
再往下0.1HZ,再往上1MHZ好像也可以做到,但是代码中还有些bug,有时候会测不准。
因为给的题目中要求比 ...

中断服务函数里头的变量不能这么声明~ .~... (这样的话进不了中断,觉得应该作全局变量声明)。其他的我跑了一下,没啥大问题(删了一些冗余的东西,然后取了个平均,用生成的方波试了一下,精度在+-1这样,上限还没试验),蛮好的,学习了~

我稍微读了一下代码,感觉这个测频的思路应该是利用两次中断来获取两次上升沿的时间差(这样频率的最后一位各种乱跳,我就取了1000次平均,还算消停了点~),然后用系统频率除掉这个时间得到频率,我看了半天那个flag==3是啥玩意~ .~... 真不懂,我觉得用i就可以判断了。

后来我将中断服务函数改成了下面的代码(将TimerIntClear函数放在了最后)。

void WTimer0AIntHandler(void)
{
    t = TimerValueGet64(WTIMER0_BASE);                // 分两次获取WTimer0的值,存入t[0]和t[1]中
    i += 1;
    if (i == 2)        // t[0]和t[1]都获取完成
    {
        time = t[1] - t[0];
        freq = SysCtlClockGet() / time;
        
        sumFreq += freq;
        sampleTimes += 1;
        
        if (sampleTimes == 1000)    // 取1000次平均
        {
            _disp(sumFreq / 1000);
            Disp_Str(1, 0, Data);
            sampleTimes = 0;
            sumFreq = 0;
        }
        i = 0;
    }
   
    TimerIntClear(WTIMER0_BASE, TIMER_CAPA_EVENT);        // 清除WTimer0捕获器A的中断标志位
}

所以我觉得你删掉那个flag,说不定就行了~

点评

恩,代码中确实存在一些问题。非常感谢这位同学,话说都快期末了还在这里研究代码,真是大神啊。  详情 回复 发表于 2014-6-16 23:21
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

8
 
Linchpin 发表于 2014-6-16 12:41
再往下0.1HZ,再往上1MHZ好像也可以做到,但是代码中还有些bug,有时候会测不准。
因为给的题目中要求比 ...

刚刚试了一下,主频40M的时候,上限能测到550k左右;主频80M的时候,能测到950k左右~

点评

恩。。非常感谢。。  详情 回复 发表于 2014-6-16 23:16
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

9
 
ChangC 发表于 2014-6-16 18:30
刚刚试了一下,主频40M的时候,上限能测到550k左右;主频80M的时候,能测到950k左右~

恩。。非常感谢。。
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

10
 
ChangC 发表于 2014-6-16 17:31
这难道不是西电的跳楼塔吗~ .~... (难道我狗眼瞎了...)

是西电的,但不是那个实验室的哦。

点评

这样... 我就想着这塔看得应该错不了~  详情 回复 发表于 2014-6-17 10:54
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

11
 
ChangC 发表于 2014-6-16 17:46
中断服务函数里头的变量不能这么声明~ .~... (这样的话进不了中断,觉得应该作全局变量声明)。其他的我跑 ...

恩,代码中确实存在一些问题。非常感谢这位同学,话说都快期末了还在这里研究代码,真是大神啊。

点评

是啊! 期。末。了...  详情 回复 发表于 2014-6-17 10:55
 
 
 

回复

211

帖子

0

TA的资源

一粒金砂(高级)

12
 
LZ 西电的?

点评

哈哈,看来这里好多xidianer  详情 回复 发表于 2014-6-17 12:34
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

13
 
Linchpin 发表于 2014-6-16 23:17
是西电的,但不是那个实验室的哦。

这样... 我就想着这塔看得应该错不了~

 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

14
 
Linchpin 发表于 2014-6-16 23:21
恩,代码中确实存在一些问题。非常感谢这位同学,话说都快期末了还在这里研究代码,真是大神啊。:lovelin ...

是啊! 期。末。了...

点评

你是哪个院的呀?  详情 回复 发表于 2014-6-17 12:34
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

15
 
ChangC 发表于 2014-6-17 10:55
是啊! 期。末。了...

你是哪个院的呀?

点评

电院 你呢?  详情 回复 发表于 2014-6-17 13:03
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

16
 

哈哈,看来这里好多xidianer
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

17
 
Linchpin 发表于 2014-6-17 12:34
你是哪个院的呀?

电院 你呢?

点评

物光院。。电院都是大神呀,还有很多牛逼老师。。像我们这种连指导老师都没有的小院  详情 回复 发表于 2014-6-17 13:46
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

18
 

物光院。。电院都是大神呀,还有很多牛逼老师。。像我们这种连指导老师都没有的小院

点评

哪都有大牛的~ 和什么院没啥关系  详情 回复 发表于 2014-6-17 16:49
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

19
 
Linchpin 发表于 2014-6-17 13:46
物光院。。电院都是大神呀,还有很多牛逼老师。。像我们这种连指导老师都没有的小院

哪都有大牛的~ 和什么院没啥关系

 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

20
 
请问下现在代码修改好了吗,能直接运行吗
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表