1707|0

2015

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

MSP430F1232针对ADC10(使用DTC+SA)的内存中采样结果读取 [复制链接]

定义一个指针,让它指向内存的某个地址,然后通过指针就可以访问。如果需要访问地址为0x210的内存单元(MSP430的ram起始地址是0x200),则可以这样:
char a;
char *p;
p=0x210;
*p=90;//在地址为0x210的内存单元存入一个数字90
a= *p;//将地址为0x210的内存单元中的数字读出赋值给a其实不光是430单片机,其他各种单片也是如此操作,这是由C语言决定的,与具体CPU无关,但各种单片机内存的地址范围不同,这个需要注意。
==============以上内容引自“百度知道”==================
地址空间的0x0200为起始地址,往高地址增长是RAM占用的地址空间,RAM占用空间的大小跟具体的器件直接相关。RAM部分可以用来存储数据和指令。
MSP430F1232的ADC10转换结果存放在ADC10SA指定的起始地址中,地址是连续的,每个地址中存放多大的数据?ADC10转换结果先放在16位MEM中,那么这16位怎么放在内存中,怎么取出来?
第一个问题:每个地址中存放8位数据第二个问题:应该是MEM中的低八位放在sa指定的初始地址a0中,高八位放在下一个地址,也就是a0+1中,到底是不是这么放的,因为手册中并没有明确的写出来,也或者自己没有找到,所以最有效的方法是通过一个例程,单步调试程序,看一下a0和a0+1地址取出的数据到底是什么样的,这是最有效的方式,所以不要嫌麻烦。
个人感觉上述来自百度知道的方法应该是有效的,但是经过实验发现该内存读写代码无法实现读取内存的目的,经过查找别的资料,发现使用AD10的ADT+SA采样转换的内存读取方案:
MSP430的ADC10的DTC功能确实强大,它支持将ADC10MEM中的内容自动存放到任意地址。经过上面的学习,我们已经知道必须要设置ADC10SA来确认传送的目标地址,然后通过设置ADC10DTC1来确认传送的数据大小(字节数),另外还可以通过设置ADC10DTC0中的ADC10TB来选择传输一块或者两块数据、设置ADC10CT来选择是否连续传递数据。
因为大家现在还没有学习flash模块,为了避免覆盖flash中的重要数据(比如我们每次用到的CALBC1_16MHZ和CALDCO_16MHZ都是在flash中存放的),我们只在RAM中做文章。我们可以给定一个固定的地址,比如0x0200,但是我们如何保证这些地址不会被别的程序覆盖呢,确实很难保证。Cloud也不推荐用这种方式。那么我们能不能利用DTC直接将数据存放到我们的变量中呢?
答案是肯定的。学习过指针的同学都知道,在程序中,所有的变量都是有其地址的,通过这个思想,我们让ADC10SA指向某个变量的地址,然后再将ADC10DTC1的大小和变量长度相匹配就好了。

[html] view plain copy
#include   

#define  uchar    unsigned char  
#define  ushort    unsigned short  

ushort temp0, temp1;  
uchar temp0_L, temp0_H;  
uchar temp1_L, temp1_H;  
ushort array[2] = (0);  

int main(void)  
{  
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT  
  BCSCTL1 |= DIVA_2;                        // ACLK = LFXT1CLK/8  
  ADC10CTL1 = ADC10SSEL_1 + INCH_1 + CONSEQ_1;            // A1/A0, single sequence, 选择ACLK作为时钟源  
  ADC10CTL0 = MSC + ADC10ON + ADC10IE + REFON + REF2_5V;     //时钟源分频+连续  
  ADC10DTC1 = 0x02;                         // 2 conversions  
  ADC10AE |= 0x03;                          // P2.1,0 ADC10 option select  
  P3SEL |= 0x30;                            // P3.4,5 = USART0 TXD/RXD  
  P3DIR |= 0x10;                            // P3.4为输出  
  ME2 |= UTXE0 + URXE0;                     // Enabled USART0 TXD/RXD  
  UCTL0 |= CHAR;                            // 8-bit character  
  UTCTL0 |= SSEL1;                          // UCLK = SMCLK, 选择SMCLK作为时钟源  
  UBR00 = 0xD0;                             // 2MHz 9600  
  UBR10 = 0x00;                             //  
  UMCTL0 = 0x00;                            // no modulation  
  UCTL0 &= ~SWRST;                          // Initalize USART state machine  
  IE2 |= URXIE0;                            // Enabled USART0 RX interrupt  

  for (;;)  
  {  
    ADC10CTL0 &= ~ENC;  
    while (ADC10CTL1 & BUSY);               // Wait if ADC10 core is active  
    ADC10SA = (short) (array);                        // Data buffer start  
    ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start  
    __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit  
    //AD把两路转换完成,而且给了ADC10SA控制将长度为2的数据块放到某个地址中,那么可以从地址中取出转换完成的数据  
    //一个块放着两个转换完的数据,每个转换完的数据长度是2个字节,一个地址是一个字节,现在的地址是在0x200的基础上加4  
    //但是这个地址是个什么意思不太明白  
    //对于中断来说,当每次两个整个数据块都传递完成时,中断标志置1,此时产生中断,让CPU跳出低功耗状态,继续执行上面的for循环  
    //继续开始转换,由于AD转换独立于CPU,所以CPU又进入低功耗状态,当转换完成时再次跳出低功耗,这样不断进入跳出,实现低功耗。  
    //所以低功耗跳出之后,以下应该写串口传输的代码,将转换完的数字量给USART  
    //很简单,模数转换之后,结果自然保存到了array数组中,数组每个元素的大小是2字节,因为ADC是10位,采样结果先放在2字节的MEM寄存器中  
    //所以一次转换结果在内存中占用两个连续的地址,也就是2字节大小  
    temp0_L = array[1] & 0x00ff;  
    temp0_H = (array[1]>>8) & 0x00ff;  
    temp1_L = array[0] & 0x00ff;  
    temp1_H = (array[0]>>8) & 0x00ff;  
    //array[1]对应着A0的数字输出;array[0]对应着A1的数字输出  
    while (!(IFG2 & UTXIFG0));   
    TXBUF0 = 0xC0;  

    while (!(IFG2 & UTXIFG0));   
    TXBUF0 = temp0_H;  
    while (!(IFG2 & UTXIFG0));   
    TXBUF0 = temp0_L;   

    while (!(IFG2 & UTXIFG0));   
    TXBUF0 = temp1_H;  
    while (!(IFG2 & UTXIFG0));   
    TXBUF0 = temp1_L;  

    while (!(IFG2 & UTXIFG0));   
    TXBUF0 = '\n';  

  }  
}  

// ADC10 interrupt service routine  
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)  
#pragma vector=ADC10_VECTOR  
__interrupt void ADC10_ISR (void)  
#elif defined(__GNUC__)  
void __attribute__ ((interrupt(ADC10_VECTOR))) ADC10_ISR (void)  
#else  
#error Compiler not supported!  
#endif  
{  
    __bic_SR_register_on_exit(CPUOFF);      // Clear CPUOFF bit from 0(SR)  
}  

 
点赞 关注

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

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