MCU:STM32F103ZET6
IDE: MDK-ARM V5 +STM32CubeMX5.0.0
串口调试助手:SSCOM3.2
功能描述:通过ADC1通道1采样外部电压值,将采样的AD值和转换后的电压值通过串口打印出来。需要配置的有USART1和ADC。
根据原理图可知ADC1的通道1的引脚为PA1,因此设置PA1为ADC1_IN1模式。
分别设置模式,单单个扫描和单次扫描,并在规则通道参数设置中设置为软件触发的方式。(对应的标准库代码在右上角)。
配置时钟为72 Mhz。
Tips:最好把Linker Settings中的Minimum Heap Size设置为0x600。
最后点Generate Code生成代码,并选择“Open Project”:
和笔记4相同,同样需要用到串口输出的功能,首先将printf()函数的输出功能映射到串口上:
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/* USER CODE BEGIN 0 */
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);
return ch;
}
/* USER CODE END 0 */
3. 在main.c中设置变量用于存储AD和电压值:(注意VOL_Value一定是浮点型的)
/* USER CODE BEGIN 1 */
uint16_t ADC_Value;
float VOL_Value;
/* USER CODE END 1 */
4.在while(1)循环中添加AD与电压转换程序:
步骤依次为:
① HAL_ADCEx_Calibration_Start()//校准ADC
② HAL_ADC_Start()//开启ADC
③ HAL_ADC_PollForConversion()//等待转换过程
④若if循环判断转换完成后,HAL_ADC_GetState()获取AD值存在ADC_Value中并打印。
⑤将AD值转换为电压值存在VOL_Value中并打印。
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_ADCEx_Calibration_Start(&hadc1); //校准
HAL_ADC_Start(&hadc1); //开启
HAL_ADC_PollForConversion(&hadc1,50); //等待转换完成
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
{
ADC_Value=HAL_ADC_GetState(&hadc1);
printf("检测AD值为:%d\r\n",ADC_Value);
VOL_Value=ADC_Value*3.3/4096;
printf("检测电压值为:%.2fV \r\n",VOL_Value);
}
HAL_Delay(200);
/* USER CODE END WHILE */
至此应该是完成了HAL库下ADC转换读取电压的程序,但是不知是硬件出了问题还是软件有逻辑错误,我的电压值一直很小,变化也不大,希望有遇到相同问题的朋友可以交流一下。(基于标准库函数的程序也遇到了这个问题)。
2019/2/20 10:23 更新:
针对上述问题,经过反复检查程序找到了问题。源程序如下:
u16 Get_ADC_Value(u8 ch,u8 times) //获取AD转换值的结果
{
u8 t;
u8 temp_val=0;
ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5); //最大的转换周期,239.5个
for (t=0;t
temp_val的取值范围是0-4095,因此应定义为32位的变量:u8 temp_val=0→u32 temp_val=0;
针对HAL库中程序,一定要定义VOL_Value为浮点型的。
则会得到正确的结果: