使用的MSP430型号为MSP430F5529LP(Lauchpad)
MSP430x5xx and MSP430x6xx Family User's Guide 给出:其内置12位ADC的 最高采样率约为200ksps
下面详述ADC设置过程。
目录
1.设置ADC转换模式为Repeat-single-channel;
2.设置ADC的转换时钟sample-and-hold source (SHI)
3.设置定时器A为输出输出模式
4.设置输入通道
5.设置ADC12SHP位
6.设置采样保持时间
1.设置ADC转换模式为Repeat-single-channel;
请通过设置ADC12CONSEQx位来设置转换模式。
2.设置ADC的转换时钟sample-and-hold source (SHI)
选择为定时器A的输出;
对于ADC12SHSx位, 默认值为0h,也就是ADC12SC位控制一次转换或多次转换的开始。在这一点上,官网上给出的大部分例程都保持默认设置。比如:
https://dev.ti.com/tirex/explore/node?devices=MSP430F5529&node=ALGZRALuAjj-L1sgzhrl-Q__IOGqZri__LATEST
本例程中需要选择定时器输出控制转换的开始, MSP430x5xx and MSP430x6xx Family User's Guide 中告诉我们需要查找device-specific data sheet
在这一点上,MSP430G2553 的ADC10的寄存器说明中则直接给出了对应的定时器:
下图摘自 MSP430x2xx Family User's Guide
对于F5529的ADC12,我们在 MSP430F552x, MSP430F551x Mixed-Signal Microcontrollers 中可以找到答案:
这样,设置ADC12SHS位为ADC12SHS_1,就可以通过TA0.1输出一个PWM波控制ADC转换。
注意,由于使用了TimerA控制转换,我们就不再需要控制ADC12SC位来开启转换。
也就是说官网示例中的以下语句我们不需要。
ADC12CTL0 |= ADC12SC; // Start sampling/conversion
同理,官网的给出的单通道重复转换的另一个示例中:
https://dev.ti.com/tirex/explore/node?devices=MSP430F5529&node=AF4y3ALvJIfHLG8i78B81g__IOGqZri__LATESThttps://dev.ti.com/tirex/explore/node?devices=MSP430F5529&node=AF4y3ALvJIfHLG8i78B81g__IOGqZri__LATEST
ADC12MSC位的设置我们也不再需要,因为我们是通过定时器输出的PWM波来控制转换的,ADC12MSC位被设置为1时,得到一个数据后,下一个数据将会被立即转换,并不受PWM波的控制。(见下)
3.设置定时器A为输出输出模式
TA0.1输出应为周期为200kHz的PWM波。
这里选择Output Mode 3,输出PWM波的周期只受TAxCCR0控制。
如果你的MSP430SMCLK为8MHz,且SMCLK被选为定时器的时钟源,那么TAxCCR0应该为:
TAxCCR1的值将只影响占空比。
选择其他的输出模式请根据实际进行设置。
4.设置输入通道
上图来自:
MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP)
slau533d.pdf
上图仍然来自: MSP430F552x, MSP430F551x Mixed-Signal Microcontrollers
这里选择P6.0作为ADC输入引脚。
5.设置ADC12SHP位
该位控制采样的模式。
Extended Sample Mode:
Pulse Sample Mode:
这里的理解为:SHI(已经被我们设置为定时器的输入)控制采样和转换时序。
对于 Extended Sample Mode,采样时长将与其高电平时间保持一致,这样在某些情况下可能导致转换出错。
比如,每次采样间隔完全足够完成一次转换,但由于低电平时间过短(比如占空比为99%),t_convert短于13个ADC12CLK,转换就会出错。
对于Pulse Sample Mode,SHI的上升沿触发采样开始,但采样时长由ADC12SHT位控制(见下一部分)
6.设置采样保持时间
由于需要达到最高转换速率,这里的设置需要异常谨慎。
下面稍作分析。
上图仍然来自:MSP430F552x, MSP430F551x Mixed-Signal Microcontrollers
上图来自:MSP430x5xx and MSP430x6xx Family User's Guide
ADC12 clock source默认值为0,即ADC12OSC,其频率范围为:4.2~5.4MHz。
这里估算时按5MHz算,则其周期为:1/5M=200ns=0.2us
而我们需要达到的转换速率为200kHz,即每5us开始一次新的采样转换。
假如我们设置ADC12SHT0x位为0010b,也就是采样时间为16个ADC12CLK,则至少需要16*0.2=3.2us进行采样。
同时在当前配置下,t_convert的最小值为2.4us,那么:
无法完成任务。这里测试的情况是采样点数不够。
所以只能设置ADC12SHT0x为0001b或0000b,其他值统统不行。
另一种解决方案,通过设置ADC12SSELx位将时钟源换为SMCLK,并将主频调成25MHz(需要进行升压操作,详见PMM模块说明,这里不多说,进而实现要求.
当然当你主频过高时,不要忘记采样时间也有要求,需要大于1000ns,否则也可能出问题。
下面贴完整代码:
#include /** * main.c */ unsigned int i=0; volatile unsigned int buf[200]; int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT Clock_init(); Timer_Init(); ADC12_Init(); } #pragma vector = ADC12_VECTOR __interrupt void ADC12_ISR(void) { switch(__even_in_range(ADC12IV,34)) { case 0: break; // Vector 0: No interrupt case 2: break; // Vector 2: ADC overflow case 4: break; // Vector 4: ADC timing overflow case 6: // Vector 6: ADC12IFG0 buf[i]=ADC12MEM0;//*3.3/4096.0; 变成浮点数将会来不及采样 i++; if(i>200) i=0; break; case 8: break; // Vector 8: ADC12IFG1 case 10: break; // Vector 10: ADC12IFG2 case 12: break; // Vector 12: ADC12IFG3 case 14: break; // Vector 14: ADC12IFG4 case 16: break; // Vector 16: ADC12IFG5 case 18: break; // Vector 18: ADC12IFG6 case 20: break; // Vector 20: ADC12IFG7 case 22: break; // Vector 22: ADC12IFG8 case 24: break; // Vector 24: ADC12IFG9 case 26: break; // Vector 26: ADC12IFG10 case 28: break; // Vector 28: ADC12IFG11 case 30: break; // Vector 30: ADC12IFG12 case 32: break; // Vector 32: ADC12IFG13 case 34: break; // Vector 34: ADC12IFG14 default: break; } } 系统频率设置为25MHz (需要设置PMM升压) void upVcc(void)//核心电压上升3级 { PMMCTL0_H = PMMPW_H; //开启PMM电源管理,即开锁 SVSMLCTL |= SVSMLRRL_1 + SVMLE; //配置SVML电压 PMMCTL0 = PMMPW +PMMCOREV_3; //配置内核电压,选择3级 while((PMMIFG & SVSMLDLYIFG)==0); //等待配置完成 PMMIFG &=~ (SVMLVLRIFG + SVMLIFG + SVSMLDLYIFG); if((PMMIFG & SVMLIFG)==1) while((PMMIFG & SVMLVLRIFG)==0); SVSMLCTL &=~ SVMLE; //关闭SVML PMMCTL0_H = 0x00; //锁存配置,即关锁 } void Clock_init() //XT2为时钟源 { upVcc(); P5SEL |= BIT2+BIT3; // Port select XT2 UCSCTL6 &= ~XT2OFF; // Enable XT2 UCSCTL3 |= SELREF_5+FLLREFDIV_2; // FLLref = XT2 4MHz divider:4 // Since LFXT1 is not used, // sourcing FLL with LFXT1 can cause // XT1OFFG flag to set UCSCTL4 |= SELA_2; // ACLK=REFO,SMCLK=DCO,MCLK=DCO UCSCTL2 = FLLD_1 + 24; //N=24 SMCLK=MCLK=DCOclkdiv:(N+1)*FFLrefclk/4=25MHz FFLD=1—>D=2为默认值 -> DCOclk=50MHz UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_7; // Set RSELx for DCO = 16 MHz // Loop until XT1,XT2 & DCO stabilizes - in this case loop until XT2 settles do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag UCSCTL6 &= ~XT2DRIVE0; // Decrease XT2 Drive according to // expected frequency 4MHz } ADC12初始化: void ADC12_Init() { P6SEL |= BIT0; // Enable A/D channel A0 ADC12CTL0 = ADC12SHT0_1 + ADC12ON; ADC12CTL1= ADC12SHP + ADC12CONSEQ_2 + ADC12SHS_1; //SHS1: TimerA 0_1 output ADC source clk:SMLCK
上一篇:MSP430FR6989功能介绍 首先看
下一篇:MSP430 低通滤波器测试
推荐阅读最新更新时间:2024-11-11 22:00