/** ****************************************************************************** * @file ADC/ADC1_DMA/main.c * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief Main program body ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" // 包含STM32F10x系列微控制器的外设寄存器定义等头文件 /** @addtogroup STM32F10x_StdPeriph_Examples * @{ */ /** @addtogroup ADC_ADC1_DMA * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define ADC1_DR_Address ((uint32_t)0x4001244C) // 定义ADC1数据寄存器(DR)的地址 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ ADC_InitTypeDef ADC_InitStructure; // 声明ADC初始化结构体变量 DMA_InitTypeDef DMA_InitStructure; // 声明DMA初始化结构体变量 __IO uint16_t ADCConvertedValue; // 用于存储ADC转换后的值,__IO表示volatile,确保每次从内存读取 /* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void); // 声明系统时钟配置函数 void GPIO_Configuration(void); // 声明GPIO配置函数 /* Private functions ---------------------------------------------------------*/ /** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); // 调用系统时钟配置函数 /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration(); // 调用GPIO配置函数 /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); // 复位DMA1通道1到默认状态 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; // DMA外设基地址设为ADC1数据寄存器地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue; // DMA内存基地址设为存储转换值的变量地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // DMA传输方向:外设作为数据源 DMA_InitStructure.DMA_BufferSize = 1; // DMA缓冲区大小为1(传输1个数据) DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 禁止外设地址自增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 禁止内存地址自增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设数据宽度为半字(16位) DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 内存数据宽度为半字(16位) DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // DMA工作在循环模式(传输完成后自动重新开始) DMA_InitStructure.DMA_Priority = DMA_Priority_High; // DMA通道优先级为高 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 禁止内存到内存传输模式 DMA_Init(DMA1_Channel1, &DMA_InitStructure); // 根据结构体配置DMA1通道1 /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); // 使能DMA1通道1 /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // ADC1工作在独立模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE; // 启用扫描模式(多通道时需开启,单通道也可开启) ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 启用连续转换模式(转换完成后自动开始下一次) ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不使用外部触发,采用软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // ADC数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; // 转换通道数量为1 ADC_Init(ADC1, &ADC_InitStructure); // 根据结构体配置ADC1 /* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); // 配置ADC1规则通道14:通道14,序列位置1,采样时间55.5个周期 /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); // 使能ADC1的DMA请求(ADC转换完成后触发DMA传输) /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); // 使能ADC1 /* Enable ADC1 reset calibration register */ ADC_ResetCalibration(ADC1); // 复位ADC1校准寄存器 /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); // 等待ADC1复位校准完成 /* Start ADC1 calibration */ ADC_StartCalibration(ADC1); // 开始ADC1校准 /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); // 等待ADC1校准完成 /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 软件触发ADC1开始转换 while (1) // 主循环,程序在此循环中运行 { } } /** * @brief Configures the different system clocks. * @param None * @retval None */ void RCC_Configuration(void) { #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) /* ADCCLK = PCLK2/2 */ RCC_ADCCLKConfig(RCC_PCLK2_Div2); // 对于低/中/高密度超值型芯片,ADC时钟设为PCLK2的1/2 #else /* ADCCLK = PCLK2/4 */ RCC_ADCCLKConfig(RCC_PCLK2_Div4); // 对于其他类型芯片,ADC时钟设为PCLK2的1/4 #endif /* Enable peripheral clocks ------------------------------------------------*/ /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 使能DMA1时钟(DMA1挂载在AHB总线上) /* Enable ADC1 and GPIOC clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE); // 使能ADC1和GPIOC时钟(均挂载在APB2总线上) } /** * @brief Configures the different GPIO ports. * @param None * @retval None */ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; // 声明GPIO初始化结构体变量 /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // 配置PC4引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 引脚模式设为模拟输入(用于ADC采样) GPIO_Init(GPIOC, &GPIO_InitStructure); // 根据结构体配置GPIOC } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */ /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
时间: 2025-07-09 15:13:17 浏览: 8
以下是对STM32F10x ADC1与DMA集成示例代码的每一行添加的详细注释,结合STM32标准外设库实现:
```c
#include "stm32f10x.h" // 包含头文件以访问寄存器定义和库函数
/** @addtogroup STM32F10x_StdPeriph_Examples
* @{
*/
/** @addtogroup ADC_ADC1_DMA
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_Address ((uint32_t)0x4001244C) // 定义ADC1数据寄存器地址(参考手册)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ADC_InitTypeDef ADC_InitStructure; // 声明ADC初始化结构体
DMA_InitTypeDef DMA_InitStructure; // 声明DMA初始化结构体
__IO uint16_t ADCConvertedValue; // 声明一个变量用于存储转换结果(volatile关键字防止优化)
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void); // 声明时钟配置函数
void GPIO_Configuration(void); // 声明GPIO配置函数
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f10x_xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f10x.c file
*/
/* System clocks configuration ---------------------------------------------*/
RCC_Configuration(); // 调用时钟配置函数,配置系统时钟源和外设时钟[^1]
/* GPIO configuration ------------------------------------------------------*/
GPIO_Configuration(); // 调用GPIO配置函数,设置ADC输入引脚为模拟模式[^1]
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1); // 复位DMA1通道1配置至默认状态[^2]
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; // 设置外设基地址为ADC1的数据寄存器
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue; // 设置内存基地址为目标变量[^2]
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 配置传输方向:外设作为源[^2]
DMA_InitStructure.DMA_BufferSize = 1; // 设置缓冲区大小为1个数据单元
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 禁用外设地址递增[^2]
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 禁用内存地址递增[^2]
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 设置外设数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 设置内存数据宽度为16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 启用循环模式,允许连续传输[^2]
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 设置通道优先级为高[^2]
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 禁用内存到内存传输模式
DMA_Init(DMA1_Channel1, &DMA_InitStructure); // 应用DMA配置到DMA1通道1
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE); // 启用DMA1通道1
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 设置ADC工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; // 启用扫描模式,支持多通道转换
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 启用连续转换模式[^1]
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不使用外部触发[^1]
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐方式[^1]
ADC_InitStructure.ADC_NbrOfChannel = 1; // 设置一次转换包含的通道数为1
ADC_Init(ADC1, &ADC_InitStructure); // 应用ADC配置到ADC1
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); // 配置通道14为规则组第1个转换,采样时间为55.5周期
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE); // 启用ADC1的DMA请求功能
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE); // 启用ADC1模块
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1); // 启动ADC校准复位过程
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1)); // 等待校准复位完成
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1); // 开始ADC校准流程[^1]
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1)); // 等待校准完成
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 启用软件启动转换命令
while (1) // 主循环
{
}
}
/**
* @brief Configures the different system clocks.
* @param None
* @retval None
*/
void RCC_Configuration(void)
{
#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
/* ADCCLK = PCLK2/2 */
RCC_ADCCLKConfig(RCC_PCLK2_Div2); // 对于低密度、中密度和高密度价值线设备,ADC时钟预分频为PCLK2除以2[^1]
#else
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div4); // 对于其他设备,ADC时钟预分频为PCLK2除以4
#endif
/* Enable peripheral clocks ------------------------------------------------*/
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 启用DMA1控制器的AHB时钟[^2]
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE); // 启用ADC1和GPIOC的APB2时钟
}
/**
* @brief Configures the different GPIO ports.
* @param None
* @retval None
*/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure; // 声明GPIO初始化结构体
/* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // 指定要配置的引脚为PC4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 设置引脚模式为模拟输入
GPIO_Init(GPIOC, &GPIO_InitStructure); // 应用配置到GPIOC端口
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
```
阅读全文