打印

msp430测脉宽问题

[复制链接]
1885|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
歪三扎愣|  楼主 | 2015-8-3 10:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
代码如下:
#include  <msp430g2553.h>
#include  "12864.h"
#include  "delay.h"
#define uint unsigned int
#define uchar unsigned char
unsigned long int mk=0;
uint num=0;
/************************主函数****************************/
void main(void)
{
    WDTCTL = WDTPW+WDTHOLD;                   //关闭看门狗
   BCSCTL1 = CALBC1_1MHZ;
    DCOCTL = CALDCO_1MHZ;                        // DCO 1MHz
    lcdinit();                               //复位1602液晶
//   LCD_dsp_string(1,0,"占空比:");
    LCD_dsp_string(1,0,"脉宽:");
    LCD_dsp_string(2,0,"脉宽:");
//   LCD_dsp_string(3,0,"脉宽:");
//   LCD_dsp_string(4,0,"脉宽:");
    P1IES = 0;                       // P1.4为 IO中断,上升沿
   P1IE |= BIT4;
//   P1REN |= BIT4;
//   P1OUT &= ~BIT4;                      //下拉电阻
   P1SEL |= BIT0;               //P1.0 ACLK输出
   P1DIR |= BIT0;
    BCSCTL1 |= DIVA_3;
    TACTL |= TACLR;
    TACCTL0 |= CCIE;
//   TACTL = TASSEL_2+MC_2;          //SMCLK 8M,清计数器,使能中断,连续增计模式
   
   while(1)
    {
      _EINT();
      LPM0;
      mk=num*65536+mk;
      if(mk<5000)
      {
        LCD_set_xy(1,3);
        LCD_write_dat('0'+mk/10000);
        LCD_write_dat('0'+mk/1000%10);
        LCD_write_dat('0'+mk/100%10);
        LCD_write_dat('0'+mk/10%10);
        LCD_write_dat('0'+mk%10);
        LCD_write_dat('u');
        LCD_write_dat('s');
      }
      else
      {
        mk=mk/1000;
        LCD_set_xy(1,3);
        LCD_write_dat('0'+mk/10000);
        LCD_write_dat('0'+mk/1000%10);
        LCD_write_dat('0'+mk/100%10);
        LCD_write_dat('0'+mk/10%10);
        LCD_write_dat('0'+mk%10);
        LCD_write_dat('m');
        LCD_write_dat('s');
      }
      num=0;
      TACTL |=TACLR;
      delay_ms(500);
    }
}
/************中断函数****************/
#pragma vector=TIMER0_A0_VECTOR           
__interrupt void TimerA0 (void)
{
   num++;
}
#pragma vector=PORT1_VECTOR                     // P1口中断处理函数
__interrupt void  PORT1_ISR(void)
{
   TACTL = TASSEL_2+MC_2;
   while(P1IN&BIT4 == BIT4);
   TACTL = MC_0;
   __disable_interrupt();
   mk=TAR;
   P1IFG = 0;
   LPM0_EXIT;                    // Clear CPUOFF bit from 0(SR)
}
我是使用的IO中断测的脉宽,可是实际效果不理想,就只是测ACLK8分频后都一直显示五千多ms,求大神助攻,帮忙看看。另外直接使用定时器的捕获测我也试过,但是好像只能测到1K到6K左右。

相关帖子

沙发
dirtwillfly| | 2015-8-3 14:20 | 只看该作者
你要测量的脉宽,大约是什么范围?

使用特权

评论回复
板凳
歪三扎愣|  楼主 | 2015-8-3 15:36 | 只看该作者
dirtwillfly 发表于 2015-8-3 14:20
你要测量的脉宽,大约是什么范围?

1Hz到100K左右,理论上都能达到,不知道为什么就是测不出来,我用F149也试过,不行。。。

使用特权

评论回复
地板
dirtwillfly| | 2015-8-3 16:08 | 只看该作者
歪三扎愣 发表于 2015-8-3 15:36
1Hz到100K左右,理论上都能达到,不知道为什么就是测不出来,我用F149也试过,不行。。。 ...

你的程序思路有些乱。
先考虑测量高频率的脉冲:先设置上升沿触发中断,接收到中断信号后马上改为下降沿触发中断。
这部分做好了,再考虑低频率脉冲的测量。

使用特权

评论回复
5
303413992| | 2015-8-4 08:23 | 只看该作者
高频测量按照楼上的思路   
弄好了之后  低频测量 弄一个变量来存寄存器溢出次数  
然后根据溢出次数+计数器值就有脉宽了

使用特权

评论回复
6
歪三扎愣|  楼主 | 2015-8-4 16:28 | 只看该作者
dirtwillfly 发表于 2015-8-3 16:08
你的程序思路有些乱。
先考虑测量高频率的脉冲:先设置上升沿触发中断,接收到中断信号后马上改为下降沿 ...

这个我用149的定时器捕获试过了,只能测量1K到6KHz左右的脉宽,再往上就测不出来了- -

使用特权

评论回复
7
歪三扎愣|  楼主 | 2015-8-4 16:29 | 只看该作者
303413992 发表于 2015-8-4 08:23
高频测量按照楼上的思路   
弄好了之后  低频测量 弄一个变量来存寄存器溢出次数  
然后根据溢出次数+计数 ...

我用f149试过了,不行好像,只能测1K到6KHz左右的脉宽

使用特权

评论回复
8
歪三扎愣|  楼主 | 2015-8-4 16:32 | 只看该作者
#include  <msp430x14x.h>
#include  "12864.h"
#include  "delay.h"

#define uint unsigned int
#define uchar unsigned char

uint start=0;
uint end=0;
uint tem=0;
uint temp=0,overflow=0;
uint num=0;

void Init_CLK(void)
{
   volatile unsigned int index;
   BCSCTL1&=~0X00; //打开XT2振荡器
   do
   {
     IFG1 &= ~OFIFG; // 清除振荡器失效标志
     for (index = 0xFF; index > 0; index--);// 延时,等待XT2起振
   }
   while ((IFG1 & OFIFG) != 0);// 判断XT2是否起振
   BCSCTL2 =SELM_2+SELS; //选择MCLK、SMCLK为XT2 8MHz
}
/************************主函数****************************/
void main(void)
{
   unsigned long int e,f;
   unsigned int  mk=0,zkb=0;
   WDTCTL = WDTPW+WDTHOLD;                   //关闭看门狗
   Init_CLK();
   lcdinit();                               //复位1602液晶
   LCD_dsp_string(1,0,"占空比:");
   LCD_dsp_string(2,0,"脉宽:");
   P4SEL |= BIT1;                             //设置P4.1端口为功能模块使用
//   P1DIR &=~BIT2;
   P2SEL |= BIT0;     //P2.0 ACLK输出
   P2DIR |= BIT0;
   BCSCTL1 |= DIVA_2;
   TBCTL |= TBCLR;
   TBCTL = TBSSEL_2+MC_2;          //SMCLK 8M,清计数寄存器,连续增计模式
   TBCCTL1 =CM_1+SCS+CAP+CCIE+CCIS_0;     //上升沿捕获,同步,capture模式 CCI1B(P4^1),中断使能
   
  while(1)
   {
       e=overflow*65536+temp-start;
       f=num*65536+end-start;
       mk=(unsigned int)(f/8.0);
       zkb=(unsigned int)((f*1000.0)/e);
       LCD_set_xy(2,3);
       LCD_write_dat('0'+mk/1000);
       LCD_write_dat('0'+mk/100%10);
       LCD_write_dat('0'+mk/10%10);
       LCD_write_dat('0'+mk%10);
       LCD_write_dat('u');
       LCD_write_dat('s');
       LCD_set_xy(1,4);
       LCD_write_dat('0'+zkb/100);
       LCD_write_dat('0'+zkb/10%10);
       LCD_write_dat('.');
       LCD_write_dat('0'+zkb%10);
       LCD_write_dat('%');
       delay_ms(500);
       _EINT();
       LPM0;
   }
}

#pragma vector=TIMERB1_VECTOR              //定时器A中断处理
__interrupt void timer_b(void)
{
  switch(TBIV)                              //向量查询
  {
    case 2:                                //捕获中断
       if(TBCCTL1&CM_1)                      //上升沿
         {
            tem++;
            if(tem==1)
            {
              TBCCTL1=(TBCCTL1&(~CM_1))|CM_2;       //更变设置为下降沿触发
              start=TBCCR1;                      //记录A波初始时间(捕捉产生start)
              overflow=0;                     //溢出计数变量复位
              num=0;
            }
            else if(tem==2)
            {
              tem=0;
              temp=TBCCR1;
              _DINT();
              LPM0_EXIT;
            }
          }
       else if(TBCCTL1&CM_2)                 //下降沿
        {
          TBCCTL1=(TBCCTL1&(~CM_2))|CM_1;       //更变设置为上升沿触发           
          end=TBCCR1;                        //用start,end,overflow计算脉冲宽度
          num=overflow;
        }
        break;
     case 14:                               //定时器溢出中断
       overflow++;
        break;                              //溢出计数加1
     default:break;
   }
}
这是f149测脉宽的,但是效果不理想,麻烦各位大虾帮忙看看哪不行?3Q

使用特权

评论回复
9
303413992| | 2015-8-5 10:32 | 只看该作者
void display();
void IO();
void Delayms1(uint xms);
void InitSys()  
{  
  unsigned int i;   
  BCSCTL1&=~XT2OFF;            //打开XT2振荡器  
  do  
  {  
   IFG1 &= ~OFIFG;             //清除振荡器失效标志  
   for (i = 0xFF; i > 0; i--); //延时,等待XT2起振  
  }  
  while ((IFG1 & OFIFG) != 0); //判断XT2是否起振  
  BCSCTL2 |= SELM_2+SELS;        //选择MCLK、SMCLK为XT2,8M  
}
void main()
{
  WDTCTL = WDTPW + WDTHOLD;
  InitSys();
  P4SEL |=0x01;
  TBCCTL0 |= CM_1 + SCS + CAP +CCIE;
  TBCTL |= TBSSEL_2 + MC_2 + TBIE;
  LcdReset();
  Init_Keypad();
  P5DIR |= BIT1;
  P3DIR |= (BIT1+BIT0+BIT2+BIT3);//P3.1接按键控制个高脉冲,P3.0接控制换(123或恒流源),P3.2和P3.3控制电阻档位
  P5DIR |= BIT4;
  P5OUT&=~BIT4;
  _EINT();


#pragma vector=TIMERB0_VECTOR
__interrupt void TimerB0(void)
{
    if(TBCCTL0&CM1)
    {
        width[m++]=65536*N1+TBCCR0-cap1;
        N1=0;
        flag_IO=1;               //完成一次测量之后继续发脉冲
        TBCCTL0 = CM_1 + SCS + CAP + CCIE;
        if(m==M1)m=0;
    }
    else if(TBCCTL0&CM0)
    {
        cap1=TBCCR0;
        N1=0;
        TBCCTL0 = CM_2 + SCS + CAP + CCIE;
    }
}
#pragma vector=TIMERB1_VECTOR
__interrupt void Timer_B(void)
{
    switch(TBIV)
    {
    case 14: N1++; break;
    }
}
一个用msp430f1611Tb测脉宽的程序    你要想测高频率   就不用把计数器分频了   这样就可以测出最小的脉宽=一个计数周期=1/8Us   

使用特权

评论回复
10
303413992| | 2015-8-5 10:34 | 只看该作者
其他无关的可以忽略  我删减了很多  保留了定时器设置的部分

使用特权

评论回复
11
半个散人| | 2015-8-5 15:43 | 只看该作者
要不用5529,将时钟设置成外部时钟8M试试看?建议,我也不知能不能用

使用特权

评论回复
12
waz668| | 2016-7-30 11:09 | 只看该作者
不。。。得。。。了

使用特权

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

本版积分规则

8

主题

115

帖子

1

粉丝