打印

求助利用TA中断采集电压信号的问题

[复制链接]
444|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Rospiers|  楼主 | 2018-1-25 14:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
思路是利用TA CCR0和CCR2中断,转变flag,然后在主程序里赋值,结果是第一次采样得到的值是270,后来每次采样都是800多,实际电压值换算过来是270,也就是说只有第一次采样正确。。。不知道为什么。。。。。。后来还要实现很多功能,这个结构写的比较乱,但是基本采样可以实现,只是采到的数据只有第一次正确,想了很久了,不知道原因,求助各位大大!!!


#include "io430x54x.h"
#include "adc12.h"
#include "in430.h"
/*初始化电源*/
void Init_Power()
{
  P10DIR |= BIT0;
  P10OUT |= BIT0;
  P10DIR |= BIT2;
  P10OUT |= BIT2;
}
//这个函数用来产生5MHz的时钟信号
void InitClock()
{
P1DIR |= BIT0;
P1SEL |= BIT0; //ACLK output,这时候可以使用示波器观察时钟信号
UCSCTL3 |= SELREF_2; // FLLref = REFO
UCSCTL4 = SELM__DCOCLKDIV + SELS__DCOCLKDIV + SELA__DCOCLKDIV;// 时钟来源:主系统时钟来源DCOCLKDIV;子系统时钟来源DCOCLKDIV;辅助系统时钟来源DCOCLKDIV
UCSCTL5 |= DIVM__1 + DIVS__4 + DIVA__1; // 分频:主系统时钟1分频;子系统时钟16分频;辅助系统时钟1分频
__bis_SR_register(SCG0); // Disable FLL
UCSCTL1 = DCORSEL_6; // 10.7MHz<Fdco<39MHz
UCSCTL2 |= FLLD__2 +151 ; // 约5MHz DCOCLKDIV Fdco/4
__bic_SR_register(SCG0); // Enable FLL
// 等待错误标志清除,振动器稳定
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
/*void Init_UART_3()
{
  P10SEL |= 0x30;         // P10_4和P10_5第二功能打开,设置方向
  P10DIR |= 0x10;
  UCA3CTL1 |= UCSWRST;  // 首先使RST位置位,只有这样后面的设置才有效
  UCA3CTL1 |= UCSSEL_2; // SMCLK,为系统时钟1048576Hz
  UCA3BR0 = 9;          // 1MHz 115200
  UCA3BR1 = 0;          // 1MHz 115200
  UCA3MCTL |= UCBRS_1 + UCBRF_0; // 设置调整参数UCBRSx=1, UCBRFx=0
  UCA3CTL1 &= ~UCSWRST; // RST复位
  //UCA3IE |= UCTXIE; // 使能发送中断允许
}*/

//初始化Timer_A1
void Init_Timer_A()
{
P7DIR |= 0x08; // P7.3 output
P7SEL |= 0x08; // P7.3 options select
P11DIR |= 0x01; // P11.0 output red_LED
P11OUT &= ~BIT0; //输出低电平 LED灯亮
TA1CCTL0 = CCIE; // CCR0 interrupt enabled
TA1CCR0 = 10000; //设置周期为40ms
TA1CCTL2 = OUTMOD_3+CCIE; // CCR2 set/reset
TA1CCR2 = 8000; // CCR2 original PWM duty cycle 1/5
TA1CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR
}
volatile unsigned Point_1,Point_2;
double Point_now ;
double temperature_now;
double i;
int flag,flag2;
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR(void)
{
switch(__even_in_range(TA1IV,14))
{
case 0: break; // No interrupt
case 2: break; // CCR1 not used
case 4: flag2 = 1;
         flag = 0;
           break;
case 6: break; // reserved
case 8: break; // reserved
case 10: break; // reserved
case 12: break; // reserved
case 14: break; // overflow
default: break;
}

}
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
P11OUT ^= 0x01; // Toggle触发 P11.0
flag = 1;
flag2 = 0;
}

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;              // Stop WDT
  Init_Power();
  InitClock();                           //初始化时钟
  
  Init_Timer_A();                 //初始化定时器A1
   
  InitADC12();                           //初始化ADC12
  
  //Init_UART_3();                         //初始化UART
  
  _EINT();
  _NOP();
  while(1)
  {
   
   
    if(flag==1)
    {
       flag=0;
       Point_2=(int)read_avg();
        Point_now = 0.2 * i + 0.8 * Point_2;
        Point_2=0;
        
        //__bis_SR_register(LPM0_bits + GIE);
     }
     else if(flag2==1)
    {
       flag2=0;
      Point_1=(int)read_avg();
      i = Point_1;
        Point_1=0;
//Point_now = 0.2 * i + 0.8 * Point_2;
     }
   

  }                       
     

  
}



#include "msp430x54x.h"
void InitADC12()
{
  ADC12CTL0 &= ~ADC12ENC;
  P6SEL |= 0x10;                                                          // Enable P6.4 as A/D channel input
  ADC12CTL0 = ADC12ON + ADC12SHT0_2;                             // Turn on ADC12, set sampling time, 16ADC12CLK cycles
  ADC12CTL1 = ADC12SHP + ADC12CONSEQ_0 + ADC12SSEL_2;   // Use sampling timer, single time single channel,MCLK=4M
  ADC12MCTL0 = ADC12SREF_2 + ADC12INCH_4;                                 // ref+ = VeREF+, ref- = AVSS, channel = A4
  //ADC12IE = ADC12IE0;                                                         // Enable ADC12IFG.0
  //ADC12CTL0 |= ADC12ENC;                                                  // Enable conversions
}
unsigned int read_ad()                   //开启一次AD转换,并读值
{
  unsigned int ad_value;
  ADC12CTL0|=ADC12SC + ADC12ENC;                   //给转换开始脉冲        
  //ADC12CTL0&=~ADC12SC;

  while((ADC12CTL1&0X01)==1);           //ADC转换忙信号时等待
  ad_value=ADC12MEM0;                   //读取转换结果值
  ADC12CTL0 &= ~ADC12ENC;
  return ad_value;
}
long read_avg()                 //数字滤波
{
  long ad_avg=0;                //滤波次数,滤波累加变量
  unsigned int flt_t;
  for(flt_t=0;flt_t<500;flt_t++)   
  {
    ad_avg+=read_ad();
  }
  ad_avg/=500;
  return ad_avg;
}


//ADC12模块初始化及读值函数
#ifndef __ADC12_H
#define __ADC12_H
void InitADC12();                 //初始化ADC12
unsigned int read_ad();          //开启一次AD转换并读值
long read_avg();          //数字滤波
#endif

相关帖子

沙发
Lewisnx| | 2018-1-25 15:02 | 只看该作者
先测试单次ADC转换是否正确,read_ad()多调用几次,调试查看每次转换是否都是对的,如果都是对的再进行下一步判断

使用特权

评论回复
板凳
CCompton| | 2018-1-25 15:16 | 只看该作者
改变ADC12SHT0_2的值(改为ADC12SHT0_15),第一次采样正确为266,第二次为1200多,之后一直稳定在1200多。当改为ADC12SHT0_0时,第一次采样正确为266,第二次为560多,之后一直稳定在560多.这是啥原因啊

使用特权

评论回复
地板
Richardd| | 2018-1-25 15:33 | 只看该作者
读取的数据不对吧,怎么是ADC12MEM0

使用特权

评论回复
5
Mattheww| | 2018-1-25 15:59 | 只看该作者
这个现象就是你的第一次采样时对的,后面存储不对,指定对应存储地址

使用特权

评论回复
评论
dirtwillfly 2018-1-25 19:57 回复TA
有这种可能 
6
Erichk| | 2018-1-25 16:25 | 只看该作者
什么采样方法,单通道单次采样??

使用特权

评论回复
7
dirtwillfly| | 2018-1-25 20:01 | 只看该作者
也有可能是adc外部电路的阻抗不匹配

使用特权

评论回复
8
mmbs| | 2018-2-3 21:33 | 只看该作者
这个转换原理是什么

使用特权

评论回复
9
1988020566| | 2018-2-3 21:34 | 只看该作者
是不是需要滤波算法

使用特权

评论回复
10
lzbf| | 2018-2-3 21:34 | 只看该作者
TA中断是怎么实现数据转的?

使用特权

评论回复
11
houjiakai| | 2018-2-3 21:35 | 只看该作者
还不如使用MSP430的ADC呢

使用特权

评论回复
12
youtome| | 2018-2-3 21:35 | 只看该作者
可能有干扰。

使用特权

评论回复
13
mmbs| | 2018-2-3 21:35 | 只看该作者
使用是什么转换芯片?

使用特权

评论回复
14
1988020566| | 2018-2-3 21:35 | 只看该作者
中值滤波能不能行?

使用特权

评论回复
15
lzbf| | 2018-2-3 21:36 | 只看该作者
不是应该ADC吗?

使用特权

评论回复
16
youtome| | 2018-2-3 21:36 | 只看该作者
是不是基准信号有变动呢?

使用特权

评论回复
17
houjiakai| | 2018-2-3 21:36 | 只看该作者
外部的ADC精度高。

使用特权

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

本版积分规则

116

主题

377

帖子

0

粉丝