一、ADC简介
12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。
ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。
二、ADC通道选择
STM32 的 ADC 多达 18 个通道,其中外部的 16 个通道就是框图中的 ADCx_IN0、ADCx_IN1…ADCx_IN5。这 16 个通道对应着不同的 IO 口,具体是哪一个 IO 口可以从手册查询到。其中 ADC1/2/3 还有内部通道:ADC1 的通道 16 连接到了芯片内部的温度传感器,
三、器件选择
淘宝购买STM32F103C8T6和光敏传感器
四、新建工程
1、打开 STM32CubeMX 软件,点击“新建工程”
2、选择 MCU 和封装
五、配置参数
1、配置时钟RCC 设置,
选择 HSE(外部高速时钟)
选择 LSE(外部低速时钟)
选择 Clock Configuration,配置系统时钟 SYSCLK 为 72MHz
修改 HCLK 的值为 72 后,输入回车,软件会自动修改所有配置
2、下载口配置ST-LINK
非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器SYS 设置,选择
3、配置状态灯PC13为GPIO_Output、方便查看程序是否运行。
4、ADC1参数配置
在 Analog 中选择 ADC1 设置,并选择 IN6 通道6
ADCs_Common_Settings:
Mode:
Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选,具体配置 ADC_CR1:DUALMOD 位。
ADC_Settings:
Data Alignment:
Right alignment 转换结果数据右对齐,一般我们选择右对齐模式。
Left alignment 转换结果数据左对齐。
Scan Conversion Mode:
Disabled 禁止扫描模式。如果是单通道 AD 转换使用 DISABLE。
Enabled 开启扫描模式。如果是多通道 AD 转换使用 ENABLE。
Continuous Conversion Mode:
Disabled 单次转换。转换一次后停止需要手动控制才重新启动转换。
Enabled 自动连续转换。
DiscontinuousConvMode:
Disabled 禁止间断模式。这个在需要考虑功耗问题的产品中很有必要,也就是在某个事件触发下,开启转换。
Enabled 开启间断模式。
ADC_Regular_ConversionMode:
Enable Regular Conversions 是否使能规则转换。
Number Of Conversion ADC转换通道数目,有几个写几个就行。
External Trigger Conversion Source 外部触发选择。这个有多个选择,一般采用软件触发方式。
Rank:
Channel ADC转换通道
Sampling Time 采样周期选择,采样周期越短,ADC 转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC 转换数据输出周期就越长同时数据精度越高。
ADC_Injected_ConversionMode:
Enable Injected Conversions 是否使能注入转换。注入通道只有在规则通道存在时才会出现。
WatchDog:
Enable Analog WatchDog Mode 是否使能模拟看门狗中断。当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断。
5、DMA Settings配置
选择DMA Settings选项卡,点击Add,选择ADC1,然后将Mode修改为Circular,Memory地址增加,Data Width选择Half Word。配置完成。
6、工程配置
选择最上面的Project Manager的Project,首先对新建的工程命名为STM32F103C8,最后将开发工具改成自己的开发工具,我这里用的是KEIL5,这里选择MDK。
7、最后生成代码:
六、程序完善
1、完善main函数
添加变量
初始化ADC
启动ADC校正和HAL_ADC_Start——DMA启动
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC_Value, 10);
2、查看DMA中断
3、添加While循环
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(50);
for(i = 0,adc =0; i < 10;)
{
adc += ADC_Value[i++];
}
adc /= 10;
/* USER CODE END WHILE */
ADC_Vol =(float) adc/4096*3.3;
if(ADC_Vol<0||ADC_Vol>3.3){
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
flag=1;
}else if(0<ADC_Vol&&ADC_Vol<0.5){
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
flag=2;
}else if(0.5<ADC_Vol&&ADC_Vol<1.5){
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
flag=3;
}else if(1.5<ADC_Vol&&ADC_Vol<2.5){
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
flag=4;
}else{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
flag=5;
}
/* USER CODE BEGIN 3 */
}
4、Debug–实物调试