Driver_ADC.c
如果需要关闭adc转换,只需要设置CNT,将其置为0,后面再转换一次就停止了。
#include "Driver_ADC.h"
void Driver_ADC1_Init(void)
{
/* 1. 时钟配置 */
/* 1.1 adc时钟 */
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->CFGR |= RCC_CFGR_ADCPRE_1;
RCC->CFGR &= ~RCC_CFGR_ADCPRE_0;
/* 1.2 gpio的时钟 */
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
/* 2. gpio工作模式: PC0 模拟输入 CNF=00 MODE=00 */
GPIOC->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_MODE0);
/* 2. ADC相关配置 */
/* 2.1 禁用扫描模式. 只有一个通道不用扫描 */
ADC1->CR1 &= ~ADC_CR1_SCAN;
/* 2.2 启用连续转换模式 CR2=CONT 1*/
ADC1->CR2 |= ADC_CR2_CONT;
/* 2.3 数据对齐方式: 右对齐 左对齐 */
ADC1->CR2 &= ~ADC_CR2_ALIGN;
/* 2.4 设置采样时间 ADC_SMPR1 010=13.5周期*/
ADC1->SMPR1 &= ~(ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_0);
ADC1->SMPR1 |= ADC_SMPR1_SMP10_1;
/* 2.6 通道组的配置 */
/* 2.6.1 配置几个通道需要转换 */
ADC1->SQR1 &= ~ADC_SQR1_L;
/* 2.6.1 把通道号配置到组里面. */
ADC1->SQR3 &= ~ADC_SQR3_SQ1; /* 先把5位清零 */
ADC1->SQR3 |= 10 << 0; /* 设置最后5位 */
/* 2.7 选择软件触发 */
ADC1->CR2 &= ~ADC_CR2_EXTTRIG; /* 禁用规则组的外部转换 */
ADC1->CR2 |= ADC_CR2_EXTSEL; /* 选择使用软件触发ADC */
}
void Driver_ADC1_StartConvert(void)
{
/* 1. 上电: 把ADC从休眠模式唤醒 */
ADC1->CR2 |= ADC_CR2_ADON;
/* 2. 执行校准 */
ADC1->CR2 |= ADC_CR2_CAL;
while (ADC1->CR2 & ADC_CR2_CAL)
;
/* 3. ADON = 1, 开始转换 0>1 从休眠模式唤醒 1->1 开始 */
ADC1->CR2 |= ADC_CR2_ADON;
/* 4. 使用软件开始转换规则通道 */;
ADC1->CR2 |= ADC_CR2_SWSTART;
/* 5. 等待首次转换完成 */
while((ADC1->SR & ADC_SR_EOC) == 0);
}
double Driver_ADC1_ReadV(void)
{
// 12位的ADC 范围 [0, 4095]
return ADC1->DR * 3.3 / 4095;
}
Driver_ADC.h
#ifndef __DRIVER_ADC_H
#define __DRIVER_ADC_H
#include "stm32f10x.h"
void Driver_ADC1_Init(void);
void Driver_ADC1_StartConvert(void);
double Driver_ADC1_ReadV(void);
double Driver_ADC1_ReadV(void);
#endif
main.c
#include "Driver_USART.h"
#include "Delay.h"
#include "Driver_ADC.h"
int main()
{
Driver_USART1_Init();
printf("ADC单通道\r\n");
Driver_ADC1_Init();
Driver_ADC1_StartConvert();
while (1)
{
double v = Driver_ADC1_ReadV();
printf("v = %.2f\r\n", v);
Delay_s(1);
}
}