实验的代码已经上传,无需积分。
1.1 资源概述开发板:正点原子STM32F103 Nano开发板
CUBEMX版本:1.3.0
MDK版本:5.27
主控芯片型号:STM32F103RBT6
1,适配正点原子STM32F103RB Nano开发板;
2,配置由CUBEMX生成;
3,采样AD的数值,并在串口上打印出来。
4,ADC运行时,LED0灯闪烁,当输出5次后,关闭ADC,同时LED0灯常亮。
3.3V通过电位器分压,最后送到芯片的PB1脚。调整VR1的值,即可调整ADC的值。
1,时钟配置,CUBEMX配置为6分频,最后时钟频率为12MHz。ADC的采样频率不能高于14MHz。最短采样周期为(1.5+12.5)/14M=1uS
2,配置ADC,采样独立模式,数据右对齐,单次采样,规则通道。
1,main()函数代码如下,使用CUBEMX生成,删除掉无用的注释信息,并增加我们需要使用的代码。
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
void LED0_ON(void);//函数在一开始进行申明,以;结束
void LED0_OFF(void);
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
int main(void)
{
uint16_t t=0;
uint16_t ADC_B=0;
float ADC_D=0;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_USART1_UART_Init();
HAL_ADC_Start(&hadc1);//开启ADC
for (t=0;tBSRR = LED0_Pin;//打开LED0
}
void LED0_OFF(void)
{
GPIOC->BSRR = (uint32_t)LED0_Pin << 16u;//关闭LED0
}
void Error_Handler(void)
{
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif /* USE_FULL_ASSERT */
2,ADC初始化函数如下。
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig={0};//初始化函数声明
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; //关闭扫描
hadc1.Init.ContinuousConvMode = DISABLE;//连续转换模式无效
hadc1.Init.DiscontinuousConvMode = DISABLE;//无效连续转换模式
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;//外部触发为软件启动
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;//数据右对齐
hadc1.Init.NbrOfConversion = 1;//转换次数
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_9;//配置采样通道
sConfig.Rank = ADC_REGULAR_RANK_1;//配置规则通道
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;//配置采样周期
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
程序中对开灯关灯的函数进行了简化,直接操作寄存器,没有使用HAL 函数,相比原函数,少了有效性判定,更加简洁,占用的空间更少,在项目中,建议前期可以使用HAL函数实现,后续将HAL函数剥离,使用寄存器的方式,这样做有几个好处:
①,消除HAL函数中可能存在的BUG。
②,提高程序效率,降低Flash使用空间,特别是当程序空间在64K,128K等这种两种芯片分段附近大小时,通过这种方式,有可能使芯片使用低一个档次的,实现更低的成本。
当然如果项目仅仅是实验性质的,并没有大批量生产的需求或者市场窗口周期极短,就没必要折腾了。HAL函数是最快最简洁的方式。连ST官网的新一代芯片后续都不计划提供标准库函数版本了,只提供HAL函数版本的支持。
自定义函数采用先定义后使用的方式,另外对于无形参无返回值的函数void LED0_ON(void)在主程序中的使用方式为 LED0_ON();不要画蛇添足添加void,添加void表明这个还是函数声明,而不是函数使用。
3,ADC函数说明
配置采样通道 ADC_CHANNEL_9和配置规则通道ADC_REGULAR_RANK_1示意如下。
扫描打开示意如下,本例子中只需要一个ADC,无需开启扫描。
单次转换模式和连续转换模式,
ADC有非常多种使用方法,其它使用方式参数其对应的参考手册。
实验结果如下,符合预期。