嵌入式设计与开发实训指导 课件 第7-10章 模数转换器ADC-直接存储器存取DMA_第1页
嵌入式设计与开发实训指导 课件 第7-10章 模数转换器ADC-直接存储器存取DMA_第2页
嵌入式设计与开发实训指导 课件 第7-10章 模数转换器ADC-直接存储器存取DMA_第3页
嵌入式设计与开发实训指导 课件 第7-10章 模数转换器ADC-直接存储器存取DMA_第4页
嵌入式设计与开发实训指导 课件 第7-10章 模数转换器ADC-直接存储器存取DMA_第5页
已阅读5页,还剩237页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章模数转换器ADC7.1ADC简介

☆7.2ADC配置

☆7.3ADC库函数

☆7.3.1ADCHAL库函数7.3.2ADCLL库函数7.4ADC设计实例

7.4.1软件设计与实现

7.4.2软件调试与分析前页

返回嵌入式设计与开发实训指导2025/6/5第7章模数转换器ADC模数转换器ADC的主要功能是将模拟信号转化为数字信号以便于微控制器进行数据处理ADC按转换原理分为逐次比较型、双积分型和S-D型逐次比较型ADC通过逐次比较将模拟信号转化为数字信号转换速度快,但精度较低,是最常用的ADC双积分型ADC通过两次积分将模拟信号转化为数字信号,精度高,抗干扰能力强,但速度较慢,主要用于万用表等测量仪器

S-D型ADC具有逐次比较型和双积分型的双重优点,正在逐步广泛地得到应用前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介STM32ADC主要由输入选择和扫描控制、12位逐次逼近模数转换器(SARADC)、触发使能和边沿选择、数据寄存器、AHB接口和模拟看门狗等部分组成。输入通道多达19个,可以实现单次、连续、扫描和不连续转换,转换结果存放在16位数据寄存器中,可以通过AHB接口读取。转换通道分为规则通道和注入通道两组。规则通道由最多16个通道组成,按顺序转换,通道数和转换顺序存放在规则序列寄存器SQR1~SQR4中,转换结果存放在规则通道数据寄存器DR中。前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介STM32ADC主要由输入选择和扫描控制、12位逐次逼近模数转换器(SARADC)、触发使能和边沿选择、数据寄存器、AHB接口和模拟看门狗等部分组成。输入通道多达19个,可以实现单次、连续、扫描和不连续转换,转换结果存放在16位数据寄存器中,可以通过AHB接口读取。转换通道分为规则通道和注入通道两组。注入通道由最多4个通道组成,可插入转换,通道数和转换顺序存放在注入序列寄存器JSQR中,转换结果分别存放在注入通道数据寄存器JDR1~JDR4中。前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介ADC使用的GPIO引脚前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介ADC使用的GPIO引脚(续)前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介ADC寄存器前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介ADC寄存器(续)前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介ADC中断和状态寄存器(ISR)ADC控制寄存器(CR)前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介ADC配置寄存器(CFGR)ADC采样时间寄存器1(SMPR1)ADC采样时间寄存器2(SMPR2)前页

返回嵌入式设计与开发实训指导08:59:34第7章模数转换器ADC7.1ADC简介ADC采样时间周期数ADC规则序列寄存器1(SQR1)前页

返回嵌入式设计与开发实训指导08:59:347.2ADC配置PB12:ADC1_IN11,模拟模式,无上拉/下拉,接R38PB14:ADC1_IN5,模拟模式,无上拉/下拉,接MCP407嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.2ADC配置LowPowerAutoWait:Enable

(参见表7.5,仅用于HAL,LL不影响)NumberOfConversions:2

(ScanConversionMode变为Enabled)Rank1的Channel:Channel11Rank2的SimplingTime:92.5Cycles

(过小时转换结果将受Rank1影响)嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:34

7.2ADC配置ADC配置完成后生成的相应HAL和LL初始化程序分别存放在HAL\Core\Src\adc.c和LL\Core\Src\adc.c中,其中主要代码如下:/*HAL工程*/hadc1.Instance=ADC1;hadc1.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;

hadc1.Init.Resolution=ADC_RESOLUTION_12B;hadc1.Init.DataAlign=ADC_DATAALIGN_RIGHT;hadc1.Init.ScanConvMode=ADC_SCAN_ENABLE;hadc1.Init.EOCSelection=ADC_EOC_SINGLE_CONV;

hadc1.Init.NbrOfConversion=2;

if(HAL_ADC_Init(&hadc1)!=HAL_OK)嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.2ADC配置ADC配置完成后生成的相应HAL和LL初始化程序分别存放在HAL\Core\Src\adc.c和LL\Core\Src\adc.c中,其中主要代码如下:

/*HAL工程*/sConfig.Channel=ADC_CHANNEL_11;

sConfig.Rank=ADC_REGULAR_RANK_1;

sConfig.SamplingTime=ADC_SAMPLETIME_2CYCLES_5;

sConfig.SingleDiff=ADC_SINGLE_ENDED;

sConfig.OffsetNumber=ADC_OFFSET_NONE;

sConfig.Offset=0;

if(HAL_ADC_ConfigChannel(&hadc1,&sConfig)!=HAL_OK)嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.2ADC配置ADC配置完成后生成的相应HAL和LL初始化程序分别存放在HAL\Core\Src\adc.c和LL\Core\Src\adc.c中,其中主要代码如下:

/*HAL工程*/__HAL_RCC_ADC12_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin=GPIO_PIN_12|GPIO_PIN_14;

GPIO_InitStruct.Mode=GPIO_MODE_ANALOG;

GPIO_InitStruct.Pull=GPIO_NOPULL;

HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.2ADC配置ADC配置完成后生成的相应HAL和LL初始化程序分别存放在HAL\Core\Src\adc.c和LL\Core\Src\adc.c中,其中主要代码如下:

/*LL工程*/LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC12);LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);GPIO_InitStruct.Pin=LL_GPIO_PIN_12;GPIO_InitStruct.Mode=LL_GPIO_MODE_ANALOG;GPIO_InitStruct.Pull=LL_GPIO_PULL_NO;LL_GPIO_Init(GPIOB,&GPIO_InitStruct);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.2ADC配置ADC配置完成后生成的相应HAL和LL初始化程序分别存放在HAL\Core\Src\adc.c和LL\Core\Src\adc.c中,其中主要代码如下:

/*LL工程*/ADC_InitStruct.Resolution=LL_ADC_RESOLUTION_12B;ADC_InitStruct.DataAlignment=LL_ADC_DATA_ALIGN_RIGHT;ADC_InitStruct.LowPowerMode=LL_ADC_LP_AUTOWAIT;

LL_ADC_Init(ADC1,&ADC_InitStruct);ADC_REG_InitStruct.TriggerSource=LL_ADC_REG_TRIG_SOFTWARE;ADC_REG_InitStruct.ContinuousMode=LL_ADC_REG_CONV_SINGLE;ADC_REG_InitStruct.DMATransfer=LL_ADC_REG_DMA_TRANSFER_NONE;ADC_REG_InitStruct.Overrun=LL_ADC_REG_OVR_DATA_PRESERVED;

LL_ADC_REG_Init(ADC1,&ADC_REG_InitStruct);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.2ADC配置ADC配置完成后生成的相应HAL和LL初始化程序分别存放在HAL\Core\Src\adc.c和LL\Core\Src\adc.c中,其中主要代码如下:

/*LL工程*/

LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_1,

LL_ADC_CHANNEL_11);

LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_11,

LL_ADC_SAMPLINGTIME_2CYCLES_5);

LL_ADC_SetChannelSingleDiff(ADC1,LL_ADC_CHANNEL_11,

LL_ADC_SINGLE_ENDED);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数基本的ADCHAL库函数在stm32g4xx_hal_adc.h中声明如下:HAL_StatusTypeDefHAL_ADC_Init(ADC_HandleTypeDef

*hadc);HAL_StatusTypeDefHAL_ADC_ConfigChannel(ADC_HandleTypeDef

*hadc,

ADC_ChannelConfTypeDef

*sConfig);HAL_StatusTypeDefHAL_ADCEx_Calibration_Start

(ADC_HandleTypeDef

*hadc,uint32_tSingleDiff);HAL_StatusTypeDefHAL_ADC_Start(ADC_HandleTypeDef*hadc);HAL_StatusTypeDefHAL_ADC_PollForConversion

(ADC_HandleTypeDef*hadc,

uint32_tTimeout);uint32_tHAL_ADC_GetValue(ADC_HandleTypeDef*hadc);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(1)初始化ADCHAL_StatusTypeDefHAL_ADC_Start(ADC_HandleTypeDef

*hadc);参数说明:

★hadc:ADC句柄,在stm32g4xx_hal_adc.h中定义如下:

typedefstruct__ADC_HandleTypeDef

{

ADC_TypeDef *Instance; /*ADC名称*/

ADC_InitTypeDef Init; /*ADC初始化参数*/

……………………

}ADC_HandleTypeDef;嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(1)初始化ADCHAL_StatusTypeDefHAL_ADC_Start(ADC_HandleTypeDef

*hadc);其中ADC_InitTypeDef在stm32g4xx_hal_adc.h中定义如下:

typedefstruct

{

uint32_tClockPrescaler; /*时钟预分频*/uint32_tResolution; /*分辨率*/

uint32_tDataAlign; /*数据对齐*/

…………………

}ADC_InitTypeDef;返回值:HAL状态,HAL_OK等。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(2)配置ADC通道HAL_StatusTypeDefHAL_ADC_ConfigChannel(ADC_HandleTypeDef

*hadc,

ADC_ChannelConfTypeDef

*sConfig);参数说明:

★hadc:ADC句柄

★sConfig:ADC配置参数,在stm32g4xx_hal_adc.h中定义如下:

typedefstruct

{

uint32_tChannel; /*通道号*/

uint32_tRank; /*顺序号*/

uint32_tSamplingTime; /*采样时间*/……………………

}ADC_ChannelConfTypeDef;嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(2)配置ADC通道HAL_StatusTypeDefHAL_ADC_ConfigChannel(ADC_HandleTypeDef

*hadc,

ADC_ChannelConfTypeDef

*sConfig);其中Channel、Rank和SamplingTime在stm32g4xx_hal_adc.h中定义如下:

#defineADC_CHANNEL_0 (LL_ADC_CHANNEL_0)

………………

#defineADC_CHANNEL_18 (LL_ADC_CHANNEL_18)

#defineADC_REGULAR_RANK_1 (LL_ADC_REG_RANK_1)

………………

#defineADC_REGULAR_RANK_16 (LL_ADC_REG_RANK_16)嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(2)配置ADC通道HAL_StatusTypeDefHAL_ADC_ConfigChannel(ADC_HandleTypeDef

*hadc,

ADC_ChannelConfTypeDef

*sConfig);其中Channel、Rank和SamplingTime在stm32g4xx_hal_adc.h中定义如下:

#defineADC_SAMPLETIME_2CYCLE_5 (LL_ADC_SAMPLINGTIME_2CYCLES_5)

………………

#defineADC_SAMPLETIME_640CYCLES_5

(LL_ADC_SAMPLINGTIME_640CYCLES_5)返回值:HAL状态,HAL_OK等。从上述定义可以看出:ADCHAL使用了ADCLL。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(3)完成ADC校准HAL_StatusTypeDefHAL_ADCEx_Calibration_Start

(ADC_HandleTypeDef*hadc,uint32_tSingleDiff);参数说明:

★hadc:ADC句柄

★SingleDiff:单端(ADC_SINGLE_ENDED)或差分(ADC_DIFFERENTIAL_ENDED)返回值:HAL状态,HAL_OK等。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(4)启动ADC转换HAL_StatusTypeDefHAL_ADC_Start(ADC_HandleTypeDef

*hadc);参数说明:

★hadc:ADC句柄。返回值:HAL状态,HAL_OK等。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(5)等待ADC转换完成HAL_StatusTypeDefHAL_ADC_PollForConversion

(ADC_HandleTypeDef

*hadc,

uint32_tTimeout);参数说明:

★hadc:ADC句柄。

★Timeout:超时(ms)。返回值:HAL状态,HAL_OK等。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.1ADCHAL库函数(6)获取ADC转换值uint32_tHAL_ADC_GetValue(ADC_HandleTypeDef

*hadc);参数说明:

★hadc:ADC句柄。返回值:ADC转换值。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数基本的ADCLL库函数在stm32g4xx_ll_adc.h中声明如下:ErrorStatusLL_ADC_Init(ADC_TypeDef*ADCx,

LL_ADC_InitTypeDef*ADC_InitStruct);ErrorStatusLL_ADC_REG_Init(ADC_TypeDef*ADCx,

LL_ADC_REG_InitTypeDef*ADC_REG_InitStruct);voidLL_ADC_DisableDeepPowerDown(ADC_TypeDef*ADCx);voidLL_ADC_EnableInternalRegulator(ADC_TypeDef*ADCx);voidLL_ADC_REG_SetSequencerRanks(ADC_TypeDef*ADCx,

uint32_tRank,

uint32_tChannel);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数基本的ADCLL库函数在stm32g4xx_ll_adc.h中声明如下:voidLL_ADC_SetChannelSamplingTime(ADC_TypeDef*ADCx,

uint32_tChannel,uint32_tSamplingTime);voidLL_ADC_StartCalibration(ADC_TypeDef*ADCx,

uint32_tSingleDiff);uint32_tLL_ADC_IsCalibrationOnGoing(ADC_TypeDef*ADCx);voidLL_ADC_Enable(ADC_TypeDef*ADCx);voidLL_ADC_REG_StartConversion(ADC_TypeDef*ADCx);uint32_tLL_ADC_IsActiveFlag_EOC(ADC_TypeDef*ADCx);uint16_tLL_ADC_REG_ReadConversionData12(ADC_TypeDef*ADCx);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(1)初始化ADCErrorStatusLL_ADC_REG_Init(ADC_TypeDef

*ADCx,

LL_ADC_REG_InitTypeDef

*ADC_REG_InitStruct);参数说明:

★ADCx:ADC名称,取值是ADC1或ADC2等

★ADC_REG_InitStruct:ADC规则通道初始化参数结构体指针,初始化参数结构体在stm32g40x_adc.h中定义如下:嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(1)初始化ADCErrorStatusLL_ADC_REG_Init(ADC_TypeDef

*ADCx,

LL_ADC_REG_InitTypeDef

*ADC_REG_InitStruct);

typedefstruct

{

uint32_tResolution; /*分辨率*/

uint32_tDataAlignment; /*数据对齐*/

uint32_tLowPowerMode; /*低功耗模式*/

}LL_ADC_InitTypeDef;返回值:错误状态,0-SUCCESS。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(2)初始化ADC规则通道ErrorStatusLL_ADC_REG_Init(ADC_TypeDef

*ADCx,

LL_ADC_REG_InitTypeDef

*ADC_REG_InitStruct);参数说明:

★ADCx:ADC名称,取值是ADC1或ADC2等

★ADC_REG_InitStruct:ADC规则通道初始化参数结构体指针,初始化参数结构体在stm32g40x_adc.h中定义如下:嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(2)初始化ADC规则通道ErrorStatusLL_ADC_REG_Init(ADC_TypeDef

*ADCx,

LL_ADC_REG_InitTypeDef

*ADC_REG_InitStruct);

typedefstruct

{

uint32_tTriggerSource; /*触发源*/

uint32_tSequencerLength; /*序列长度*/

uint32_tSequencerDiscont; /*序列不连续模式*/

………………}LL_ADC_REG_InitTypeDef;返回值:错误状态,0-SUCCESS。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(3)禁止深度关断voidLL_ADC_DisableDeepPowerDown(ADC_TypeDef*ADCx);参数说明:

★ADCx:ADC名称。

(4)允许内部稳压器voidLL_ADC_EnableInternalRegulator(ADC_TypeDef*ADCx);参数说明:

★ADCx:ADC名称。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(5)设置规则通道voidLL_ADC_SetSequencerRanks(ADC_TypeDef*ADCx,uint32_tRank,

uint32_tChannel);参数说明:

★ADCx:ADC名称。

★Rank:顺序(1~16)。

★Channel:ADC通道(0~18)。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(6)设置采样时间voidLL_ADC_SetChannelSamplingTime(ADC_TypeDef

*ADCx,

uint32_tChannel,uint32_tSamplingTime);参数说明:

★ADCx:ADC名称。

★Channel:ADC通道(0~18)。

★SamplingTime:采样时间。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数

(7)启动校准voidLL_ADC_StartCalibration(ADC_TypeDef*ADCx,

uint32_tSingleDiff);参数说明:

★ADCx:ADC名称。

★SingleDiff:单端(LL_ADC_SINGLE_ENDED)

或差分(LL_ADC_DIFFERENTIAL_ENDED)。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数

(8)获取校准状态uint32_tLL_ADC_IsCalibrationOnGoing(ADC_TypeDef*ADCx);参数说明:

★ADCx:ADC名称。返回值:0-校准完成,1-校准正在进行。(9)允许ADCvoidLL_ADC_Enable(ADC_TypeDef*ADCx);参数说明:

★ADCx:ADC名称,取值是ADC1或ADC2等嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(10)启动规则通道转换voidLL_ADC_REG_StartConversion(ADC_TypeDef

*ADCx);参数说明:

★ADCx:ADC名称(11)获取EOC标志uint32_tLL_ADC_IsActiveFlag_EOC(ADC_TypeDef

*ADCx);参数说明:

★ADCx:ADC名称返回值:EOC标志(0或1)。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.3ADC库函数7.3.2ADCLL库函数(12)获取转换数据uint16_tLL_ADC_REG_ReadConversionData12(ADC_TypeDef*ADCx);参数说明:★ADCx:ADC名称。返回值:转换数据。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例系统包括STM32MCU

(内嵌SysTick定时器)按键、LEDLCD显示屏UART接口24C02、MCP4017ADC1_IN5(PB14)

ADC1_IN11(PB12)

ADC2_IN15(PB15)嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现下面编程实现用B1按键通过I2C1接口改变MCP4017的阻值,从而改变ADC1-IN5的输入电压,用R38改变ADC1-IN11的输入电压,用R37改变ADC2-IN15的输入电压,用ADC1采集两路输入电压进行AD转换,用ADC2采集一路输入电压进行AD转换,转换结果显示在LCD上。ADC软件设计与实现在I2C实现的基础上修改完成:

●将“064_I2C”文件夹复制粘贴并重命名为“074_ADC”文件夹。

●将“Core/Src”文件夹中的“adc.c”复制粘贴到“074_ADC”文件夹,并在Keil中删除“adc.c”前的路径“../Core/Src/”,以方便修改。ADC的软件设计与实现包括硬件接口设置、硬件接口函数和数据处理函数设计与实现。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置

CT117E-M4(V1.2)SPI接口和ADC公用PB12、PB14和PB15,为了保证系统正常工作,需要对硬件接口进行设置,具体步骤如下:

①将J11、J12和J15的1和2相连(PB14-ADC1_IN5,PB12-ADC1_IN11,PB15-ADC2_IN15)。

②对于HAL工程,在adc.c的MX_ADC1_Init()中将下列语句:

sConfig.Channel=ADC_CHANNEL_14;sConfig.Channel=ADC_CHANNEL_4;

修改为:sConfig.Channel=ADC_CHANNEL_11;sConfig.Channel=ADC_CHANNEL_5;嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置在adc.c的MX_ADC2_Init()中将下列语句:sConfig.Channel=ADC_CHANNEL_13;

修改为:sConfig.Channel=ADC_CHANNEL_15;在adc.c的HAL_ADC_MspInit()中注释下列语句:

//GPIO_InitStruct.Pin=GPIO_PIN_3;

//GPIO_InitStruct.Mode=GPIO_MODE_ANALOG;

//GPIO_InitStruct.Pull=GPIO_NOPULL;

//HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置

在adc.c的HAL_ADC_MspInit()中将下列语句:GPIO_InitStruct.Pin=GPIO_PIN_11;GPIO_InitStruct.Pin=GPIO_PIN_5;HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);

修改为(可以忽略,因为引脚的默认模式是“模拟”):GPIO_InitStruct.Pin=GPIO_PIN_12|GPIO_PIN_14;GPIO_InitStruct.Pin=GPIO_PIN_15;HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置

③对于LL工程,在adc.c的MX_ADC1_Init()中注释下列语句:

//GPIO_InitStruct.Pin=LL_GPIO_PIN_3;

//GPIO_InitStruct.Mode=LL_GPIO_MODE_ANALOG;

//GPIO_InitStruct.Pull=LL_GPIO_PULL_NO;

//LL_GPIO_Init(GPIOA,&GPIO_InitStruct);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置在adc.c的MX_ADC1_Init()中将下列语句:

GPIO_InitStruct.Pin=LL_GPIO_PIN_11;LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_1,

LL_ADC_CHANNEL_14);LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_14,LL_ADC_SAMPLINGTIME_2CYCLES_5);LL_ADC_SetChannelSingleDiff(ADC1,LL_ADC_CHANNEL_14,

LL_ADC_SINGLE_ENDED);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置在adc.c的MX_ADC1_Init()中将下列语句:

LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_2,

LL_ADC_CHANNEL_4);LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_4,LL_ADC_SAMPLINGTIME_92CYCLES_5);LL_ADC_SetChannelSingleDiff(ADC1,LL_ADC_CHANNEL_4,

LL_ADC_SINGLE_ENDED);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置

修改为:

GPIO_InitStruct.Pin=LL_GPIO_PIN_14;LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_1,

LL_ADC_CHANNEL_11);LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_11,LL_ADC_SAMPLINGTIME_2CYCLES_5);LL_ADC_SetChannelSingleDiff(ADC1,LL_ADC_CHANNEL_11,

LL_ADC_SINGLE_ENDED);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置

LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_2,

LL_ADC_CHANNEL_5);LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_5,LL_ADC_SAMPLINGTIME_92CYCLES_5);LL_ADC_SetChannelSingleDiff(ADC1,LL_ADC_CHANNEL_5,

LL_ADC_SINGLE_ENDED);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置在adc.c的MX_ADC2_Init()中将下列语句:

GPIO_InitStruct.Pin=LL_GPIO_PIN_5;LL_GPIO_Init(GPIOA,&GPIO_InitStruct);LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_1,

LL_ADC_CHANNEL_13);LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_13,LL_ADC_SAMPLINGTIME_2CYCLES_5);LL_ADC_SetChannelSingleDiff(ADC1,LL_ADC_CHANNEL_13,

LL_ADC_SINGLE_ENDED);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(1)硬件接口设置

修改为:GPIO_InitStruct.Pin=LL_GPIO_PIN_15;LL_GPIO_Init(GPIOB,&GPIO_InitStruct);LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_1,

LL_ADC_CHANNEL_15);LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_15,LL_ADC_SAMPLINGTIME_2CYCLES_5);LL_ADC_SetChannelSingleDiff(ADC1,LL_ADC_CHANNEL_15,

LL_ADC_SINGLE_ENDED);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现接口函数设计与实现的步骤如下:

①在i2c.h中添加下列函数声明:

voidMCP_Write(uint8_tucVal); /*MCP写*/

②在i2c.c的EEPROM_Write()后添加下列代码:

/*MCP写*/

voidMCP_Write(uint8_tucVal)

{

/*HAL工程代码*/

HAL_I2C_Master_Transmit(&hi2c1,0x5e,&ucVal,1,100);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现

②在i2c.c的EEPROM_Write()后添加下列代码:

/*MCP写*/

voidMCP_Write(uint8_tucVal)

{

/*LL工程代码*/

LL_I2C_HandleTransfer(I2C1,0x5e,LL_I2C_ADDRSLAVE_7BIT,1,

LL_I2C_MODE_AUTOEND,LL_I2C_GENERATE_START_WRITE);

while(!LL_I2C_IsActiveFlag_TXIS(I2C1)); /*等待发送就绪*/

LL_I2C_TransmitData8(I2C1,ucVal); /*发送数据*/

}嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现

③在adc.h中添加下列代码:

/*USERCODEBEGINPrototypes*/

voidADC1_Read(uint16_t*pusBuf); /*ADC1读取*/

uint16_tADC2_Read(void); /*ADC2读取*/

/*USERCODEENDPrototypes*/嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现

④在adc.c中MX_ADC1_Init()的后部添加下列代码:

/*USERCODEBEGINADC1_Init2*/

/*HAL工程代码*/

HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);

/*LL工程代码*/

LL_ADC_StartCalibration(ADC1,LL_ADC_SINGLE_ENDED);

while(LL_ADC_IsCalibrationOnGoing(ADC1));

LL_ADC_Enable(ADC1);

/*USERCODEENDADC1_Init2*/嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现

⑤在adc.c中MX_ADC2_Init()的后部添加下列代码:

/*USERCODEBEGINADC2_Init2*/

/*HAL工程代码*/

HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);

/*LL工程代码*/

LL_ADC_StartCalibration(ADC2,LL_ADC_SINGLE_ENDED);

while(LL_ADC_IsCalibrationOnGoing(ADC2));

LL_ADC_Enable(ADC2);/*USERCODEENDADC2_Init2*/嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现

⑥在adc.c的后部添加下列代码:

/*USERCODEBEGIN1*/

voidADC1_Read(uint16_t*pusBuf) /*ADC1读取*/

{

/*HAL工程代码*/

HAL_ADC_Start(&hadc1);

if(HAL_ADC_PollForConversion(&hadc1,10)==HAL_OK)

pusBuf[0]=HAL_ADC_GetValue(&hadc1);

if(HAL_ADC_PollForConversion(&hadc1,10)==HAL_OK)

pusBuf[1]=HAL_ADC_GetValue(&hadc1);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现

⑥在adc.c的后部添加下列代码:

/*USERCODEBEGIN1*/

voidADC1_Read(uint16_t*pusBuf) /*ADC1读取*/

{

/*LL工程代码*/

LL_ADC_REG_StartConversion(ADC1);

while(LL_ADC_IsActiveFlag_EOC(ADC1)==0);

pusBuf[0]=LL_ADC_REG_ReadConversionData12(ADC1);

while(LL_ADC_IsActiveFlag_EOC(ADC1)==0);

pusBuf[1]=LL_ADC_REG_ReadConversionData12(ADC1);

}嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现

⑥在adc.c的后部添加下列代码:

uint16_tADC2_Read(void) /*ADC2读取*/

{

/*HAL工程代码*/

HAL_ADC_Start(&hadc2);

if(HAL_ADC_PollForConversion(&hadc2,10)==HAL_OK)

returnHAL_ADC_GetValue(&hadc2);

else

return0;嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(2)接口函数设计与实现

⑥在adc.c的后部添加下列代码:

uint16_tADC2_Read(void) /*ADC2读取*/

{

/*LL工程代码*/

LL_ADC_REG_StartConversion(ADC2);

while(LL_ADC_IsActiveFlag_EOC(ADC2)==0);

returnLL_ADC_REG_ReadConversionData12(ADC2);

}

/*USERCODEEND1*/嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(3)数据处理函数设计与实现处理函数设计与实现的步骤如下:

①在main.c中声明下列全局变量:

uint8_tucMcp=0x0f; /*MCP值*/

uint16_tusAdc[3]; /*ADC转换值*/

uint8_tucTadc; /*ADC刷新时间*/

②在main.c中声明如下函数:

voidADC_Proc(void); /*ADC处理*/嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(3)数据处理函数设计与实现处理函数设计与实现的步骤如下:

③在main()的初始化部分取消下列注释:

//MX_ADC1_Init();

//MX_ADC2_Init();

④在main()的EEPROM_Write()后添加下列代码:MCP_Write(ucMcp); /*MCP写*/

⑤在while(1)中添加如下代码:ADC_Proc(); /*ADC处理*/嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(3)数据处理函数设计与实现处理函数设计与实现的步骤如下:

⑥在KEY_Proc()的case1中添加下列代码:ucMcp+=0x10;if(ucMcp==0x8f)ucMcp=0x0f;MCP_Write(ucMcp);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(3)数据处理函数设计与实现处理函数设计与实现的步骤如下:

⑦在LCD_Proc()中添加下列代码:sprintf((char*)ucLcd,"R37:%04uB1:0x%02X",usAdc[2],ucMcp);LCD_DisplayStringLine(Line4,ucLcd);sprintf((char*)ucLcd,"R38:%04uMCP:%03u",usAdc[0],usAdc[1]);LCD_DisplayStringLine(Line5,ucLcd);嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(3)数据处理函数设计与实现处理函数设计与实现的步骤如下:

⑧在fputc()后添加下列代码:

voidADC_Proc(void) /*ADC处理*/

{

if(ucTadc<100) /*100ms未到*/

return;

ucTadc=0;

ADC1_Read(usAdc);

usAdc[2]=ADC2_Read();

}嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.1软件设计与实现(3)数据处理函数设计与实现处理函数设计与实现的步骤如下:

⑨在stm32g4xx_it.c中添加下列外部变量声明:externuint8_tucTadc;

/*ADC刷新计时*/

在stm32g4xx_it.c的SysTick_Handler()中添加下列代码:ucTadc++; /*ADC刷新计时*/编译下载程序,旋转电位器R37或R38,LCD上的显示值从0000变化到4095。每按一下B1按键,B1后显示值加0x10,加到0x7F返回0x0F,MCP后显示值跟随变化(2240~3730)。嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.2软件调试与分析嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.2软件调试与分析嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:347.4ADC设计实例7.4.2软件调试与分析嵌入式设计与开发实训指导第7章模数转换器ADC前页

返回08:59:348.1TIM简介

☆8.2TIM配置

☆8.3TIM库函数

☆8.3.1TIMHAL库函数8.3.2TIMLL库函数8.4TIM设计实例

8.4.1软件设计与实现

8.4.2软件调试与分析前页

返回第8章定时器TIM嵌入式设计与开发实训指导2025/6/5STM32定时器除系统滴答定时器SysTick外,还有高级控制定时器TIM1/8、通用定时器TIM2~5、基本定时器TIM6/7、实时钟RTC、独立看门狗IWDG和窗口看门狗WWDG等高级控制定时器除了具有刹车输入BKIN、互补输出CHxN和重复次数计数器外与通用定时器的主要功能基本相同,两者都包含基本定时器的功能实时钟提供时钟日历的功能。独立看门狗和窗口看门狗用来检测和解决软件错误引起的故障前页

返回嵌入式设计与开发实训指导第8章定时器TIM08:59:348.1TIM简介定时器主要由由时钟控制、时基单元、输入捕获和输出比较等部分组成时钟控制包含触发控制器、从模式控制器和编码器接口等,可以选择内部时钟(默认值)、外部时钟模式和内部触发

时基单元包含16位计数器CNT、预分频器PSC、自动重装载寄存器ARR和重复次数计数器RCR。计数器可以向上计数、向下计数或向上向下双向计数,计数器时钟由预分频器对多种时钟源分频得到,计数器初值来自自动重装载寄存器,重复次数计数器实现重复计数。嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:348.1TIM简介时基单元是定时器的核心,也是基本定时器的主要功能单元。输入捕获包含输入滤波器和边沿检测器、预分频器和捕获/比较寄存器等,可以捕获计数器的值到捕获/比较寄存器,也可以测量PWM信号的周期和脉冲宽度。输出比较包含捕获/比较寄存器、死区发生器DTG和输出控制,可以输出单脉冲,也可以输出PWM信号。嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:34第8章定时器TIM8.1TIM简介TIM使用的GPIO引脚嵌入式设计与开发实训指导前页

返回08:59:34第8章定时器TIM8.1TIM简介TIM主要寄存器嵌入式设计与开发实训指导前页

返回08:59:34第8章定时器TIM8.1TIM简介TIM主要寄存器(续)嵌入式设计与开发实训指导前页

返回08:59:34第8章定时器TIM8.1TIM简介TIM从模式控制寄存器(SMCR)TIM状态寄存器(SR)嵌入式设计与开发实训指导前页

返回08:59:34第8章定时器TIM8.1TIM简介TIM捕获/比较模式寄存器1(CCMR1,输入捕获模式)TIM捕获/比较模式寄存器1(CCMR1,输出比较模式)嵌入式设计与开发实训指导前页

返回08:59:34第8章定时器TIM8.1TIM简介TIM捕获/比较使能寄存器(CCER)嵌入式设计与开发实训指导前页

返回08:59:348.2TIM配置TIM1配置嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:348.2TIM配置TIM1配置

Prescaler(PSC-16bitsvalue):

169(170/(169+1)=1(MHz))

CounterPeriod(AutoReloadRegister-16bitsvalue):499(周期2kHz)

AutomaticOutputState: Enable(允许输出)

PWMGenerationChannel1N的Pluse

(16bitsvalue):50(占空比10%)嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:34

8.2TIM配置TIM2配置嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:348.2TIM配置TIM2配置嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:34

8.2TIM配置TIM2配置

Prescaler(PSC-16bitsvalue):

169(170/(169+1)=1(MHz))

CounterPeriod(AutoReloadRegister-32bitsvalue):4294967295

InputCaptureChannel1的PolaritySelection:FallingEdge

InputCaptureChannel2的PolaritySelection:RisingEdge嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:348.2TIM配置TIM3配置嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:348.2TIM配置TIM3配置

Prescaler(PSC-16bitsvalue):

169(170/(169+1)=1(MHz))

CounterPeriod(AutoReloadRegister-16bitsvalue):999(周期1kHz)

PWMGenerationChannel2的Pluse

(16bitsvalue):100(占空比10%)嵌入式设计与开发实训指导第8章定时器TIM前页

返回08:59:34

8.2TIM配置TIM配置完成后生成的相应HAL和LL初始化程序分别存放在HAL\Core\Src\tim.c和LL\Core\Src\tim.c中,其中主要代码如下:/*HAL工程*/htim1.Instance=TIM1;

htim1.Init.Prescaler=169;htim1.Init.CounterMode=TIM_COUNTERMODE_UP;

htim1.Init.Period=499;htim1.Init.Clock

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论