学习板为stm32F103VET
1 STM32的ADC简单介绍
1.1拥有3个ADC,可以单独使用,也可以使用双重模式(目前就学习了单独使用),
1.2stm32的ADC是12位的模数转换器(所以这里存在左对齐和右对齐两种模式,左对齐得到的数值要除以16),
1.3具有18通道可测量16个外部和2个内部信号源(使用较多的就是测量外部信号),各通道具有4种模式:单次,连续,扫描,间断
1.4不要让ADC的时钟超过14M,ADC在APB2上,所以一般设置6分频,
1.5ADC转换分为2个通道组,规则和注入通道组,可以把注入理解为中断(这里不太懂,日后加强)
2 STM32ADC的一些重要寄存器
2.1 ADC_CR1和ADC_CR2
ADC_CR1的第8位SCAN位,设置扫描模式,1:开启 ;0:关闭
ADC_CR1的16-19位共4位设置ADC的操作模式,本次学习,只使用了独立模式,所以设置为0000
ADC_CR2的第0位ADCON用于开关ADC转换器
ADC_CR2的第1位CONT用于设置是否连续转换,本次学习使用单次转换,设置为0
ADC_CR2的第11位ALIGN用于设置ADC_DR(AD转换结束读取的数据)的对齐方式
ADC_CR2的第17-19位用于选择启动规则转换组转换的外部事件,详情查阅dataSheet,本次使用软件触发(SWSTART),该3位设置为111
2.2 ADC_SMPR1和ADC_SMPR2
这两个寄存器用于设置通道0~17的采样时间,(SMPR1包括10-17通道,SMPR2包括0-9通道)每个通道占用3个位:
000-111 8种采样时间,本次学习使用111:239.5周期
2.3 ADC_SQR1~3
2.4 ADC_DR
AD转化结果都将被存在这个寄存器里面(有左对齐和右对齐2种方式)
2.5 ADC_SR
位1 EOC:转换结束标志位(1:转换完成,由软件清除或读取ADC_DR后自动清除)
位2 JEOC:注入通道转换结束标志位
位3 JSTRT:注入通道开始位
位4 STRT:规则通道开始位
用的较多的是位1,用于判断AD转换结束后,读取转换结果
3 使用库函数完成本次的简单ADC转换的例子
void RCC_Configuration(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //USART用于将AD转换结果输出到电脑查看
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //ADC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
}
//管脚配置
void GPIO_Configuration(void){
//UASRT PA9 and PA10
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//ADC
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0作为模拟量输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void USART_Configuration(void){
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No; //无校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件控制
USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1,ENABLE);
USART_ClearFlag(USART1,USART_FLAG_TC); //先清除发送完成标志位,防止第一次发送出现异常
}
void ADC_Configuration(void){
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode=DISABLE; //关闭扫描模式
ADC_InitStructure.ADC_ContinuousConvMode=DISABLE; //工作在单次模式
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; //软件触发方式
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_NbrOfChannel=1; //只进行1个通道进行规则转换
ADC_Init(ADC1,&ADC_InitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5); //确定ADC1的通道0,采用时间为239.5周期
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1); //开始复位校验
while(ADC_GetResetCalibrationStatus(ADC1)); //
ADC_StartCalibration(ADC1);//开始AD校验
while(ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1,ENABLE); //手动开启ADC转换
}
主函数:
int fputc(int ch,FILE* f){
USART_SendData(USART1,(u8)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return ch;
}
int main(void){
u32 ad = 0;
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART_Configuration();
ADC_Configuration();
while(1){
ad = 0;
for(i=0;i<50;i++){ //获取50次,取平均值,提高精度
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
ad=ad+ADC_GetConversionValue(ADC1);
}
ad=ad/50;
printf("ad =%f\r\n",3.3/4095*ad);
delay_ms(1000);
}
}