社区导航

 
快捷导航
  • 首页
  • 论坛
  • 查看新帖
  • 最新回复
  • 社区活动
  • 联系管理员
  • 消灭零回复
  • E金币兑换
  • 干货
搜索
查看: 529|回复: 8

[求助] msp430测量方波频率

[复制链接]

20

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2018-4-9 20:47:15 | 显示全部楼层 |阅读模式
今天看了mcu工程师炼成记,写了个代码。
我的思路是计算两次上升沿捕获到的定时器值的差,小于0就加上65536。通过这个差值,再乘以定时器时钟周期就是所测得的方波周期。
测试时我用P1.0输出的aclk信号连接接受捕获信号的引脚P1.1进行测试,但是测试时发现差值一直变化非常大。我实在是没看出来。还麻烦大家看看哪有问题。备注都很清楚。谢谢大家!
#include <msp430.h>
#define uint unsigned int
#define uchar unsigned char
uint new_cap=0;
uint old_cap=0;
uint cap_diff=0;
uint cap_diff2=0;
uint j=0;
uint i;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
for(i=0;i<20000;i++);//等晶振稳定震荡
P1DIR=0x41;//P1.0输出ACLK,P1.6为LED设置为输出
P1SEL=0X03;//P1.0输出ACLK信号,为第二功能。P1.1引脚作输入接受捕获信号,为第二功能。
CCTL0=CM_1+CCIS_0+SCS+CAP+CCIE;//上升沿捕获+P1.1捕捉CCI0A 输入+同步+捕获模式+开始中断
TACTL=TASSEL_2+MC_2;//SMCLK时钟+连续模式
_BIS_SR(LPM0_bits+GIE);
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A(void)
{
P1OUT^=0x40;//led翻转
j++;
if(j%2>=1)
old_cap=TACCR0;//第一次捕获上升沿时,定时器的值
if(j%2==0)
{
new_cap=TACCR0;//第二次捕获上升沿时,定时器的值
if(new_cap<old_cap)
cap_diff=65536+new_cap-old_cap;//两次相减得到一个周期内定时器的计数
else
cap_diff=new_cap-old_cap;//两次相减得到一个周期内定时器的计数
CCTL0&=~CCIE;//两次捕获完成之后关中断。方便调试
}

此帖出自MSP430论坛


回复

使用道具 举报

3169

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2018-4-10 08:25:45 | 显示全部楼层
被测信号周期不能大于计数周期,否则要扩展计数范围
别的没看出问题,你用示波器看一下led的信号


回复

使用道具 举报

20

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-4-10 12:40:18 | 显示全部楼层
huo_hu 发表于 2018-4-10 08:25
被测信号周期不能大于计数周期,否则要扩展计数范围
别的没看出问题,你用示波器看一下led的信号

我是这样理解你说的被测信号周期不能大于计数周期的,您看下对没对。
我直接用的p1.0的第二功能输出aclk信号输入捕获引脚p1.1。辅助时钟ACLK由外部低频晶振产生,一般为32.768kHz。计数时钟用的是SMCLK,SMCLK由内部数控震荡器DCO产生,大约在1.1MHz左右。
计数周期为1/1100000*65536=0.059578。被测信号周期为1/32768=0.0000305。被测信号周期小于计数周期。是这样吧版主。谢谢版主!


回复

使用道具 举报

3169

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2018-4-10 17:18:21 | 显示全部楼层
是这个意思,如果你的两个上升沿跨过了两个计数周期,那算法就不对了.
另外程序可以再优化成每次计算,
新数和上次求差
保存本次计数,下次才来就是旧数了


回复

使用道具 举报

20

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-4-11 10:40:17 | 显示全部楼层
huo_hu 发表于 2018-4-10 17:18
是这个意思,如果你的两个上升沿跨过了两个计数周期,那算法就不对了.
另外程序可以再优化成每次计算,
新数 ...

额我找到为什么我测试结果没对了。今天我用函数发生器测试,程序完全正确。我之前用的430内部的aclk时钟信号作为捕获信号,我用示波器看了,aclk信号不是固定频率的,他在一段时间频率会突变,所以造成同一信号差值发生变化。
不过我对您的优化不是很懂。新数和上次求差,就是一个周期定时器计数值啊,保留计数,下次才来的就是旧数这个我确实没理解版主的意思,还望版主指点


回复

使用道具 举报

3169

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2018-4-11 13:25:44 | 显示全部楼层
uint ole_cap;
__interrupt void Timer_A(void)
{
uint new_cap;
P1OUT^=0x40;//led翻转
new_cap=TACCR0;//
if(old_cap<new_cap)
cap_diff=65536+new_cap-old_cap;//两次相减得到一个周期内定时器的计数
else
cap_diff=new_cap-old_cap;//两次相减得到一个周期内定时器的计数
old_cap=new_cap;
CCTL0&=~CCIE;//两次捕获完成之后关中断。方便调试
}

点评

谢谢版主  详情 回复 发表于 2018-4-11 19:47


回复

使用道具 举报

3169

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2018-4-11 13:27:26 | 显示全部楼层
aclk跳变不应该啊,是不是供电有问题


回复

使用道具 举报

20

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-4-11 19:47:19 | 显示全部楼层
huo_hu 发表于 2018-4-11 13:27
aclk跳变不应该啊,是不是供电有问题

懂了版主的改进方法了。供电这不知道有问题没,就是430的launchpad,直接接电脑上供电的啊


回复

使用道具 举报

20

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-4-11 19:47:33 | 显示全部楼层
huo_hu 发表于 2018-4-11 13:25
uint ole_cap;
__interrupt void Timer_A(void)
{
uint new_cap;
P1OUT^=0x40;//led翻转
new_cap=T ...

谢谢版主


回复

使用道具 举报

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

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-7-23 10:00 , Processed in 0.352839 second(s), 16 queries , Gzip On, Redis On.

快速回复 返回顶部 返回列表