MSP430学习之ADC12
接着上一篇帖子继续给大家讲一讲430的基本模块,今天就说一说MSP430的ADC12。
今天以f149为例给大家说一说ADC12的配置:
首先不得不说430这款单片机不像STM32它要求详细的配置寄存器,说实在是有点麻烦的,像32调用一下库函数就行了,但是430的ADC以其超级稳定的采样依旧吸引着众多单片机爱好者(毕竟TI是做模拟出身的)
ADC12 模块一共提供了 4 钟转换模式:
l 单通道单次转换
l 序列通道单次转换
l 单通道多次转换
l 序列通道多次转换
不论用户使用何种模式,都需要注意以下问题
l 设置具体的转换模式
l 输入模拟信号
l 选择启动信号
l 关注结束信号
l 存放转换数据
l 采用查询或者中断方式来读取数据
为了简洁明了我直接附上f149ADC12的代码:
[1] 单通道单次转换
l 进行单通道单次转换需要注意以下的设置
l 设置通道控制寄存器,设置采样通道和参考电压,ADC12MCTLx
l 单通道转换的地址 CSTARTADD,对应于上面的 ADC12MCTLx
l 相对应的中断标志 ADC12IFGx
下面是软件查询式的单通道单次转换所需要对 ADC12 进行的设置
//-----------------------------------------------------------------------
// 单通道单次转换的通道不一定要是 ADC12MCTL0, 程序中使用了 ADC12MCTL4, 但是采样的通道
// 是 A0, MSP430 中的 ADC12 通道设置是非常灵活的.
// ADC12 单通道单次转换(软件查询式)
void ADC12_Sampling_SingleChannelSingleConvert(void)
{
// ADC12 控制寄存器设置
// 内核开启, 启动内部基准, 选择 2.5V 基准, 设置采样保持时间
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2;
// 时钟源为内部震荡器, 出发信号来自采样定时器, 转换地址为 ADC12MCTL4
ADC12CTL1 = ADC12SSEL_0 + SHP + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_0; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A0
// 启动转换
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
while((ADC12IFG & 0x0010) == 0); // 软件查询中断标志, 等待转换结束
_NOP(); // 处理
}
//-----------------------------------------------------------------------
下面是中断查询式的单通道单次转换所需要对 ADC12 进行的设置
//-----------------------------------------------------------------------
// ADC12 单通道单次转换(中断查询式)
void ADC12_Sampling_SingleChannelSingleConvert(void)
{
// ADC12 控制寄存器设置
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2;
ADC12CTL1 = ADC12SSEL_0 + SHP + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_0; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A0
// 中断允许
ADC12IE = 0x0010;
_EINT();
// 启动转换
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
__low_power_mode_0(); // 进入低功耗模式, 等待转换结束
}
// ADC12 中断向量
#pragma vector = ADC_VECTOR
__interrupt void ADC12_IRQ(void)
{
_NOP(); // 处理
__low_power_mode_off_on_exit(); // 中断结束时, 退出低功耗模式
}
[2] 序列通道单次转换
进行序列通道单次转换需要注意以下的设置:
l 设置若干个通道控制寄存器,设置采样通道和参考电压,ADC12MCTLx,最后一个通道需要加 EOS
l 序列通道转换的首地址 CSTARTADD,对应于上面的第一个 ADC12MCTLx 相对应的最后一个通道的
l 中断标志 ADC12IFGx 下面是软件查询式的序列通道单次转换所需要对 ADC12 进行的设置
//-----------------------------------------------------------------------
// ADC12 序列通道单次转换(软件查询式)
void ADC12_Sampling_SequenceChannelsSingleConvert(void)
{
// ADC12 控制寄存器设置
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2;
// CONSEQ_1 表示当前模式为序列通道单次转换, 起始地址为 ADC12MCTL4, 结束地址 ADC12MCTL6
ADC12CTL1 = ADC12SSEL_0 + SHP + CONSEQ_1 + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_0; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A0
ADC12MCTL5 = SREF_1 + INCH_1; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A1
ADC12MCTL6 = SREF_1 + INCH_10 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:片内温度传感器
// 启动转换
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
while((ADC12IFG & 0x0040) == 0); // 等待转换结束
_NOP(); // 处理
}
//-----------------------------------------------------------------------
[3] 单通道多次转换
进行单通道多次转换需要注意以下的设置:
l 设置通道控制寄存器,设置采样通道和参考电压,ADC12MCTLx
l 单通道转换地址 CSTARTADD,对应于上面的 ADC12MCTLx
l 单通道的中断标志 ADC12IFGx
l 多次转换只能使用中断查询式读数
下面是软件查询式的单通道多次转换所需要对 ADC12 进行的设置
//-----------------------------------------------------------------------
// ADC12 单通道多次转换
void ADC12_Sampling_SingleChannelSequenceConvert(void)
{
// ADC12 控制寄存器设置
// 对于多次转换需要设置 MSC
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2 + MSC;
// CONSEQ_2 表示当前模式为单通道多次转换, 转换地址为 ADC12MCTL4
ADC12CTL1 = ADC12SSEL_0 + SHP + CONSEQ_2 + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_4 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A4
// 中断允许
ADC12IE = 0x0010;
_EINT();
// 启动转换
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
}
// ADC12 中断向量
#pragma vector = ADC_VECTOR
__interrupt void ADC12_IRQ(void)
{
_NOP(); // 处理
}
//-----------------------------------------------------------------------
[4] 序列通道多次转换
进行序列通道多次转换需要注意以下的设置
设置若干个通道控制寄存器,设置采样通道和参考电压,ADC12MCTLx,最后一个通道需要加 EOS
l 序列通道转换的首地址 CSTARTADD,对应于上面的第一个 ADC12MCTLx
l 相对应的最后一个通道的中断标志 ADC12IFGx
l 多次转换只能使用中断查询式读数 下面是软件查询式的序列通道多次转换所需要对 ADC12 进行的设置
//-----------------------------------------------------------------------
// ADC12 序列通道多次转换
void ADC12_Sampling_SequenceChannelSequenceConvert(void)
{
// ADC12 控制寄存器设置
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2 + MSC;
ADC12CTL1 = ADC12SSEL_0 + SHP + CONSEQ_3 + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_4 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A4
ADC12MCTL5 = SREF_1 + INCH_5 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A5
ADC12MCTL6 = SREF_1 + INCH_6 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A6
// 中断允许
ADC12IE = 0x0040;
_EINT();
// 启动转换
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
}
// ADC12 中断向量
#pragma vector = ADC_VECTOR
__interrupt void ADC12_IRQ(void)
{
_NOP(); // 处理
}
//-----------------------------------------------------------------------
还有就是大家可能比较喜欢用F5529,它的ADC12配置和F149的还不太一样,这里我也给大家附上一点我自己编写的好用的代码吧:
#include "MSP430f5529.h"
#include "ADC.h"
unsigned int results[4]; // 转换值存取变量
void ADC12_init(void)
{
P6SEL = 0x0F; // Enable A/D channel inputs
ADC12CTL0 = ADC12ON + ADC12MSC + ADC12SHT0_15 + ADC12REFON + ADC12REF2_5V; // Turn on ADC12, set sampling time
ADC12CTL1 = ADC12SHP + ADC12CONSEQ_1; // Use sampling timer, single sequence
ADC12MCTL0 = ADC12INCH_0; // ref+=AVcc, channel = A0
ADC12MCTL1 = ADC12INCH_1; // ref+=AVcc, channel = A1
ADC12MCTL2 = ADC12SREF_4 + ADC12INCH_2; // ref+=2.5V, channel = A2
ADC12MCTL3 = ADC12INCH_3+ADC12EOS; // ref+=AVcc, channel = A3, end seq.
ADC12IE = 0x08; // Enable ADC12IFG.3
__delay_cycles(100); // delay to allow Ref to settle
ADC12CTL0 |= ADC12ENC; // Enable conversions
}
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{
results[0] = ADC12MEM0; // Move A0 results, IFG is cleared
results[1] = ADC12MEM1; // Move A1 results, IFG is cleared
results[2] = ADC12MEM2; // Move A2 results, IFG is cleared
results[3] = ADC12MEM3; // Move A3 results, IFG is cleared
} |