MSP430F1232针对ADC10(使用DTC+SA)的内存中采样结果读取

来源:互联网 发布:java myeclipse 编辑:程序博客网 时间:2024/06/13 21:43

定义一个指针,让它指向内存的某个地址,然后通过指针就可以访问。如果需要访问地址为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的大小和变量长度相匹配就好了。


#include <msp430.h>#define  uchar    unsigned char#define  ushort    unsigned shortushort 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)}



0 0
原创粉丝点击