由于使用STM32的F103MCU,proteus选择R6型号,所以CUBEMX选型STM32F103R6。
proteus仿真频率不能太高,所以CUBEMX时钟使用内部8MHz。使用了串口USART1波特率设置为9600,也是考虑为了适应proteus,使ADC1。选择IN1、IN2、IN3三个通道。其余参数设置如下图1。注意设置三个规则通道的采集顺序:IN1:rank1、IN2:rank2、IN3:rank3。
DMA设置 add ADC1,设置如下图2:
生成keil初始化工程,添加串口一重定位代码(可添加到main.c中):
#if 1
#include <stdio.h>
/* 告知连接器不从C库链接使用半主机的函敿 */
#pragma import(__use_no_semihosting)
/* 定义 _sys_exit() 以避免使用半主机模式 */
void _sys_exit(int x)
{
x = x;
}
/* 标准库需要的支持类型 */
struct __FILE
{
int handle;
};
FILE __stdout;
/* */
int fputc(int ch, FILE* stream)
{
/* 堵塞判断串口是否发鿁完房 */
/* 不同芯片的串口标志位不一定相同! */
while((USART1->SR & 0X40) == 0);
/* 串口发鿁完成,将该字符发鿿 */
USART1->DR = (uint8_t) ch;
return ch;
}
#endif
主函数如:
int main(void)
{
uint16_t ADC_Value[90];
uint8_t i;
uint16_t ad1, ad2, ad3;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_USART1_UART_Init();
while(1)
{
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&ADC_Value,90);
for(i=0,ad1=0,ad2=0,ad3=0;i<90;){
ad1 += ADC_Value[i++];
ad2 += ADC_Value[i++];
ad3 += ADC_Value[i++];
}
ad1 /=30;ad2 /=30;ad3 /=30;
printf("\r\n========ADC-DMA-TEST=========\r\n");
printf("V_in1=%1.3fV\r\n",ad1*5.0f/4096);
HAL_Delay(50);
printf("V_in2=%1.3fV\r\n",ad2*5.0f/4096);
HAL_Delay(50);
printf("V_in3=%1.3fV\r\n",ad3*5.0f/4096);
HAL_Delay(50);
}
/* USER CODE END 3 */
}
我用的是proteus8.15 ,都懂的方法安装的。proteus仿真效果如下:
这个实例proteus仿真很难成功,可以观察采集结果,但是电压数值一直变化,究竟是DMA使用不对,还是proteus的问题,请各位大神帮忙分析一下。
所有工程(proteus、CUBEMX,keil-mdk)全部奉上,供交流学习。
Keil代码与Proteus仿真下载:
STM32F103R6-HAL - ADC_DMA多通道采集.7z
(421.38 KB, 下载次数: 79)
|