用G2553测低频脉冲时,在CCS编译运行时测的数值很正常,但是退出编译环境就全乱!测量的值就变得很大,而且没有规律。感觉像是时钟乱了。其中数据我用串口发出。
#include "msp430G2553.h" #include "stdio.h" unsigned long int TA_OverflowCnt=0,Period=0; double X = 0, F=0; char a; char b; char s[3]; void Init_uart0() {
UCA0CTL1|=UCSWRST; P1SEL|=BIT1+BIT2; //将P1.1 P1.2设为第二功能 P1SEL2|=BIT1+BIT2; P1DIR |= BIT2; //P1.2 UART_TX P1DIR &=~BIT1; //P1.1 UART_RX UCA0CTL0&=~UC7BIT;//字符长度为8 UCA0CTL1|=UCSSEL_2;//选择系统时钟 UCA0BR0=0x68; //波特率为9600 UCA0BR1=0; UCA0MCTL=0X40;//UCA0MCTL=UCBRS0; UCA0CTL1&=~UCSWRST;
IE2|=UCA0RXIE;//开接收使能
} void Uart0Sends(char *x) { while(*x!='\0') { UCA0TXBUF=*x;
while((IFG2&UCA0TXIFG)==0); //查询发送是否结束 // IFG2&=~UCA0TXIFG; //清除发送一标志位 x++; //} } } void main( ) { BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; Init_uart0(); WDTCTL = WDTPW + WDTHOLD; TACTL|=TASSEL0+TACLR+TAIE; //时钟源,定时器清零,允许定时器溢出中断 TACTL|=MC1;//Timer_a连续计数模式 P1IE|=BIT4;//允许中断 P1IES|=BIT4;//下降沿触发 P1IFG &=~BIT4;//中断标志清除 _EINT(); //_BIS_SR(CPUOFF+GIE); b=6;
} #pragma vector=PORT1_VECTOR __interrupt void P1_ISR(void) { volatile static unsigned int i=1; // I/O中断计数值 if(P1IFG&BIT4) i++; if(i>=10) // 计数100次 { i=0;
X=(((unsigned long int)TA_OverflowCnt)<<16)+TAR; // 获得100个周期内的时钟个数 F=X/10000; Period=(1/F)*1.6*1.32; TA_OverflowCnt=0; TACTL|=TACLR; // 定时清零
s[0]=Period; s[1]=25; s[2]=32; Uart0Sends(s); X=0; F=0; Period=0; } P1IFG &=~BIT4; // P1.4 IFG cleared; /*用于测试*/
} #pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A (void) { switch(TAIV) // TA中断方式选择 { case 2: break; case 4: break; case 10: TA_OverflowCnt++; // 溢出中断计数加1 break; } }
HG:
大体思路就是中断来时把TACCRx保存,下一个中断沿来时再保存下,两个相减就是脉宽。不过,你的代码太乱了。。。。。。。
Walse Walse:
回复 HG:
你好,这个已经被我改的面目全非了。。。你能帮我看一下吗,这个为什么一退出CCS那个编译,程序就无法正常检测频率了,我程序给你贴一个程序吧。。。
Walse Walse:
回复 HG:
#include "msp430G2553.h"
#include "stdio.h"
unsigned long int TA_OverflowCnt=0,Period=0;
double X = 0, F=0;
char a;
char b;
char s[3];
void Init_uart0() {
UCA0CTL1|=UCSWRST;
P1SEL|=BIT1+BIT2; //将P1.1 P1.2设为第二功能
P1SEL2|=BIT1+BIT2;
P1DIR |= BIT2; //P1.2 UART_TX
P1DIR &=~BIT1; //P1.1 UART_RX
UCA0CTL0&=~UC7BIT;//字符长度为8
UCA0CTL1|=UCSSEL_2;//选择系统时钟
UCA0BR0=0x68; //波特率为9600
UCA0BR1=0;
UCA0MCTL=0X40;//UCA0MCTL=UCBRS0;
UCA0CTL1&=~UCSWRST;
IE2|=UCA0RXIE;//开接收使能
}
void Uart0Sends(char *x)
{ while(*x!='\0')
{
UCA0TXBUF=*x;
while((IFG2&UCA0TXIFG)==0); //查询发送是否结束
x++;
}
}
void main( )
{ WDTCTL = WDTPW + WDTHOLD;
TACTL|=TASSEL0+TACLR+TAIE; //时钟源,定时器清零,允许定时器溢出中断
TACTL|=MC1;//Timer_a连续计数模式
P1IE|=BIT4;//允许中断
P1IES|=BIT4;//下降沿触发
P1IFG &=~BIT4;//中断标志清除
Init_uart0();
_EINT(); //_BIS_SR(CPUOFF+GIE);
}
#pragma vector=PORT1_VECTOR
__interrupt void P1_ISR(void)
{
volatile static unsigned int i=1; // I/O中断计数值
if(P1IFG&BIT4)
i++;
if(i>=10) // 计数10次
{ i=0;
X=(((unsigned long int)TA_OverflowCnt)<<16)+TAR; // 获得10个周期内的时钟个数
F=X/10000;
Period=(1/F)*1.6*1.32;
TA_OverflowCnt=0;
TACTL|=TACLR; // 定时清零
s[0]=Period;
s[1]=25;
s[2]=32;
Uart0Sends(s);
}
P1IFG &=~BIT4;//中断标志清除
}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A (void)
{
switch(TAIV) // TA中断方式选择
{
case 2: break;
case 4: break;
case 10: TA_OverflowCnt++; // 溢出中断计数加1
break;
}
}
HG:
回复 Walse Walse:
我看了下你的程序,中断里太多太多东西了,很不安全。又是浮点,又是uart,建议你简化流程,把相关数据用全局变量保留,尽量把事情挪到中断外面去,想弄一个相对干净的程序出来。
Walse Walse:
回复 HG:
我刚开始的时候也是把发送的部分反正中断以外的,采用while不断将频率发送出去,但是也是一样的情况。就感觉一退出那个编译运行环境,时钟全乱套了。你能帮我看一下那个我的时钟设置是有冲突的地方吗?
HG:
回复 Walse Walse:
时钟没有看出不对的地方,加不加仿真器实际上是非常影响正常时序的,加了仿真器,连着JTAG有时会不一样的。
用示波器量过波形么?对不对?进中断先保存状态,然后先把中断标志清除了。
P1IFG &=~BIT4;//中断标志清除
Walse Walse:
回复 HG:
我用了1.7输出那个时间的脉冲波形,然后什么都没有。
Walse Walse:
回复 HG:
我在那个CCS进行执行的时候,我测试有晶振脉冲的,但是我一退出CCS编译环境就没有晶振输出了!!!!!!