笔者学习采用单片机型号为MSP430F5529,使用MSP-EXP430F5529LP开发板。
一、ADC12_A模块库函数简介
12位模拟数字转换器(ADC12_A)API提供了一组用于使用MSP430Ware ADC12_A模块的函数。这些函数用于初始化ADC12_A模块,设置每个内存缓冲区的信号源和参考电压,并管理ADC12_A模块的中断。
ADC12_A模块能够将模拟信号转换为相对于给定参考电压的数字值。它可以生成从0到Vcc的数字值,分辨率为8位、10位或12位,有16个不同的内存缓冲区(12个外部信号,4个内部信号)用于存储转换结果。它可以在2种不同的采样模式(扩展采样模式、脉冲采样模式)和4种不同的转换模式(单通道)下运行。采样模式分为扩展采样和脉冲采样,在扩展采样中,采样/保持信号必须保持高电平以进行采样,而在脉冲模式下,设置一个采样计时器以在采样/保持信号的上升沿开始采样,并持续采样指定数量的时钟周期。4种转换模式分别为单通道单次转换、序列通道单次转换、重复单通道转换和重复序列通道转换。
ADC12CONSEQx | 模式操作 |
---|---|
00 | 单通道单次转换 |
01 | 通道序列(自动扫描)单次转换 |
10 | 单通道重复转换 |
11 | 通道序列(重复自动扫描)重复转换 |
ADC12_A模块可以生成多个中断。当一个转换完成时,每个内存缓冲区都可以产生一个中断,或者当一个转换即将覆盖尚未读取的内存缓冲区中的数据时,也会产生中断,以及当一个转换即将开始而上一个转换尚未完成时也会产生中断。
二、常用库函数及其使用方法
// 初始化ADC12_A模块
bool ADC12_A_init(uint16_t baseAddress, uint16_t sampleHoldSignalSourceSelect, uint8_t clockSourceSelect, uint16_t clockSourceDivider);
// 启用ADC12_A模块
void ADC12_A_enable(uint16_t baseAddress);
// 禁用ADC12_A模块
void ADC12_A_disable(uint16_t baseAddress);
// 设置和启用采样定时器脉冲模式
void ADC12_A_setupSamplingTimer(uint16_t baseAddress, uint16_t clockCycleHoldCountLowMem, uint16_t clockCycleHoldCountHighMem, uint16_t multipleSamplesEnabled);
// 禁用采样定时器脉冲模式
void ADC12_A_disableSamplingTimer(uint16_t baseAddress);
// 配置选定的存储器缓冲区控件
void ADC12_A_configureMemory(uint16_t baseAddress, ADC12_A_configureMemoryParam *param);
// 启用选定的ADC12_A中断源
void ADC12_A_enableInterrupt(uint16_t baseAddress, uint32_t interruptMask);
// 禁用选定的ADC12_A中断源
void ADC12_A_disableInterrupt(uint16_t baseAddress, uint32_t interruptMask);
// 清除选定的ADC12_A中断标志
void ADC12_A_clearInterrupt(uint16_t baseAddress, uint16_t memoryInterruptFlagMask);
// 返回选定的存储器中断标志的状态
uint16_t ADC12_A_getInterruptStatus(uint16_t baseAddress, uint16_t memoryInterruptFlagMask);
// 启用/开始模拟-数字转换
void ADC12_A_startConversion(uint16_t baseAddress, uint16_t startingMemoryBufferIndex, uint8_t conversionSequenceModeSelect);
// 禁用ADC将不再转换任何信号
void ADC12_A_disableConversions(uint16_t baseAddress, bool preempt);
// 获取指定存储器缓冲区的结果
uint16_t ADC12_A_getResults(uint16_t baseAddress, uint8_t memoryBufferIndex);
// 用于更改转换数据的分辨率
void ADC12_A_setResolution(uint16_t baseAddress, uint8_t resolutionSelect);
// 用于反转或取消反转采样/保持信号
void ADC12_A_setSampleHoldSignalInversion(uint16_t baseAddress, uint16_t invertedSignal);
// 设置转换数据的读回格式
void ADC12_A_setDataReadBackFormat(uint16_t baseAddress, uint8_t readBackFormat);
// 启用参考缓冲区的突发能力
void ADC12_A_enableReferenceBurst(uint16_t baseAddress);
// 禁用参考缓冲区的突发能力
void ADC12_A_disableReferenceBurst(uint16_t baseAddress);
// 设置参考缓冲区的采样率
void ADC12_A_setReferenceBufferSamplingRate(uint16_t baseAddress, uint8_t samplingRateSelect);
// 返回DMA模块的指定存储器缓冲区的地址
uint32_t ADC12_A_getMemoryAddressForDMA(uint16_t baseAddress, uint8_t memoryIndex);
// 返回ADC12_A核心的忙状态
uint16_t ADC12_A_isBusy(uint16_t baseAddress);
ADC12_A API被分成三组函数:初始化和转换函数,处理中断的函数以及处理ADC12_A的辅助功能的函数。
ADC12_A初始化和转换函数包括:
ADC12_A_init()
:初始化ADC12_A模块。ADC12_A_configureMemory()
:配置内存缓冲区的信号源和参考电压。ADC12_A_setupSamplingTimer()
:设置采样计时器。ADC12_A_disableSamplingTimer()
:禁用采样计时器。ADC12_A_startConversion()
:开始转换。ADC12_A_disableConversions()
:禁用转换。ADC12_A_readResults()
:读取转换结果。ADC12_A_isBusy()
:检查ADC12_A是否正在进行转换。
ADC12_A中断由以下函数处理:
ADC12_A_enableInterrupt()
:使能ADC12_A中断。ADC12_A_disableInterrupt()
:禁用ADC12_A中断。ADC12_A_clearInterrupt()
:清除ADC12_A中断标志。ADC12_A_getInterruptStatus()
:获取ADC12_A中断状态。
ADC12_A的辅助功能由以下函数处理:
ADC12_A_setResolution()
:设置ADC12_A的分辨率。ADC12_A_setSampleHoldSignalInversion()
:设置采样/保持信号的反相。ADC12_A_setDataReadBackFormat()
:设置数据读回格式。ADC12_A_enableReferenceBurst()
:使能参考电压突发模式。ADC12_A_disableReferenceBurst()
:禁用参考电压突发模式。ADC12_A_setReferenceBufferSamplingRate()
:设置参考电压缓冲区采样率。ADC12_A_getMemoryAddressForDMA()
:获取DMA的内存地址。ADC12_A_enable()
:使能ADC12_A模块。ADC12_A_disable()
:禁用ADC12_A模块。
三、代码示例
3.1 单通道转换
ADC_12.h
/*
* ADC_12.h
*
* Created on: 2023年7月20日
* Author: Include everything
*/
#ifndef HARDWARE_ADC_12_H_
#define HARDWARE_ADC_12_H_
void ADC12_Init(void);
#endif /* HARDWARE_ADC_12_H_ */
ADC_12.c
/*
* ADC_12.c
*
* Created on: 2023年7月20日
* Author: Include everything
*/
#include <driverlib.h>
void ADC12_Init(void)
{
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN0); // A0
// ADC12_A初始化
ADC12_A_init(ADC12_A_BASE,
ADC12_A_SAMPLEHOLDSOURCE_SC,
ADC12_A_CLOCKSOURCE_ADC12OSC,
ADC12_A_CLOCKDIVIDER_1);
// 设置采样定时器采样并保持16个时钟周期
ADC12_A_setupSamplingTimer(ADC12_A_BASE,
ADC12_A_CYCLEHOLD_64_CYCLES,
ADC12_A_CYCLEHOLD_4_CYCLES,
ADC12_A_MULTIPLESAMPLESENABLE);
ADC12_A_enable(ADC12_A_BASE);
ADC12_A_configureMemoryParam ADC_12_configureMemoryInitStructure;
ADC_12_configureMemoryInitStructure.endOfSequence = ADC12_A_NOTENDOFSEQUENCE; // 指定的转换结果存储是否为序列的结尾
ADC_12_configureMemoryInitStructure.inputSourceSelect = ADC12_A_INPUT_A0;
ADC_12_configureMemoryInitStructure.memoryBufferControlIndex = ADC12_A_MEMORY_0;
ADC_12_configureMemoryInitStructure.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
ADC_12_configureMemoryInitStructure.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
ADC12_A_configureMemory(ADC12_A_BASE, &ADC_12_configureMemoryInitStructure);
ADC12_A_clearInterrupt(ADC12_A_BASE, ADC12IFG0);
ADC12_A_enableInterrupt(ADC12_A_BASE, ADC12IE0);
}
main.c
#include <driverlib.h>
#include "OLED.h"
#include "System_CLK.h"
#include "Delay.h"
#include "Key.h"
#include "ADC_12.h"
uint16_t MeasureNum;
/**
* main.c
*/
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
SystemClock_Init();
Key_Init();
OLED_Init();
ADC12_Init();
OLED_ShowString(1, 1, "ADC_12 A0(P6.0)");
OLED_ShowString(2, 1, "Result:");
ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, ADC12_A_REPEATED_SINGLECHANNEL);
while (1)
{
OLED_ShowNum(2, 8, MeasureNum, 4);
}
}
// ADC12_A中断函数模板
#pragma vector=ADC12_VECTOR
__interrupt void ADC_12_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
MeasureNum = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_0);
__bic_SR_register_on_exit(LPM0_bits);
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;
}
}
持续更新完善中……
原创笔记,码字不易,欢迎点赞,收藏~ 如有谬误敬请在评论区不吝告知,感激不尽!博主将持续更新有关嵌入式开发、机器学习方面的学习笔记~