MSP430F5529 DriverLib 库函数学习笔记(八)模数转换模块(ADC12)

目录

  • 硬知识
    • 模数转换概述
    • MSP430单片机ADC12模块介绍
    • MSP430单片机ADC12模块操作
      • ADC12的转换模式
      • 采样和转换
      • 转换存储器
      • 使用片内集成温度传感器
    • ADC12模块寄存器
  • ADC_12A API (机翻)
    • 处理初始化和转换的函数
      • 参数
    • 处理中断的函数
      • 参数
    • 处理ADC_12A的辅助功能的函数
      • 参数
  • 上机实战
    • (使用中断)参考电压为AVcc的单通道采样
      • 测量引脚复用输入
      • 配置ADC模块
      • 启动ADC转换
      • ADC中断服务函数
      • 整体代码
      • 实验结果
    • 采用内部参考电压的单通道采样
      • 测量引脚复用输入
      • 配置ADC模块
      • 启动转换并将结果由串口发送
      • 整体代码
      • 实验结果
    • (使用中断)序列多通道转换
      • 测量引脚复用输入
      • 配置ADC模块
      • 配置采样存储器
      • 配置ADC中断
      • 开始ADC采样
      • 配置ADC中断服务函数
      • 整体代码
      • 实验结果

平台:Code Composer Studio 10.3.1
MSP430F5529 LaunchPad™ Development Kit
(MSP‑EXP430F5529LP)


硬知识

模数转换概述

       在MSP430单片机的实时控制和智能仪表等实际应用系统中,常常会遇到连续变化的物理量,如温度、流量、压力和速度等。利用传感器把这些物理量检测出来,转换为模拟电信号,再经过模数转换模块(ADC)转换成数字量,模拟量才能够被MSP430单片机处理和控制。
1.模数转换基本过程
       首先连续时间输入信号x(t)输入ADC的采样保持器中,ADC每隔Ts(采样周期)读出一次x(t)的采样值,对此采样值进行量化。量化的过程是将此信号转换成离散时间、离散幅度的多电平信号。从数学角度理解,量化是把一个连续幅度值的无限数集合映射到一个离散幅度值的有限数集合。在进行ADC转换时,必须把采样电压表示为某个规定的最小数量单位的整数倍,所取的最小数量单位叫做量化单位,用Δ表示。显然,数字信号最低有效位(LSB)的1所代表的数量大小就等于Δ。把量化的结果用代码表示出来,这个过程称为编码。这些代码就是ADC转换的输出结果。
2.ADC的位数
       ADC的位数为ADC模块采样转换后输出代码的位数。例如,一个12位的ADC模块,采样转换后的代码即为12位,表示数值的取值范围为0~4095。
3.分辨率
       分辨率表示输出数字量变化的一个相邻数码所需输入模拟电压的变化量。它定义为转换器的满刻度电压与2n的比值,其中n为ADC的位数。因此,分辨率与ADC的位数有关。例如,一个8位ADC模块的分辨率为满刻度电压的1/256。如果满刻度输入电压为5V,该ADC模块的分辨率即为5V/256=20mV。分辨率代表了ADC模块对输入信号的分辨能力,一般来说,ADC模块位数越高,数据采集的精度就越高。
4.量化误差
       量化误差是由于用有限数字对模拟数值进行离散取值(量化)而引起的误差。因此,量化误差理论上为一个单位分辨率,即1/2LSB。量化误差是无法消除的,但是,通过提高分辨率可以减少量化误差。
5.采样周期
       采样周期是每两次采样之间的时间间隔。采样周期包括采样保持时间和转换时间。采样保持时间是指ADC模块完成一次采样和保持的时间,转换时间是指ADC模块完成一次模数转换所需要的时间。在MSP430单片机的ADC12模块中,采样保持时间可通过控制寄存器进行设置,而转换时间一般需要13个ADCCLK的时间。
6.采样频率
       采样频率,也称为采样速率或者采样率,定义为每秒从连续信号中提取并组成离散信号的采样个数,单位为赫兹(Hz)。采样频率的倒数是采样周期。为了确定对一个模拟信号的采样频率,在此简单介绍采样定理。采样定理又称香农采样定理或者奈奎斯特采样定理,即在进行模数信号的转换过程中,当采样频率fs.max大于信号中最高频率分量fmax的2倍时(fs.max≥2fmax),采样之后的数字信号能保留原始信号中的信息。在一般应用中,采样频率应为被采样信号中最高频率的5~10倍。
7.采样保持电路
       采样保持电路(S/H或者SH)是模数转换系统中的一种重要电路,其作用是采集模拟输入电压在某一时刻的瞬时值,并在模数转换器进行转换期间保持输出电压不变,以供模数转换。该电路存在的原因在于模数转换需要一定时间,在转换过程中,如果送给ADC的模拟量发生变化,就不能保证采样的精度。为了简单起见,在此只分析单端输入ADC的采样保持电路,如图所示。
在这里插入图片描述
       采样保持电路有两种工作状态:采样状态和保持状态。当控制开关S闭合时,输出跟随输入变化,称为采样状态;当控制开关S断开时,由保持电容C维持该电路的输出不变,称为保持状态。
8.多通道同步采样和分时复用
       大多数单片机都集成了8个以上的ADC通道,这些单片机内部的ADC模块大多都是多通道分时复用的结构,其内部其实只有一个ADC内核,依靠增加模拟开关的方法轮流使用ADC内核,所以可以有多个ADC的输入通道。MSP430单片机也采用这种结构,如左图所示。
       同步采样ADC实际就是多个完整独立的ADC。如右图所示为三通道同步采样ADC的示意图。每一组通道都有各自独立的采样保持电路和ADC内核,3个ADC模块共用控制电路和输入/输出接口。
在这里插入图片描述

MSP430单片机ADC12模块介绍

ADC12模块的特性有:
 高达200ksps的最大转换率;
 无数据丢失的单调的12位转换器;
 采样周期可由软件或定时器编程控制的采样保持功能;
 软件或定时器启动转换;
 可通过软件选择片内参考电压(MSP430F54xx:1.5V或2.5V,其他芯片:1.5V、2.0V或2.5V,注意此处只限MSP430F5xx/6xx系列单片机);
 可通过软件选择内部或外部参考电压;
 高达12路可单独配置的外部输入通道;
 可为内部温度传感器、AVCC和外部参考电压分配转换通道;
 正或负参考电压通道可独立选择;
 转换时钟源可选;
 具有单通道单次、单通道多次、序列通道单次和序列通道多次的转换模式;
 ADC内核和参考电压都可独立关闭;
 具有18路快速响应的ADC中断;
 具有16个转换结果存储寄存器。
       ADC12模块的结构框图如图所示。ADC12模块支持快速的12位模数转换。该模块具有一个12位的逐次逼近(SAR)内核、模拟输入多路复用器、参考电压发生器、采样及转换所需的时序控制电路和16个转换结果缓冲及控制寄存器。转换结果缓冲及控制寄存器允许在没有CPU干预的情况下,进行多达16路ADC采样、转换和保存。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

MSP430单片机ADC12模块操作

ADC12的转换模式

       ADC12模块有4种转换模式,可以通过CONSEQx控制位进行选择,具体转换模式说明如表所示。
在这里插入图片描述
(1)单通道单次转换模式
       该模式对单一通道实现单次转换。模数转换结果被写入由CSTARTADDx位定义的存储寄存器ADC12MEMx中。单通道单次转换的流程图如图所示。当用户利用软件使ADC12SC启动转换时,下一次转换可以通过简单地设置ADC12SC位来启动。当有其他任何触发源用于转换时,ADC12ENC位必须在等待触发信号之前置位(上升沿)。其他的采样输入信号将在ADC12ENC复位并置位之前被忽略。
在这里插入图片描述
(2)序列通道单次转换模式
       该模式对序列通道做单次转换。ADC12转换结果将顺序写入由CSTARTADDx位定义的以ADCMEMx开始的转换存储器中。当由ADC12MCTLx寄存器中ADC12EOS位定义的最后一个通道转换完成之后,整个序列通道转换完成。序列通道单次转换的流程图如图所示。当使用ADC12SC位启动转换时,下一次转换可以通过简单地设置ADC12SC位来启动。当有其他任何触发源用于开始转换,ADC12ENC位必须在等待触发信号前置位(上升沿)。其他的采样输入信号将在ADC12ENC复位并置位之前被忽略。
在这里插入图片描述

(3)单通道多次转换模式
       单通道多次转换模式是在选定的通道上进行多次转换。ADC转换的结果被存入由CSTARTADDx位定义的ADC12MEMx寄存器中。在这种转换模式下,当每次转换完成后CPU必须读取ADC12MEMx寄存器的值,否则在下一次转换中,ADC12MEMx寄存器的值会被覆盖。单通道多次转换模式的流程图如图所示。在此模式下,若复位ADC12ENC位,则在当前转换完成之后,转换将立即停止。同时设置CONSEQx=0和ADC12ENC=0,也可以立即停止当前的转换,但是,转换结果是不可靠的。
在这里插入图片描述
(4)序列通道多次转换模式
       序列通道多次转换模式用来进行多通道的连续转换。ADC12转换结果将顺序写入由CSTARTADDx位定义的以ADCMEMx开始的存储器中。当由ADC12MCTLx寄存器中ADC12EOS位定义的最后一个通道转换完成之后,一次序列通道转换完成,触发信号会触发下一次序列通道转换。序列通道多次转换模式的流程图如图所示。
在这里插入图片描述

采样和转换

       当采样触发信号SHI出现上升沿时将启动模数转换。SHI信号源可以通过SHSx位进行定义,有4种选择:ADC12SC、Timer_A.OUT1、Timer_B.OUT0、Timer_B.OUT1。ADC12支持8位、10位及12位分辨率模式,可以通过ADC12RES控制位进行选择,模数转换分别需要9、11及13个ADC12CLK周期。采样输入信号的极性用ISSH控制位来选择。采样转换信号SAMPCON可以来自于采样输入信号SHI或采样定时器,能够控制采样的周期及转换的开始。当SAMPCON信号为高电平时采样被激活,SAMPCON的下降沿将触发模数转换。ADC12SHP定义了两种不同的采样时序方法:扩展采样时序模式和脉冲采样时序模式。

转换存储器

       典型的模数操作通常用中断请求的方式来通知ADC转换的结束,并需要在下一次ADC执行前将转换结果转存到另一位置。ADC12中的16个转换存储缓冲寄存器(ADC12MEMx)使得ADC可以进行多次转换而不需要软件干预,这一点提高了系统性能,也减少了软件开销。
       ADC12模块的每个ADC12MEMx缓冲寄存器都可通过相关的ADC12MCTLx控制寄存器来配置,为转换存储提供了很大的灵活性。SREFx控制位定义了参考电压,INCHx控制位选择输入通道。当使用序列通道转换模式时,ADC12EOS控制位定义了转换序列的结束。

使用片内集成温度传感器

       如果需要使用MSP430单片机片内的温度传感器,用户可以选择模拟输入通道INCHx=1010。与选择外部输入通道一样,需要进行其他寄存器的配置,包括参考电压选择、转换存储寄存器选择等。温度传感器典型的转换函数如图6.2.12所示,该转换函数仅仅作为一个示例,实际的参数可以参考具体芯片的数据手册。当使用温度传感器时,采样周期必须大于30ms。温度传感器的偏移误差比较大,在大多数实际应用中需要进行校准。选择温度传感器会自动地开启片上参考电压发生器作为温度传感器的电源。但是,它不会使能VREF+输出或者影响作为模数转换的参考电压设置,温度传感器的参考电压设置与其他通道相同。
在这里插入图片描述

ADC12模块寄存器

在这里插入图片描述

ADC_12A API (机翻)

ADC_12A API被分成三组函数:
处理初始化和转换的函数,
处理中断的函数,
处理ADC_12A的辅助功能的函数。

处理初始化和转换的函数

ADC12_A_init(uint16_t baseAddress, uint16_t sampleHoldSignalSourceSelect, uint8_t clockSourceSelect, uint16_t clockSourceDivider)
//初始化ADC12_A模块
ADC12_A_configureMemory(uint16_t baseAddress, ADC12_A_configureMemoryParam ∗param)
//配置所选内存缓冲区的控件
ADC12_A_setupSamplingTimer(uint16_t baseAddress, uint16_t clockCycleHoldCountLowMem, uint16_t clockCycleHoldCountHighMem, uint16_t multipleSamplesEnabled)
//设置并启用采样定时器脉冲模式
ADC12_A_disableSamplingTimer(uint16_t baseAddress)
//禁用采样定时器脉冲模式
ADC12_A_startConversion(uint16_t baseAddress, uint16_t startingMemoryBufferIndex, uint8_t conversionSequenceModeSelect)
//使能/开始模数转换
ADC12_A_disableConversions(uint16_t baseAddress, bool preempt)
//禁止ADC转换任何信号
ADC12_A_getResults(uint16_t baseAddress, uint8_t memoryBufferIndex)
//A Signed Integer of the contents of the specified memory buffer
ADC12_A_isBusy(uint16_t baseAddress)
//返回ADC12_A核心的忙碌状态。

参数

baseAddress

ADC12_A_BASE

sampleHoldSignalSourceSelect

/*
is the signal that will trigger a sample-and-hold for an input
signal to be converted. This parameter is device specific and
sources should be found in the device's datasheet. Valid
values are:
*/
ADC12_A_SAMPLEHOLDSOURCE_SC 	//[Default]
ADC12_A_SAMPLEHOLDSOURCE_1
ADC12_A_SAMPLEHOLDSOURCE_2
ADC12_A_SAMPLEHOLDSOURCE_3 /*This parameter is device specific and sources 
should befound in the device's datasheet.
Modified bits are ADC12SHSx of ADC12CTL1 register.*/

clockSourceSelect

/*
selects the clock that will be used by the ADC12_A core, and
the sampling timer if a sampling pulse mode is enabled.
Valid values are:
*/
ADC12_A_CLOCKSOURCE_ADC12OSC 	//[Default] - MODOSC 5 MHz oscillator from the UCS
ADC12_A_CLOCKSOURCE_ACLK 		//The Auxiliary Clock
ADC12_A_CLOCKSOURCE_MCLK 		//The Master Clock
ADC12_A_CLOCKSOURCE_SMCLK 		//The Sub-Master Clock
//Modified bits are ADC12SSELx of ADC12CTL1 register.

clockSourceDivider

/*selects the amount that the clock will be divided. Valid
values are:*/
ADC12_A_CLOCKDIVIDER_1 	//[Default]
ADC12_A_CLOCKDIVIDER_2
ADC12_A_CLOCKDIVIDER_3
ADC12_A_CLOCKDIVIDER_4
ADC12_A_CLOCKDIVIDER_5
ADC12_A_CLOCKDIVIDER_6
ADC12_A_CLOCKDIVIDER_7
ADC12_A_CLOCKDIVIDER_8
ADC12_A_CLOCKDIVIDER_12
ADC12_A_CLOCKDIVIDER_16
ADC12_A_CLOCKDIVIDER_20
ADC12_A_CLOCKDIVIDER_24
ADC12_A_CLOCKDIVIDER_28
ADC12_A_CLOCKDIVIDER_32
/*Modified bits are ADC12PDIV of ADC12CTL2 register;
bits ADC12DIVx of ADC12CTL1 register.*/

ADC12_A_configureMemoryParam

//*****************************************************************************
//
//! \brief Used in the ADC12_A_configureMemory() function as the param
//! parameter.
//
//*****************************************************************************
typedef struct ADC12_A_configureMemoryParam {//! Is the selected memory buffer to set the configuration for.//! \n Valid values are://! - \b ADC12_A_MEMORY_0 [Default]//! - \b ADC12_A_MEMORY_1//! - \b ADC12_A_MEMORY_2//! - \b ADC12_A_MEMORY_3//! - \b ADC12_A_MEMORY_4//! - \b ADC12_A_MEMORY_5//! - \b ADC12_A_MEMORY_6//! - \b ADC12_A_MEMORY_7//! - \b ADC12_A_MEMORY_8//! - \b ADC12_A_MEMORY_9//! - \b ADC12_A_MEMORY_10//! - \b ADC12_A_MEMORY_11//! - \b ADC12_A_MEMORY_12//! - \b ADC12_A_MEMORY_13//! - \b ADC12_A_MEMORY_14//! - \b ADC12_A_MEMORY_15uint8_t memoryBufferControlIndex;//! Is the input that will store the converted data into the specified//! memory buffer.//! \n Valid values are://! - \b ADC12_A_INPUT_A0 [Default]//! - \b ADC12_A_INPUT_A1//! - \b ADC12_A_INPUT_A2//! - \b ADC12_A_INPUT_A3//! - \b ADC12_A_INPUT_A4//! - \b ADC12_A_INPUT_A5//! - \b ADC12_A_INPUT_A6//! - \b ADC12_A_INPUT_A7//! - \b ADC12_A_INPUT_A8//! - \b ADC12_A_INPUT_A9//! - \b ADC12_A_INPUT_TEMPSENSOR//! - \b ADC12_A_INPUT_BATTERYMONITOR//! - \b ADC12_A_INPUT_A12//! - \b ADC12_A_INPUT_A13//! - \b ADC12_A_INPUT_A14//! - \b ADC12_A_INPUT_A15uint8_t inputSourceSelect;//! Is the reference voltage source to set as the upper limit for the//! conversion stored in the specified memory.//! \n Valid values are://! - \b ADC12_A_VREFPOS_AVCC [Default]//! - \b ADC12_A_VREFPOS_EXT//! - \b ADC12_A_VREFPOS_INTuint8_t positiveRefVoltageSourceSelect;//! Is the reference voltage source to set as the lower limit for the//! conversion stored in the specified memory.//! \n Valid values are://! - \b ADC12_A_VREFNEG_AVSS [Default]//! - \b ADC12_A_VREFNEG_EXTuint8_t negativeRefVoltageSourceSelect;//! Indicates that the specified memory buffer will be the end of the//! sequence if a sequenced conversion mode is selected//! \n Valid values are://! - \b ADC12_A_NOTENDOFSEQUENCE [Default] - The specified memory buffer//!    will NOT be the end of the sequence OR a sequenced conversion mode//!    is not selected.//! - \b ADC12_A_ENDOFSEQUENCE - The specified memory buffer will be the//!    end of the sequence.uint8_t endOfSequence;
} ADC12_A_configureMemoryParam;

clockCycleHoldCountLowMem

/*sets the amount of clock cycles to sample- and-hold for the
higher memory buffers 0-7. Valid values are:*/
ADC12_A_CYCLEHOLD_4_CYCLES 	//[Default]
ADC12_A_CYCLEHOLD_8_CYCLES
ADC12_A_CYCLEHOLD_16_CYCLES
ADC12_A_CYCLEHOLD_32_CYCLES
ADC12_A_CYCLEHOLD_64_CYCLES
ADC12_A_CYCLEHOLD_96_CYCLES
ADC12_A_CYCLEHOLD_128_CYCLES
ADC12_A_CYCLEHOLD_192_CYCLES
ADC12_A_CYCLEHOLD_256_CYCLES
ADC12_A_CYCLEHOLD_384_CYCLES
ADC12_A_CYCLEHOLD_512_CYCLES
ADC12_A_CYCLEHOLD_768_CYCLES
ADC12_A_CYCLEHOLD_1024_CYCLES
/*Modified bits are ADC12SHT0x of ADC12CTL0 register.*/

clockCycleHoldCountHighMem

/*sets the amount of clock cycles to sample-and-hold for the
higher memory buffers 8-15. Valid values are:*/
ADC12_A_CYCLEHOLD_4_CYCLES 	//[Default]
ADC12_A_CYCLEHOLD_8_CYCLES
ADC12_A_CYCLEHOLD_16_CYCLES
ADC12_A_CYCLEHOLD_32_CYCLES
ADC12_A_CYCLEHOLD_64_CYCLES
ADC12_A_CYCLEHOLD_96_CYCLES
ADC12_A_CYCLEHOLD_128_CYCLES
ADC12_A_CYCLEHOLD_192_CYCLES
ADC12_A_CYCLEHOLD_256_CYCLES
ADC12_A_CYCLEHOLD_384_CYCLES
ADC12_A_CYCLEHOLD_512_CYCLES
ADC12_A_CYCLEHOLD_768_CYCLES
ADC12_A_CYCLEHOLD_1024_CYCLES
/*Modified bits are ADC12SHT1x of ADC12CTL0 register.*/

multipleSamplesEnabled

/*allows multiple conversions to start without a trigger signal
from the sample/hold signal Valid values are:*/
ADC12_A_MULTIPLESAMPLESDISABLE //[Default] - a timer trigger will be needed to start every ADC conversion.
ADC12_A_MULTIPLESAMPLESENABLE //- during a sequenced and/or repeated conversion mode, after the first conversion, no sample/hold signal is necessary to start subsequent sample/hold and convert processes.
//Modified bits are ADC12MSC of ADC12CTL0 register.

startingMemoryBufferIndex

/*is the memory buffer that will hold the first or only
conversion. Valid values are:*/
ADC12_A_MEMORY_0 //[Default]
ADC12_A_MEMORY_1
ADC12_A_MEMORY_2
ADC12_A_MEMORY_3
ADC12_A_MEMORY_4
ADC12_A_MEMORY_5
ADC12_A_MEMORY_6
ADC12_A_MEMORY_7
ADC12_A_MEMORY_8
ADC12_A_MEMORY_9
ADC12_A_MEMORY_10
ADC12_A_MEMORY_11
ADC12_A_MEMORY_12
ADC12_A_MEMORY_13
ADC12_A_MEMORY_14
ADC12_A_MEMORY_15
//Modified bits are ADC12STARTADDx of ADC12CTL1 register

conversionSequenceModeSelect

/*determines the ADC operating mode. Valid values are:*/
ADC12_A_SINGLECHANNEL /*[Default] - one-time
conversion of a single channel into a single memory
buffer.*/
ADC12_A_SEQOFCHANNELS /* - one time conversion
of multiple channels into the specified starting memory
buffer and each subsequent memory buffer up until the
conversion is stored in a memory buffer dedicated as
the end-of-sequence by the memory's control register.*/
ADC12_A_REPEATED_SINGLECHANNEL /* -
repeated conversions of one channel into a single
memory buffer.*/
ADC12_A_REPEATED_SEQOFCHANNELS /* -
repeated conversions of multiple channels into the
specified starting memory buffer and each subsequent
memory buffer up until the conversion is stored in a
memory buffer dedicated as the end-of-sequence by
the memory's control register.*/
/*Modified bits are ADC12CONSEQx of ADC12CTL1
register.*/

preempt

/*specifies if the current conversion should be pre-empted before the end of the
conversion. Valid values are:*/
ADC12_A_COMPLETECONVERSION /*- Allows the ADC12_A to end the
current conversion before disabling conversions.*/
ADC12_A_PREEMPTCONVERSION /*- Stops the ADC12_A immediately,
with unpredictable results of the current conversion.*/

memoryBufferIndex

/*is the specified Memory Buffer to read. Valid values
are:*/
ADC12_A_MEMORY_0 //[Default]
ADC12_A_MEMORY_1
ADC12_A_MEMORY_2
ADC12_A_MEMORY_3
ADC12_A_MEMORY_4
ADC12_A_MEMORY_5
ADC12_A_MEMORY_6
ADC12_A_MEMORY_7
ADC12_A_MEMORY_8
ADC12_A_MEMORY_9
ADC12_A_MEMORY_10
ADC12_A_MEMORY_11
ADC12_A_MEMORY_12
ADC12_A_MEMORY_13
ADC12_A_MEMORY_14
ADC12_A_MEMORY_15

处理中断的函数

ADC12_A_enableInterrupt(uint16_t baseAddress, uint32_t interruptMask)
//使能选定的ADC 12_A中断源
ADC12_A_disableInterrupt(uint16_t baseAddress, uint32_t interruptMask)
//禁用选定的ADC12中断源
ADC12_A_clearInterrupt(uint16_t baseAddress, uint16_t memoryInterruptFlagMask)
//清除ADC12_A选择的中断标志
ADC12_A_getInterruptStatus(uint16_t baseAddress, uint16_t memoryInterruptFlagMask)
//返回所选内存中断标志的状态

参数

baseAddress

ADC12_A_BASE

interruptMask

//Mask value is the logical OR of any of the following:
ADC12_A_IE0
ADC12_A_IE1
ADC12_A_IE2
ADC12_A_IE3
ADC12_A_IE4
ADC12_A_IE5
ADC12_A_IE6
ADC12_A_IE7
ADC12_A_IE8
ADC12_A_IE9
ADC12_A_IE10
ADC12_A_IE11
ADC12_A_IE12
ADC12_A_IE13
ADC12_A_IE14
ADC12_A_IE15
ADC12_A_OVERFLOW_IE
ADC12_A_CONVERSION_TIME_OVERFLOW_IE

memoryInterruptFlagMask

/*is a bit mask of the interrupt flags to be cleared. Mask value is the
logical OR of any of the following:*/
ADC12_A_IFG0
ADC12_A_IFG1
ADC12_A_IFG2
ADC12_A_IFG3
ADC12_A_IFG4
ADC12_A_IFG5
ADC12_A_IFG6
ADC12_A_IFG7
ADC12_A_IFG8
ADC12_A_IFG9
ADC12_A_IFG10
ADC12_A_IFG11
ADC12_A_IFG12
ADC12_A_IFG13
ADC12_A_IFG14
ADC12_A_IFG15

处理ADC_12A的辅助功能的函数

ADC12_A_setResolution(uint16_t baseAddress, uint8_t resolutionSelect)
//用于更改转换数据的分辨率
ADC12_A_setSampleHoldSignalInversion(uint16_t baseAddress, uint16_t invertedSignal)
//用于 反相或取消反相 采样/保持信号
ADC12_A_setDataReadBackFormat(uint16_t baseAddress, uint8_t readBackFormat)
//用于设置转换后的数据的回读格式
ADC12_A_enableReferenceBurst(uint16_t baseAddress)
//Enables the reference buffer's burst ability
ADC12_A_disableReferenceBurst(uint16_t baseAddress)
//Disables the reference buffer's burst ability
ADC12_A_setReferenceBufferSamplingRate(uint16_t baseAddress, uint8_t samplingRateSelect)
//用于设置参考缓冲区的采样率
ADC12_A_getMemoryAddressForDMA(uint16_t baseAddress, uint8_t memoryIndex)
//返回DMA模块的指定内存缓冲区的地址
ADC12_A_enable(uint16_t baseAddress)
//启用ADC12_A模块
ADC12_A_disable(uint16_t baseAddress)
//禁用ADC12_A模块

参数

baseAddress

ADC12_A_BASE

resolutionSelect

/*determines the resolution of the converted data. Valid values
are:*/
ADC12_A_RESOLUTION_8BIT
ADC12_A_RESOLUTION_10BIT
ADC12_A_RESOLUTION_12BIT //[Default]
//Modified bits are ADC12RESx of ADC12CTL2 register

invertedSignal

/*set if the sample/hold signal should be inverted Valid values are:*/
ADC12_A_NONINVERTEDSIGNAL /*[Default] - a sample-and-hold of an
input signal for conversion will be started on a rising edge of the
sample/hold signal.*/
ADC12_A_INVERTEDSIGNAL /*- a sample-and-hold of an input signal for
conversion will be started on a falling edge of the sample/hold signal.
Modified bits are ADC12ISSH of ADC12CTL1 register.*/

readBackFormat

/*is the specified format to store the conversions in the memory buffer. Valid
values are:*/
ADC12_A_UNSIGNED_BINARY /*[Default]*/
ADC12_A_SIGNED_2SCOMPLEMENT
/*Modified bits are ADC12DF of ADC12CTL2 register*/

samplingRateSelect

/*is the specified maximum sampling rate. Valid values are:*/
ADC12_A_MAXSAMPLINGRATE_200KSPS /*[Default]*/
ADC12_A_MAXSAMPLINGRATE_50KSPS
/*Modified bits are ADC12SR of ADC12CTL2 register.*/

memoryIndex

/*is the memory buffer to return the address of. Valid values are:*/
ADC12_A_MEMORY_0 /*[Default]*/
ADC12_A_MEMORY_1
ADC12_A_MEMORY_2
ADC12_A_MEMORY_3
ADC12_A_MEMORY_4
ADC12_A_MEMORY_5
ADC12_A_MEMORY_6
ADC12_A_MEMORY_7
ADC12_A_MEMORY_8
ADC12_A_MEMORY_9
ADC12_A_MEMORY_10
ADC12_A_MEMORY_11
ADC12_A_MEMORY_12
ADC12_A_MEMORY_13
ADC12_A_MEMORY_14
ADC12_A_MEMORY_15

上机实战

(使用中断)参考电压为AVcc的单通道采样

(改自官方例程)
在这里插入图片描述
所用被测信号为配套实验板的拨盘电位器输出
在这里插入图片描述
信号引脚在0~3.3V之间可调。
在这里插入图片描述

测量引脚复用输入

P6.5对应A5
将P6.5复用输入

    //P6.5 ADC option selectGPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,GPIO_PIN5);

配置ADC模块

ADC模块时钟源选为MODOSC,不分频
       内部模块振荡器(MODOSC)能够产生约4.8MHz的MODCLK时钟。Flash控制器模块、ADC_12模块等片内外设都可使用MODCLK作为内部参考时钟
在这里插入图片描述

在这里插入图片描述

    //Initialize the ADC12_A Module/** Base address of ADC12_A Module* Use internal ADC12_A bit as sample/hold signal to start conversion* USE MODOSC 5MHZ Digital Oscillator as clock source* Use default clock divider of 1*/ADC12_A_init(ADC12_A_BASE,ADC12_A_SAMPLEHOLDSOURCE_SC,ADC12_A_CLOCKSOURCE_ADC12OSC,ADC12_A_CLOCKDIVIDER_1);ADC12_A_enable(ADC12_A_BASE);

配置采样定时器

    /** Base address of ADC12_A Module* For memory buffers 0-7 sample/hold for 64 clock cycles* For memory buffers 8-15 sample/hold for 4 clock cycles (default)* Disable Multiple Sampling*/ADC12_A_setupSamplingTimer(ADC12_A_BASE,ADC12_A_CYCLEHOLD_64_CYCLES,ADC12_A_CYCLEHOLD_4_CYCLES,ADC12_A_MULTIPLESAMPLESDISABLE);

配置采样结果缓冲寄存器
选择输入信号为A5
正参考电压源选为AVcc
负参考电压源选为AVss
在这里插入图片描述
在这里插入图片描述

    //Configure Memory Buffer/** Base address of the ADC12_A Module* Configure memory buffer 0* Map input A5 to memory buffer 0* Vref+ = AVcc* Vr- = AVss* Memory buffer 0 is not the end of a sequence*/ADC12_A_configureMemoryParam param = {0};param.memoryBufferControlIndex = ADC12_A_MEMORY_0;param.inputSourceSelect = ADC12_A_INPUT_A5;param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;ADC12_A_configureMemory(ADC12_A_BASE ,&param);

配置ADC中断
因使用的是ADC12_A_MEMORY_0,故使能为Enable memory buffer 0 interrupt

    //Enable memory buffer 0 interruptADC12_A_clearInterrupt(ADC12_A_BASE,ADC12IFG0);ADC12_A_enableInterrupt(ADC12_A_BASE,ADC12IE0);

启动ADC转换

    while(1){//Enable/Start sampling and conversion/** Base address of ADC12_A Module* Start the conversion into memory buffer 0* Use the single-channel, single-conversion mode*/ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, ADC12_A_SINGLECHANNEL);//LPM0, ADC12_A_ISR will force exit__bis_SR_register(LPM0_bits + GIE);//for Debugger__no_operation();}

ADC中断服务函数

当被测电压大于0.5*AVcc时,点亮LED
反之熄灭LED,并打印所测电压值
case为ADC12_A_MEMORY_0对应的Vector 6

#pragma vector=ADC12_VECTOR
__interrupt
void ADC12_A_ISR (void)
{uint16_t Measured = 0;switch (__even_in_range(ADC12IV,34)){case  0: break;   //Vector  0:  No interruptcase  2: break;   //Vector  2:  ADC overflowcase  4: break;   //Vector  4:  ADC timing overflowcase  6:          //Vector  6:  ADC12IFG0//Is Memory Buffer 0 = A5 > 0.5AVcc?Measured = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_0);if (Measured >= 0x7ff){//set P1.0GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);}else{//Clear P1.0 LED offGPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);}UART_printf(USCI_A1_BASE, "Measured_Volt: %f\r\n", (float)Measured/0xfff*3.3);//Exit active CPU__bic_SR_register_on_exit(LPM0_bits);case  8: break;   //Vector  8:  ADC12IFG1case 10: break;   //Vector 10:  ADC12IFG2case 12: break;   //Vector 12:  ADC12IFG3case 14: break;   //Vector 14:  ADC12IFG4case 16: break;   //Vector 16:  ADC12IFG5case 18: break;   //Vector 18:  ADC12IFG6case 20: break;   //Vector 20:  ADC12IFG7case 22: break;   //Vector 22:  ADC12IFG8case 24: break;   //Vector 24:  ADC12IFG9case 26: break;   //Vector 26:  ADC12IFG10case 28: break;   //Vector 28:  ADC12IFG11case 30: break;   //Vector 30:  ADC12IFG12case 32: break;   //Vector 32:  ADC12IFG13case 34: break;   //Vector 34:  ADC12IFG14default: break;}
}

整体代码

#include "driverlib.h"#define MCLK_IN_HZ      25000000#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))void UART_printf(uint16_t baseAddress, const char *format,...);
bool UART_Init(uint16_t baseAddress, uint32_t Baudrate);void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3);     //高主频工作需要较高的核心电压//XT1引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL参考时钟,先8分频,再50倍频 4MHz / 8 * 50 = 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);UCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 = 32768HzUCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 = 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 = 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值UCS_setExternalClockSource(32768, 4000000);
}void ADC_Test_Init(void)
{//P6.5 ADC option selectGPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,GPIO_PIN5);//Initialize the ADC12_A Module/** Base address of ADC12_A Module* Use internal ADC12_A bit as sample/hold signal to start conversion* USE MODOSC 5MHZ Digital Oscillator as clock source* Use default clock divider of 1*/ADC12_A_init(ADC12_A_BASE,ADC12_A_SAMPLEHOLDSOURCE_SC,ADC12_A_CLOCKSOURCE_ADC12OSC,ADC12_A_CLOCKDIVIDER_1);ADC12_A_enable(ADC12_A_BASE);/** Base address of ADC12_A Module* For memory buffers 0-7 sample/hold for 64 clock cycles* For memory buffers 8-15 sample/hold for 4 clock cycles (default)* Disable Multiple Sampling*/ADC12_A_setupSamplingTimer(ADC12_A_BASE,ADC12_A_CYCLEHOLD_64_CYCLES,ADC12_A_CYCLEHOLD_4_CYCLES,ADC12_A_MULTIPLESAMPLESDISABLE);//Configure Memory Buffer/** Base address of the ADC12_A Module* Configure memory buffer 0* Map input A5 to memory buffer 0* Vref+ = AVcc* Vr- = AVss* Memory buffer 0 is not the end of a sequence*/ADC12_A_configureMemoryParam param = {0};param.memoryBufferControlIndex = ADC12_A_MEMORY_0;param.inputSourceSelect = ADC12_A_INPUT_A5;param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;ADC12_A_configureMemory(ADC12_A_BASE ,&param);//Enable memory buffer 0 interruptADC12_A_clearInterrupt(ADC12_A_BASE,ADC12IFG0);ADC12_A_enableInterrupt(ADC12_A_BASE,ADC12IE0);
}int main(void)
{WDT_A_hold(WDT_A_BASE);SystemClock_Init();UART_Init(USCI_A1_BASE, 115200);ADC_Test_Init();GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);while(1){//Enable/Start sampling and conversion/** Base address of ADC12_A Module* Start the conversion into memory buffer 0* Use the single-channel, single-conversion mode*/ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, ADC12_A_SINGLECHANNEL);//LPM0, ADC12_A_ISR will force exit__bis_SR_register(LPM0_bits + GIE);//for Debugger__no_operation();}
}#pragma vector=ADC12_VECTOR
__interrupt
void ADC12_A_ISR (void)
{uint16_t Measured = 0;switch (__even_in_range(ADC12IV,34)){case  0: break;   //Vector  0:  No interruptcase  2: break;   //Vector  2:  ADC overflowcase  4: break;   //Vector  4:  ADC timing overflowcase  6:          //Vector  6:  ADC12IFG0//Is Memory Buffer 0 = A5 > 0.5AVcc?Measured = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_0);if (Measured >= 0x7ff){//set P1.0GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);}else{//Clear P1.0 LED offGPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);}UART_printf(USCI_A1_BASE, "Measured_Volt: %f\r\n", (float)Measured/0xfff*3.3);//Exit active CPU__bic_SR_register_on_exit(LPM0_bits);case  8: break;   //Vector  8:  ADC12IFG1case 10: break;   //Vector 10:  ADC12IFG2case 12: break;   //Vector 12:  ADC12IFG3case 14: break;   //Vector 14:  ADC12IFG4case 16: break;   //Vector 16:  ADC12IFG5case 18: break;   //Vector 18:  ADC12IFG6case 20: break;   //Vector 20:  ADC12IFG7case 22: break;   //Vector 22:  ADC12IFG8case 24: break;   //Vector 24:  ADC12IFG9case 26: break;   //Vector 26:  ADC12IFG10case 28: break;   //Vector 28:  ADC12IFG11case 30: break;   //Vector 30:  ADC12IFG12case 32: break;   //Vector 32:  ADC12IFG13case 34: break;   //Vector 34:  ADC12IFG14default: break;}
}#include <string.h>
#include <stdarg.h>
#include <stdio.h>
void UART_printf(uint16_t baseAddress, const char *format,...)
{uint32_t length;va_list args;uint32_t i;char TxBuffer[128] = {0};va_start(args, format);length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer)+1, (char*)format, args);va_end(args);for(i = 0; i < length; i++)USCI_A_UART_transmitData(baseAddress, TxBuffer[i]);
}bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{float UART_Temp = 0;USCI_A_UART_initParam huart = {0};if(baseAddress == USCI_A0_BASE)         //P3.3, P3.4 = USCI_A0 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);}else if(baseAddress == USCI_A1_BASE)    //P4.4, P4.5 = USCI_A1 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);}if(Baudrate <= 9600){huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_ACLK;UART_Temp = (float)UCS_getACLK()/Baudrate;}else{huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;UART_Temp = (float)UCS_getSMCLK()/Baudrate;}if(UART_Temp < 16)huart.overSampling = USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;else{huart.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;UART_Temp /= 16;}huart.clockPrescalar = (int)UART_Temp;if(huart.overSampling == USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION){huart.secondModReg = (int)((UART_Temp - huart.clockPrescalar) * 8);}else{huart.firstModReg = (int)((UART_Temp - huart.clockPrescalar) * 16);}huart.parity = USCI_A_UART_NO_PARITY;huart.msborLsbFirst = USCI_A_UART_LSB_FIRST;huart.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;huart.uartMode = USCI_A_UART_MODE;if (STATUS_FAIL == USCI_A_UART_init(baseAddress, &huart)){return STATUS_FAIL;}//Enable UART module for operationUSCI_A_UART_enable(baseAddress);//Enable Receive InterruptUSCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);return STATUS_SUCCESS;
}//******************************************************************************
//
//This is the USCI_A0 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA0IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A0_BASE);USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);break;default:break;}
}//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA1IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A1_BASE);USCI_A_UART_transmitData(USCI_A1_BASE,receivedData);break;default:break;}
}

实验结果

连上串口,转动电位器,得到被测信号波形:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

采用内部参考电压的单通道采样

(改自官方例程)

测量引脚复用输入

    //P6.5 ADC option selectGPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN5);

配置ADC模块

正参考电压源选为内部参考电压,其他部分同上一个实验

     //Initialize the ADC12_A Module/** Base address of ADC12_A Module* Use internal ADC12_A bit as sample/hold signal to start conversion* USE MODOSC 5MHZ Digital Oscillator as clock source* Use default clock divider of 1*/ADC12_A_init(ADC12_A_BASE,ADC12_A_SAMPLEHOLDSOURCE_SC,ADC12_A_CLOCKSOURCE_ADC12OSC,ADC12_A_CLOCKDIVIDER_1);ADC12_A_enable(ADC12_A_BASE);/** Base address of ADC12_A Module* For memory buffers 0-7 sample/hold for 64 clock cycles* For memory buffers 8-15 sample/hold for 4 clock cycles (default)* Disable Multiple Sampling*/ADC12_A_setupSamplingTimer(ADC12_A_BASE,ADC12_A_CYCLEHOLD_64_CYCLES,ADC12_A_CYCLEHOLD_4_CYCLES,ADC12_A_MULTIPLESAMPLESDISABLE);//Configure Memory Buffer/** Base address of the ADC12_A Module* Configure memory buffer 0* Map input A0 to memory buffer 0* Vr+ = Vref+ (int)* Vr- = AVss* Memory buffer 0 is not the end of a sequence*/ADC12_A_configureMemoryParam param = {0};param.memoryBufferControlIndex = ADC12_A_MEMORY_0;param.inputSourceSelect = ADC12_A_INPUT_A5;param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_INT;param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;ADC12_A_configureMemory(ADC12_A_BASE ,&param);

配置内部参考电压

     //Configure internal reference//If ref generator busy, WAITwhile ( REF_ACTIVE == Ref_isRefGenBusy(REF_BASE) ) ;//Select internal ref = 1.5VRef_setReferenceVoltage(REF_BASE,REF_VREF1_5V);//Internal Reference ONRef_enableReferenceVoltage(REF_BASE);//Delay (~75us) for Ref to settledelay_us(75);

其中内部参考电压可设为1.5V、2V、2.5V

//*****************************************************************************
//
// The following are values that can be passed to the referenceVoltageSelect
// parameter for functions: Ref_setReferenceVoltage().
//
//*****************************************************************************
#define REF_VREF1_5V                                                (REFVSEL_0)
#define REF_VREF2_0V                                                (REFVSEL_1)
#define REF_VREF2_5V                                                (REFVSEL_2)

启动转换并将结果由串口发送

    while(1){//Enable/Start first sampling and conversion cycle/** Base address of ADC12_A Module* Start the conversion into memory buffer 0* Use the single-channel, single-conversion mode*/ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, ADC12_A_SINGLECHANNEL);//Poll for interrupt on memory buffer 0while (!ADC12_A_getInterruptStatus(ADC12_A_BASE, ADC12IFG0));Measured = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_0);UART_printf(USCI_A1_BASE, "Measured_Volt: %f\r\n", (float)Measured/0xfff*1.5);//SET BREAKPOINT HERE__no_operation();}

整体代码

#include "driverlib.h"#define MCLK_IN_HZ      25000000#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))void UART_printf(uint16_t baseAddress, const char *format,...);
bool UART_Init(uint16_t baseAddress, uint32_t Baudrate);void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3);     //高主频工作需要较高的核心电压//XT1引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL参考时钟,先8分频,再50倍频 4MHz / 8 * 50 = 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);UCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 = 32768HzUCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 = 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 = 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值UCS_setExternalClockSource(32768, 4000000);
}void ADC_Test_Init(void)
{//P6.5 ADC option selectGPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN5);//Initialize the ADC12_A Module/** Base address of ADC12_A Module* Use internal ADC12_A bit as sample/hold signal to start conversion* USE MODOSC 5MHZ Digital Oscillator as clock source* Use default clock divider of 1*/ADC12_A_init(ADC12_A_BASE,ADC12_A_SAMPLEHOLDSOURCE_SC,ADC12_A_CLOCKSOURCE_ADC12OSC,ADC12_A_CLOCKDIVIDER_1);ADC12_A_enable(ADC12_A_BASE);/** Base address of ADC12_A Module* For memory buffers 0-7 sample/hold for 64 clock cycles* For memory buffers 8-15 sample/hold for 4 clock cycles (default)* Disable Multiple Sampling*/ADC12_A_setupSamplingTimer(ADC12_A_BASE,ADC12_A_CYCLEHOLD_64_CYCLES,ADC12_A_CYCLEHOLD_4_CYCLES,ADC12_A_MULTIPLESAMPLESDISABLE);//Configure Memory Buffer/** Base address of the ADC12_A Module* Configure memory buffer 0* Map input A0 to memory buffer 0* Vr+ = Vref+ (int)* Vr- = AVss* Memory buffer 0 is not the end of a sequence*/ADC12_A_configureMemoryParam param = {0};param.memoryBufferControlIndex = ADC12_A_MEMORY_0;param.inputSourceSelect = ADC12_A_INPUT_A5;param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_INT;param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;ADC12_A_configureMemory(ADC12_A_BASE ,&param);//Configure internal reference//If ref generator busy, WAITwhile ( REF_ACTIVE == Ref_isRefGenBusy(REF_BASE) ) ;//Select internal ref = 1.5VRef_setReferenceVoltage(REF_BASE,REF_VREF1_5V);//Internal Reference ONRef_enableReferenceVoltage(REF_BASE);//Delay (~75us) for Ref to settledelay_us(75);
}int main(void)
{uint16_t Measured = 0;WDT_A_hold(WDT_A_BASE);SystemClock_Init();UART_Init(USCI_A1_BASE, 115200);ADC_Test_Init();while(1){//Enable/Start first sampling and conversion cycle/** Base address of ADC12_A Module* Start the conversion into memory buffer 0* Use the single-channel, single-conversion mode*/ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, ADC12_A_SINGLECHANNEL);//Poll for interrupt on memory buffer 0while (!ADC12_A_getInterruptStatus(ADC12_A_BASE, ADC12IFG0));Measured = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_0);UART_printf(USCI_A1_BASE, "Measured_Volt: %f\r\n", (float)Measured/0xfff*1.5);//SET BREAKPOINT HERE__no_operation();}
}#include <string.h>
#include <stdarg.h>
#include <stdio.h>
void UART_printf(uint16_t baseAddress, const char *format,...)
{uint32_t length;va_list args;uint32_t i;char TxBuffer[128] = {0};va_start(args, format);length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer)+1, (char*)format, args);va_end(args);for(i = 0; i < length; i++)USCI_A_UART_transmitData(baseAddress, TxBuffer[i]);
}bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{float UART_Temp = 0;USCI_A_UART_initParam huart = {0};if(baseAddress == USCI_A0_BASE)         //P3.3, P3.4 = USCI_A0 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);}else if(baseAddress == USCI_A1_BASE)    //P4.4, P4.5 = USCI_A1 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);}if(Baudrate <= 9600){huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_ACLK;UART_Temp = (float)UCS_getACLK()/Baudrate;}else{huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;UART_Temp = (float)UCS_getSMCLK()/Baudrate;}if(UART_Temp < 16)huart.overSampling = USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;else{huart.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;UART_Temp /= 16;}huart.clockPrescalar = (int)UART_Temp;if(huart.overSampling == USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION){huart.secondModReg = (int)((UART_Temp - huart.clockPrescalar) * 8);}else{huart.firstModReg = (int)((UART_Temp - huart.clockPrescalar) * 16);}huart.parity = USCI_A_UART_NO_PARITY;huart.msborLsbFirst = USCI_A_UART_LSB_FIRST;huart.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;huart.uartMode = USCI_A_UART_MODE;if (STATUS_FAIL == USCI_A_UART_init(baseAddress, &huart)){return STATUS_FAIL;}//Enable UART module for operationUSCI_A_UART_enable(baseAddress);//Enable Receive InterruptUSCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);return STATUS_SUCCESS;
}//******************************************************************************
//
//This is the USCI_A0 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA0IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A0_BASE);USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);break;default:break;}
}//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA1IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A1_BASE);USCI_A_UART_transmitData(USCI_A1_BASE,receivedData);break;default:break;}
}

实验结果

万用表测得此时P6.5电压为1.0076V
在这里插入图片描述
参考电压为1.5V时
串口打印电压为1.015385V,误差0.77%
在这里插入图片描述

(使用中断)序列多通道转换

(改自官方例程)

测量引脚复用输入

由于开发板上只有一个电位器,故将电位器所连的P6.5通过杜邦线再连至P6.4
P6.4、P6.5复用输入

    //Enable A/D channel inputsGPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,GPIO_PIN4 | GPIO_PIN5);

配置ADC模块

使能多通道采样

    //Initialize the ADC12_A Module/** Base address of ADC12_A Module* Use internal ADC12_A bit as sample/hold signal to start conversion* USE MODOSC 5MHZ Digital Oscillator as clock source* Use default clock divider of 1*/ADC12_A_init(ADC12_A_BASE,ADC12_A_SAMPLEHOLDSOURCE_SC,ADC12_A_CLOCKSOURCE_ADC12OSC,ADC12_A_CLOCKDIVIDER_1);ADC12_A_enable(ADC12_A_BASE);/** Base address of ADC12_A Module* For memory buffers 0-7 sample/hold for 256 clock cycles* For memory buffers 8-15 sample/hold for 4 clock cycles (default)* Enable Multiple Sampling*/ADC12_A_setupSamplingTimer(ADC12_A_BASE,ADC12_A_CYCLEHOLD_128_CYCLES,ADC12_A_CYCLEHOLD_4_CYCLES,ADC12_A_MULTIPLESAMPLESENABLE);

配置采样存储器

正参考电压都设为AVcc
负参考电压都设为AVss
其中A4不是序列的结尾
A5是序列的结尾

    ADC12_A_configureMemoryParam param = {0};param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;//Configure Memory Buffers/** Base address of the ADC12_A Module* Configure memory buffer 4* Map input A4 to memory buffer 4* Vref+ = AVcc* Vref- = AVss* Memory buffer 4 is not the end of a sequence*/param.memoryBufferControlIndex = ADC12_A_MEMORY_4;param.inputSourceSelect = ADC12_A_INPUT_A4;param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;ADC12_A_configureMemory(ADC12_A_BASE ,&param);/** Base address of the ADC12_A Module* Configure memory buffer 5* Map input A5 to memory buffer 5* Vr+ = AVcc* Vr- = AVss* Memory buffer 5 IS the end of a sequence*/param.memoryBufferControlIndex = ADC12_A_MEMORY_5;param.inputSourceSelect = ADC12_A_INPUT_A5;param.endOfSequence = ADC12_A_ENDOFSEQUENCE;ADC12_A_configureMemory(ADC12_A_BASE ,&param);

配置ADC中断

当序列转换结束,进入中断,故设为5的中断

    //Enable memory buffer 5 interruptADC12_A_clearInterrupt(ADC12_A_BASE, ADC12IFG5);ADC12_A_enableInterrupt(ADC12_A_BASE, ADC12IE5);

开始ADC采样

开始转换序列,起始为通道4
模式为序列通道多次转换

    //Enable/Start first sampling and conversion cycle/** Base address of ADC12_A Module* Start the conversion into memory buffer 0* Use the repeated sequence of channels*/ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_4, ADC12_A_REPEATED_SEQOFCHANNELS);

配置ADC中断服务函数

序列转换结束进入一次中断,每累计转换Num_of_Results次,打印一次电压平均值。

#pragma vector=ADC12_VECTOR
__interrupt
void ADC12ISR (void)
{static uint16_t index = 0;switch (__even_in_range(ADC12IV,34)){case  0: break;   //Vector  0:  No interruptcase  2: break;   //Vector  2:  ADC overflowcase  4: break;   //Vector  4:  ADC timing overflowcase  6: break;   //Vector  6:  ADC12IFG0case  8: break;   //Vector  8:  ADC12IFG1case 10: break;   //Vector 10:  ADC12IFG2case 12: break;   //Vector 12:  ADC12IFG3case 14: break;   //Vector 14:  ADC12IFG4case 16:          //Vector 16:  ADC12IFG5//Move A4 results, IFG is clearedA4results[index] = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_4);//Move A5 results, IFG is clearedA5results[index] = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_5);//Increment results index, modulo; Set BREAKPOINT hereindex++;if (index == Num_of_Results){float A4_Volt, A5_Volt;uint8_t i = 0;index = 0;for(i = 0, A4_Volt = 0; i < Num_of_Results; i++)A4_Volt += A4results[i];A4_Volt = A4_Volt/10/0xfff*3.3;for(i = 0, A5_Volt = 0; i < Num_of_Results; i++)A5_Volt += A5results[i];A5_Volt = A5_Volt/10/0xfff*3.3;UART_printf(USCI_A1_BASE, "%f %f\r\n", A4_Volt, A5_Volt);}break;case 18: break;   //Vector 18:  ADC12IFG6case 20: break;   //Vector 20:  ADC12IFG7case 22: break;   //Vector 22:  ADC12IFG8case 24: break;   //Vector 24:  ADC12IFG9case 26: break;   //Vector 26:  ADC12IFG10case 28: break;   //Vector 28:  ADC12IFG11case 30: break;   //Vector 30:  ADC12IFG12case 32: break;   //Vector 32:  ADC12IFG13case 34: break;   //Vector 34:  ADC12IFG14default: break;}
}

整体代码

#include "driverlib.h"#define MCLK_IN_HZ      25000000#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))void UART_printf(uint16_t baseAddress, const char *format,...);
bool UART_Init(uint16_t baseAddress, uint32_t Baudrate);void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3);     //高主频工作需要较高的核心电压//XT1引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL参考时钟,先8分频,再50倍频 4MHz / 8 * 50 = 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);UCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 = 32768HzUCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 = 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 = 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值UCS_setExternalClockSource(32768, 4000000);
}#define   Num_of_Results   10
volatile uint16_t A4results[Num_of_Results];
volatile uint16_t A5results[Num_of_Results];
void ADC_Test_Init(void)
{//Enable A/D channel inputsGPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,GPIO_PIN4 | GPIO_PIN5);//Initialize the ADC12_A Module/** Base address of ADC12_A Module* Use internal ADC12_A bit as sample/hold signal to start conversion* USE MODOSC 5MHZ Digital Oscillator as clock source* Use default clock divider of 1*/ADC12_A_init(ADC12_A_BASE,ADC12_A_SAMPLEHOLDSOURCE_SC,ADC12_A_CLOCKSOURCE_ADC12OSC,ADC12_A_CLOCKDIVIDER_1);ADC12_A_enable(ADC12_A_BASE);/** Base address of ADC12_A Module* For memory buffers 0-7 sample/hold for 256 clock cycles* For memory buffers 8-15 sample/hold for 4 clock cycles (default)* Enable Multiple Sampling*/ADC12_A_setupSamplingTimer(ADC12_A_BASE,ADC12_A_CYCLEHOLD_128_CYCLES,ADC12_A_CYCLEHOLD_4_CYCLES,ADC12_A_MULTIPLESAMPLESENABLE);ADC12_A_configureMemoryParam param = {0};param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;//Configure Memory Buffers/** Base address of the ADC12_A Module* Configure memory buffer 4* Map input A4 to memory buffer 4* Vref+ = AVcc* Vref- = AVss* Memory buffer 4 is not the end of a sequence*/param.memoryBufferControlIndex = ADC12_A_MEMORY_4;param.inputSourceSelect = ADC12_A_INPUT_A4;param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;ADC12_A_configureMemory(ADC12_A_BASE ,&param);/** Base address of the ADC12_A Module* Configure memory buffer 5* Map input A5 to memory buffer 5* Vr+ = AVcc* Vr- = AVss* Memory buffer 5 IS the end of a sequence*/param.memoryBufferControlIndex = ADC12_A_MEMORY_5;param.inputSourceSelect = ADC12_A_INPUT_A5;param.endOfSequence = ADC12_A_ENDOFSEQUENCE;ADC12_A_configureMemory(ADC12_A_BASE ,&param);//Enable memory buffer 5 interruptADC12_A_clearInterrupt(ADC12_A_BASE, ADC12IFG5);ADC12_A_enableInterrupt(ADC12_A_BASE, ADC12IE5);//Enable/Start first sampling and conversion cycle/** Base address of ADC12_A Module* Start the conversion into memory buffer 0* Use the repeated sequence of channels*/ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_4, ADC12_A_REPEATED_SEQOFCHANNELS);//Enter LPM0, Enable interrupts__bis_SR_register(LPM0_bits + GIE);//For debugger__no_operation();
}int main(void)
{WDT_A_hold(WDT_A_BASE);SystemClock_Init();UART_Init(USCI_A1_BASE, 115200);ADC_Test_Init();
}#pragma vector=ADC12_VECTOR
__interrupt
void ADC12ISR (void)
{static uint16_t index = 0;switch (__even_in_range(ADC12IV,34)){case  0: break;   //Vector  0:  No interruptcase  2: break;   //Vector  2:  ADC overflowcase  4: break;   //Vector  4:  ADC timing overflowcase  6: break;   //Vector  6:  ADC12IFG0case  8: break;   //Vector  8:  ADC12IFG1case 10: break;   //Vector 10:  ADC12IFG2case 12: break;   //Vector 12:  ADC12IFG3case 14: break;   //Vector 14:  ADC12IFG4case 16:          //Vector 16:  ADC12IFG5//Move A4 results, IFG is clearedA4results[index] = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_4);//Move A5 results, IFG is clearedA5results[index] = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_5);//Increment results index, modulo; Set BREAKPOINT hereindex++;if (index == Num_of_Results){float A4_Volt, A5_Volt;uint8_t i = 0;index = 0;for(i = 0, A4_Volt = 0; i < Num_of_Results; i++)A4_Volt += A4results[i];A4_Volt = A4_Volt/10/0xfff*3.3;for(i = 0, A5_Volt = 0; i < Num_of_Results; i++)A5_Volt += A5results[i];A5_Volt = A5_Volt/10/0xfff*3.3;UART_printf(USCI_A1_BASE, "%f, %f\r\n", A4_Volt, A5_Volt);}break;case 18: break;   //Vector 18:  ADC12IFG6case 20: break;   //Vector 20:  ADC12IFG7case 22: break;   //Vector 22:  ADC12IFG8case 24: break;   //Vector 24:  ADC12IFG9case 26: break;   //Vector 26:  ADC12IFG10case 28: break;   //Vector 28:  ADC12IFG11case 30: break;   //Vector 30:  ADC12IFG12case 32: break;   //Vector 32:  ADC12IFG13case 34: break;   //Vector 34:  ADC12IFG14default: break;}
}#include <string.h>
#include <stdarg.h>
#include <stdio.h>
void UART_printf(uint16_t baseAddress, const char *format,...)
{uint32_t length;va_list args;uint32_t i;char TxBuffer[128] = {0};va_start(args, format);length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer)+1, (char*)format, args);va_end(args);for(i = 0; i < length; i++)USCI_A_UART_transmitData(baseAddress, TxBuffer[i]);
}bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{float UART_Temp = 0;USCI_A_UART_initParam huart = {0};if(baseAddress == USCI_A0_BASE)         //P3.3, P3.4 = USCI_A0 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);}else if(baseAddress == USCI_A1_BASE)    //P4.4, P4.5 = USCI_A1 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);}if(Baudrate <= 9600){huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_ACLK;UART_Temp = (float)UCS_getACLK()/Baudrate;}else{huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;UART_Temp = (float)UCS_getSMCLK()/Baudrate;}if(UART_Temp < 16)huart.overSampling = USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;else{huart.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;UART_Temp /= 16;}huart.clockPrescalar = (int)UART_Temp;if(huart.overSampling == USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION){huart.secondModReg = (int)((UART_Temp - huart.clockPrescalar) * 8);}else{huart.firstModReg = (int)((UART_Temp - huart.clockPrescalar) * 16);}huart.parity = USCI_A_UART_NO_PARITY;huart.msborLsbFirst = USCI_A_UART_LSB_FIRST;huart.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;huart.uartMode = USCI_A_UART_MODE;if (STATUS_FAIL == USCI_A_UART_init(baseAddress, &huart)){return STATUS_FAIL;}//Enable UART module for operationUSCI_A_UART_enable(baseAddress);//Enable Receive InterruptUSCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);return STATUS_SUCCESS;
}//******************************************************************************
//
//This is the USCI_A0 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA0IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A0_BASE);USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);break;default:break;}
}//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA1IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A1_BASE);USCI_A_UART_transmitData(USCI_A1_BASE,receivedData);break;default:break;}
}

实验结果

如图所示,两个通道测量值成功输出
在这里插入图片描述
转动电位器,输出随之变化
在这里插入图片描述
电压表实测1.9864V时,打印测量值为2.003V,误差0.8%左右
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有意思的鼠标指针交互探究

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

python基本数据类型——str

一、字符串的创建 test str() / "" test str("licheng") / "licheng" 无参数&#xff0c;创建空字符串一个参数&#xff0c;创建普通字符串两个参数&#xff0c;int&#xff08;字节&#xff0c;编码&#xff09;二、字符串的常用方法 #capita…

MSP430F5529 DriverLib 库函数学习笔记(九)SPI

目录硬知识USCI的同步模式SPI概述SPI特性及结构框图同步操作原理与操作USCI寄存器——SPI模式USCI_x_SPI API &#xff08;机翻&#xff09;处理状态和初始化的函数参数处理数据的函数参数管理中断的函数参数DMA相关参数平台&#xff1a;Code Composer Studio 10.3.1 MSP430F5…

轻松上手Fluentd,结合 Rainbond 插件市场,日志收集更快捷

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

深入理解Threadlocal

SUN公司早在JDK1.2的时候就为我们提供了java.lang.ThreadLocal,低版本的JDK所提供的get()返回的是Object对象&#xff0c;需要强制类型转换&#xff0c;使用起来不方便&#xff0c;而在JDK1.5引入了泛型&#xff0c;在一定程度地简化ThreadLocal的使用。 我们知道在spring容器中…

HDU 2289 几何+圆台

题意;给定一个圆台杯子的R&#xff0c;r&#xff0c;H和里面水的体积V 求h 二分。。。。。。。。。。。。。。。。。 因为解不出来h。。。。。。。。。。。。 View Code 1 /*2 几何3 圆台体积4 V1/3*pi*h*(r1*r1r2*r2r1*r2)5 6 */7 #include<stdio.h>8 #include<stri…

MSP430F5529 DriverLib 库函数学习笔记(十)SPI驱动墨水屏

目录上机实战SPI 驱动 墨水屏墨水屏介绍电子纸的分类电泳型电子纸技术详解原理结构优势与不足实验电路介绍程序分析引脚初始化SPI模块初始化发送和接收全部源代码main.cmain.h墨水屏相关Paper_Display.cPaper_Display.hInclude.h实验结果现象波形对应平台&#xff1a;Code Comp…

Xamarin开发IOS笔记:切换输入法时输入框被遮住

在进行IOS开发的过程中&#xff0c;出现类似微信朋友圈的交互界面&#xff0c;当用户遇到感兴趣的内容可以进行评论。为了方便评论输入&#xff0c;当出现评论输入框的时候自动将评论输入框移动至键盘的上方&#xff0c;这样方便边输入边查看。 当用户隐藏键盘或者切换输入法的…

技术管理进阶——你了解成长的全貌吗?

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

MSP430F5529 DriverLib 库函数学习笔记(十一)I2C / IIC

目录硬知识USCI的I2C模式I2C概述MSP430单片机I2C模块特征及结构框图I2C原理I2C主从操作&#xff08;1&#xff09;从模式&#xff08;2&#xff09;主模式I2C模式下的USCI中断USCI寄存器—I2C模式I2C API (机翻)API介绍主机模式主机模式单字节传输主机模式多字节传输主机模式单…

使用 Abp.Zero 搭建第三方登录模块(一):原理篇

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

MSP430F5529 DriverLib 库函数学习笔记(十二)I2C实战

目录上机实战I2C给 DAC 芯片 DAC7571 写入数字量DAC7571 介绍程序分析引脚复用I2C 初始化发送一个字节发送一个字读取一个字节读取多个字节中断服务函数整体代码main.cMSP430F5529_I2C.cMSP430F5529_I2C.h实验结果I2C 读取 TMP421 温度TMP421 简介程序摘要TMP421初始化温度的读…

mysqldump造成Buffer Pool污染的研究 [转]

原文链接&#xff1a;http://www.shaoqun.com/m/a/43307.aspx 前言&#xff1a; 最近Oracle MySQL在其官方Blog上贴出了 5.6中一些变量默认值的修改。其中innodb_old_blocks_time 的默认值从0替换成了1000&#xff08;即1s&#xff09; 关于该参数的作用摘录如下&#xff1a; h…

自动加载缓存框架

2019独角兽企业重金招聘Python工程师标准>>> 自动加载缓存框架 代码&#xff0c;请访问github 获取更详情&#xff0c;更新的内容 QQ交流群:429274886&#xff0c;版本更新会在群里通知&#xff0c;能了解最新动态 0.5版本已经是稳定版本了&#xff0c;大家可以放心…

(数据科学学习手札139)geopandas 0.11版本重要新特性一览

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

MSP430F5529 DriverLib 库函数学习笔记(十三)认识低功耗模式

目录硬知识低功耗模式MSP430单片机各工作模式下的电流消耗API进入低功耗模式退出低功耗模式平台&#xff1a;Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) 硬知识 低功耗模式 MSP430单片机具有7种低功耗模式&#xff08;LPM0…

剖析虚幻渲染体系(16)- 图形驱动的秘密

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

Python NLPIR(中科院汉语分词系统)的使用 十五分钟快速入门与完全掌握

前叙 博主写这篇文章使用了八十分钟,阅读需要十五分钟,读完之后你将会学会在Python中使用NLPIR2016.如果你花费更多的时间练习后半部分的例子,你将能够在一天内学会在Python中使用NLPIR2016的全部所需知识 如果你想要获取更详细的API翻译,你需要进一步学习ctypes,附赠一篇关于…

微信朋友圈也可以发语音你们造吗?

在微信朋友圈发照片太矫情&#xff0c;小视频又耗流量&#xff0c;只发文字又太单调&#xff0c;何不发段语音来呼朋唤友呢&#xff1f;你是说朋友圈发语音&#xff1f;这是真的吗&#xff1f;sure&#xff0c;开发者已经利用微信JS-SDK接口实现了&#xff0c;扫描下方的二维码…

MSP430F5529 DriverLib 库函数学习笔记(十四)看门狗定时器 (WDT)

目录硬知识看门狗定时计数器 &#xff08;WDTCNT&#xff09;看门狗模式定时计数模式看门狗定时器中断时钟故障保护功能低功耗模式下的看门狗操作看门狗定时器控制寄存器WDT_A API (机翻)参数上机实战定时计数模式配置中断服务函数整体代码实验结果看门狗模式配置整体代码平台&…