4740|6

61

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

求助:MSP430F149采样问题 [复制链接]

各位大侠,帮小弟看看这个问题:
我想用430做数据采集,双通道数据采集,每个通道采集64个点之后,通过IO口来发送,现在是ADC这块都有问题。采样频率为20KHz以上,使用TIMERA.OUT1为触发源。
问题是:我单步运行运行到ADCTL0 |= ADC12SC;这条语句是,就不能再单步运行了,我整体运行程序,会产生ADCMEM0和ADCMEM1中有数据,缓冲区result1和result2只有result[0]result1[0]中有数据,其他为0。
这到底怎么回事啊,我的程序有问题吗?谢谢大家我的程序如下:
/名字:ADC12_DATA
//实现功能:使用MSP430内部的ADC模块,并且通过IO口将数据送到DSP的SDRAM
//时间:2009、5、1

#include <MSP430x14x.h>

#define Num_result 64
#define ADCOK 0x01 //ADC转换结束标志
#define Sample_fre 200
void init(void); //系统初始化
void ADC_init (void); //初始化ADC12
void timer_A_init(void); //初始化TIMERA
void clk_init (void); //初始化时钟

//全局变量
unsigned char gbit;
int results1[Num_result] = {0};
int results2[Num_result] = {0};
unsigned char results1_buff[Num_result] = {0}; //缓冲区1
unsigned char results2_buff[Num_result] = {0}; //缓冲区2
//****************************************************************************
//主程序
void main(void)
{
init();
for (;;)
{
LPM0;
ADC12CTL0 |= ADC12SC; //sampling open,AD转换完成后(ADC12BUSY=0),ADC12SC自动复位;
while((gbit & ADCOK) == ADCOK )
{
gbit &= ~ADCOK; //清转换完成标志

}
}

}

//****************************************************************************
//系统初始化

void init(void)
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
P1OUT |= BIT0;
P1DIR |= BIT0;
clk_init(); //初始化时钟
timer_A_init(); //初始化TIMERA
ADC_init(); //初始化ADC
// hpi_init(); //初始化HPI
gbit=0x00;
_EINT();
}


//****************************************************************************
//时钟初始化
void clk_init(void)
{
unsigned int i;
BCSCTL1 = 0x00; //将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为
do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1
BCSCTL2 = 0x00; //将寄存器的内容清零
BCSCTL2 += SELM_2; //MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK
BCSCTL2 += DIVS_1; //分频因子为1
}

//****************************************************************************
//初始化定时器A

void timer_A_init(void)
{
// TACTL = TASSEL1 + TACLR; //选择SMCLK,分频因子为1
//CCTL0 = CCIE; //CCR0允许中断
TACTL = TASSEL_1 + MC_1; //增计数模式
TACCTL1 |= OUTMOD_2; //PWM置位/复位
TACCR0 = 1666;
TACCR1 = 833; //时间间隔为20KHz
}


//****************************************************************************
//初始化ADC

void ADC_init(void)
{
//ADC12设置**************************
P6SEL |= 0x03; //使用A/D通道 A0,A1
ADC12CTL0 = ADC12ON+MSC+SHT0_2 ; //开ADC12内核,设SHT0=2 (N=4)
ADC12CTL1 = SHP+CONSEQ_1+SHS_1 ; //SAMPCON信号选为采样定时器输出,序列单次,Timer_A.OUT1采样时钟源
//ADC12内部参考电压设置
ADC12CTL0 |= REF2_5V; //选用内部参考电压为2.5V
ADC12CTL0 |= REFON; //内部参考电压打开
ADC12MCTL0 |= SREF_1+INCH_0; //R+=2.5V R-=VSS,A6输入

ADC12MCTL1 |= SREF_1+INCH_1+EOS; //R+=2.5V R-=VSS,A7输入,结束位

ADC12IE =0x0002; //使能中断ADC12IFG A1
ADC12CTL0 |= ENC;
}

//****************************************************************************
//ADC中断程序

#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR(void)
{
int i;
static unsigned int index = 0;
_NOP();
results1[index] = ADC12MEM0; //转移数据
results2[index] = ADC12MEM1;
index = index+1;
P1OUT ^= BIT0;
if (index == Num_result)
{
ADC12CTL0 &= ~ENC; //停止ADC工作
index = 0;
_NOP();
for(i = 0 ;i<Num_result;i++)
{
results1_buff[i] = results1[i];
results2_buff[i] = results2[i];
}
ADC12CTL0 |= ENC + ADC12SC; //开启转换
gbit |= ADCOK;
LPM3; //进入低功耗模式3,次处可设置断点
}
}

最新回复

说明第一次进入AD中断后就没再进AD中断了,因为第一次进去后你设置了LPM3,这样的话系统相应时钟停止工作,也就是AD的触发源TIMERA.OUT1不再工作了!去掉LPM3试试~  详情 回复 发表于 2013-7-25 19:14
 
点赞 关注(1)

回复
举报

72

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
看代码好像是序列通道单次转换,能先跑个例程吗?
单步到ADCTL0 |= ADC12SC;这条语句是,就不能再单步运行了——是由于前面有LPM0,先把这条语句去掉。

另:你在主程序里使用了LPM0,但没看到哪里有退出这个低功耗的语句?
在ADC转换中断里为什么又进入了LMP3?
是不是程序的逻辑上有些问题?

下面给你一个序列通道单次转换的例程:
#include <msp430x14x.h>

static unsigned int results[4]; // Needs to be global in this example
// Otherwise, the compiler removes it
// because it is not used for anything.

void main(void)
{
WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
P6SEL = 0x0F; // Ena××e A/D channel inputs
ADC12CTL0 = ADC12ON+MSC+SHT0_2; // Turn on ADC12, set sampling time
ADC12CTL1 = SHP+CONSEQ_1; // Use sampling timer, single sequence
ADC12MCTL0 = INCH_0; // ref+=××cc, channel = A0
ADC12MCTL1 = INCH_1; // ref+=××cc, channel = A1
ADC12MCTL2 = INCH_2; // ref+=××cc, channel = A2
ADC12MCTL3 = INCH_3+EOS; // ref+=××cc, channel = A3, end seq.
ADC12IE = 0x08; // Ena××e ADC12IFG.3
ADC12CTL0 |= ENC; // Ena××e conversions

while(1)
{
ADC12CTL0 |= ADC12SC; // Start conversion
_BIS_SR(LPM0_bits + GIE); // Enter LPM0, Ena××e interrupts
}
}

#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{
results[0] = ADC12MEM0; // Move results, IFG is cleared
results[1] = ADC12MEM1; // Move results, IFG is cleared
results[2] = ADC12MEM2; // Move results, IFG is cleared
results[3] = ADC12MEM3; // Move results, IFG is cleared
_BIC_SR_IRQ(LPM0_bits); // Clear LPM0, SET BREAKPOINT HERE
}
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
首先,感谢楼上热心回答我的问题。

我是序列通道单次采集,后面的重复采集是靠定时器TIMERA.OUT1来触发重复采集的。采集好64个点之后,停止ADC,发哦那个数据。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

4
 
程序的问题,本身就比较复杂,而且还与硬件相关;
建议先找TI有无相关例程,拿到类似例程先做测试,无问题后只修改与已相关部分,然后逐步修改到符合自己使用。
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

5
 
行,我在改改,谢谢楼上支招。感激ing
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

6
 
好资料!多谢,看看!~
 
 
 

回复

182

帖子

0

TA的资源

一粒金砂(高级)

7
 
说明第一次进入AD中断后就没再进AD中断了,因为第一次进去后你设置了LPM3,这样的话系统相应时钟停止工作,也就是AD的触发源TIMERA.OUT1不再工作了!去掉LPM3试试~
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表