江科大--AD单通道&多通道

AD的程序编程步骤如下所示:

第一步,开启RCC时钟,包括ADC和GPIO的时钟。另外这里ADCCLK的分频器,也需要配置一下

第二步,配置GPIO,把需要用的GPIO配置成模拟输入的模式

第三步,选择规则组的输入通道,配置这里的多路开关,把左边的通道接入到右边的规则组列表里。(这个过程就是我们之前说的点菜,把各个通道的菜,列在菜单里)

第四步,就是配置ADC转换器了。在库函数里,是用结构体来配置的,可以配置这一大块电路的参数,包括ADC是单次转换还是连续转换,扫描还是非扫描,有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。

如果需要配置阈值或者检测通道,则会有几个函数用来配置阈值和监测通道。

如果要开启中断,那就在中断输出控制里用ITConfig函数开启对应的中断输出,然后再在NVIC里,配置一下优先级,这样就能触发中断了

那接下来,就是开关控制,调用一下ADC_Cmd函数,开启ADC。

下面在ADC.h库中查看相关库函数的作用:

//用来配置ADCCLK分频器的
//可以对APB2的72Mhz选择不同的分频,输入到ADCCLK
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);

//Delniit恢复初始化配置、Init初始化、Structlnit结构体初始化
void ADC_DeInit(ADC_TypeDef* ADCx);
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);

//ADC Cmd,这个是用于给ADC上电的,也就是PPT这里的开关控制
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);

//DMA Cmd,这个是用于开启DMA输出信号的,如果使用DMA转运数据,那就得调用这个函数
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);

//中断输出控制,用于控制某个中断,能不能通往NVIC
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);

//复位校准、获取复位校准状态、开始校准、获取开始校准状态
void ADC_ResetCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);
void ADC_StartCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);

//ADC软件开始转换控制,这个就是用于软件触发的函数了
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

//第一个函数是,每隔几个脉冲间断
//第二个函数是,是不是启用间断模式
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

//ADC 规则组通道配置
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

//ADC 外部触发转换控制,就是是否允许外部触发转换
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

下面对程序进行编写

AD.C文件注释和程序如下所示:

#include "stm32f10x.h"                  // Device header


void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频--12Mhz
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  //ADC专属模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//通道采样周期(ADC周期)是55.5,转换周期是固定的12.5==68个周期
	//例如:当ADCCLK=14MHz,采样时间为1.5个ADC周期
	//		TCONV = 1.5 + 12.5 = 14个ADC周期 = 1μs
	
	//规则组通道配置
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	
	//单次转换,非扫描
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;	
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据对齐模式
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//连续还是非连续
	ADC_InitStructure.ADC_NbrOfChannel=1;
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);//开启ADC
	
	
	//校准
	ADC_ResetCalibration(ADC1);//开启复位校准(重置所选ADC校准寄存器)
	//获取复位校准状态(等待复位校准完成),也就是读取这一位
	//如果他是一,那么就一直空循环等待
	//如果变为0,那么说明复位校准完成,跳出等待!
	while (ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);//启动校准
	while (ADC_GetCalibrationStatus(ADC1)==SET);
}

uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1,ENABLE); //启用或禁用所选ADC软件启动转换
	//检查是否设置了指定的ADC标志位,ADC_FLAG_EOC转换结束标志
	while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1); //返回常规通道的最后一次ADCx转换结果数据。
}

main.c中程序及注释如下所示:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.H"

uint16_t ADValue;
float Voltage;
int main(void)
{
	OLED_Init();
	AD_Init();
	OLED_ShowString(1,1,"ADValue:");
	OLED_ShowString(2,1,"Voltage:0.00V");
	while (1)
	{
		ADValue=AD_GetValue();
		
		Voltage=(float)ADValue / 4095 * 3.3;//强制类型转换,将0-4096的范围转变为0-3.3
		OLED_ShowNum(1,9,ADValue,4);
		OLED_ShowNum(2,9,Voltage,1);
		OLED_ShowNum(2,11,(uint16_t)(Voltage * 100) % 100,2);//强制类型转换
	}
}
//输出抖动————迟滞比较———设置上阈值和下阈值

下面是关于多通道的程序编写:

由于多通道扫描模式无法手动对数据进行处理(因为每个通道传输完毕,不会单独产生特定的标志位或信号,只有当菜单中的所有通道全部传输完成后才可以出现EOC标志位的变化,此时前面的数据就已经覆盖丢失了),必须借助DMA来避免数据覆盖的问题。

使用单次转换、非扫描模式,在每次触发转换前更换所要触发的通道,之后触发等待读值

uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	//将原本的通道0改为变量参数中的指定通道即可
	ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}

多通道选择通道0、1、2、3对应于GPIO_Pin_0、1、2、3

总的AD.C和MAIN.C函数如下所示:

#include "stm32f10x.h"                  // Device header


void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频--12Mhz
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  //ADC专属模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//通道采样周期(ADC周期)是55.5,转换周期是固定的12.5==68个周期
	//例如:当ADCCLK=14MHz,采样时间为1.5个ADC周期
	//		TCONV = 1.5 + 12.5 = 14个ADC周期 = 1μs

	
	
	//单次转换,非扫描
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;	
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
	ADC_InitStructure.ADC_NbrOfChannel=1;
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);
	
	
	//校准
	ADC_ResetCalibration(ADC1);//开启复位校准
	while (ADC_GetResetCalibrationStatus(ADC1)==SET);
	//获取复位校准状态(等待复位校准完成),也就是读取这一位
	//如果他是一,那么就一直空循环等待
	//如果变为0,那么说明复位校准完成,跳出等待!
	ADC_StartCalibration(ADC1);//启动校准
	while (ADC_GetCalibrationStatus(ADC1)==SET);
}

uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	//将原本的通道0改为变量参数中的指定通道即可
	ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.H"

uint16_t AD0,AD1,AD2,AD3;


int main(void)
{
	OLED_Init();
	AD_Init();
	
	OLED_ShowString(1,1,"AD0:");
	OLED_ShowString(2,1,"AD1:");
	OLED_ShowString(3,1,"AD2:");
	OLED_ShowString(4,1,"AD3:");

	while (1)
	{
		AD0=AD_GetValue(ADC_Channel_0);
		AD1=AD_GetValue(ADC_Channel_1);
		AD2=AD_GetValue(ADC_Channel_2);
		AD3=AD_GetValue(ADC_Channel_3);
		OLED_ShowNum(1,5,AD0,4);
		OLED_ShowNum(2,5,AD1,4);
		OLED_ShowNum(3,5,AD2,4);
		OLED_ShowNum(4,5,AD3,4);
		Delay_ms(1000);
	}
}
//输出抖动————迟滞比较———设置上阈值和下阈值

<think>好的,我现在需要帮用户概括科大STM32教程P1到P35的内容。首先,用户之前问过可能被考察的问题,现在需要更概括性的总结。我要回忆之前的回复结构,看看如何转换。 首先,用户可能是正在学习STM32的学生,任务来自协会,他们需要复习视频内容应对考察。之前的回答是按模块分知识点和问题,现在需要整体概括,可能用户想要一个更简洁的综述,方便快速回顾。 接下来,我需要确定P1到P35大概覆盖哪些内容。根据之前的回答,包括基础概念、GPIO、中断、定时器、通信协议和综合应用。可能视频的前部分讲的是入门知识、环境搭建、GPIO使用,然后逐步深入外设和通信。 我需要分段概括,可能按章节或主题来组织。比如分为入门介绍、GPIO应用、中断系统、定时器、通信协议、其他模块、开发工具和项目实战。这样结构清晰,用户容易浏览。 要注意每个部分的关键点,比如GPIO的工作模式,中断配置步骤,PWM原理,通信协议的区别等。同时要提到开发工具,如Keil、ST-Link,以及调试方法,这可能也是用户关心的。 还要确保使用用户之前提到的LaTeX格式要求,数学公式和术语用$符号包裹。例如,PWM中的ARR和CCR参数,或者通信协议中的时序信号。 另外,用户可能希望知道学习后的能力,比如能完成哪些项目,如LED控制、传感器通信,这能帮助他们自我评估。 最后,检查是否覆盖了所有重要模块,没有遗漏关键内容,比如时钟树配置,这在STM32中很重要。同时要语言简洁,分点明确,方便用户快速复习。</think>科大STM32教程P1-P35核心内容概括(按知识模块划分): 一、**开发基础** 1. 开发环境搭建:Keil MDK安装 + ST-Link驱动配置 2. 工程结构解析: - 启动文件`startup_stm32f10x_hd.s` - 库函数框架(`main.c`/`stm32f10x.h`) 3. 最小系统组成:电源/时钟/复位/下载电路设计要点 二、**GPIO深度解析** 1. 8种工作模式详解: - 输入类(浮空/上拉/下拉/模拟) - 输出类(推挽/开漏 + 复用模式) 2. LED控制实验: ```c GPIO_SetBits(GPIOB, GPIO_Pin_5); // 输出高电平 GPIO_ResetBits(GPIOB, GPIO_Pin_5); // 输出低电平 ``` 3. 按键检测:硬件消抖(电容滤波)vs 软件消抖(延时采样) 三、**中断系统** 1. NVIC优先级管理: - 4种分组方式(如`NVIC_PriorityGroup_2`) - 抢占优先级 vs 响应优先级 2. EXTI配置流程: - GPIO映射到EXTI线(如PB12→EXTI12) - 中断服务函数必须清除挂起标志 四、**定时器应用** 1. PWM波形生成: - 周期由`ARR`决定:$T = (ARR+1) \times \frac{1}{f_{CK\_CNT}}$ - 占空比由`CCR`控制 2. 输入捕获测频:利用两个上升沿的时间差计算频率 3. 定时中断:通过更新事件触发中断 五、**通信协议** 1. USART串口通信: - 波特率计算:$Baud = \frac{f_{PCLK}}{16 \times USARTDIV}$ - 数据帧结构(起始位+数据位+校验位+停止位) 2. I2C总线: - 起始/停止信号时序 - 7位地址寻址模式 3. SPI四线制: - 四种工作模式(CPOL/CPHA组合) 六、**进阶模块** 1. 时钟系统: - 时钟树结构(HSI/HSE/PLL) - 系统时钟配置流程 2. DMA直接存储器访问: - 外设到内存的无CPU干预传输 3. ADC模数转换: - 12位分辨率配置 - 规则通道采样序列设置 七、**开发工具** 1. 调试技巧: - 使用Logic分析仪抓取PWM波形 - 串口printf重定向调试 2. 常见问题排查: - 时钟未使能导致的初始化失败 - 中断标志未清除引发的重复进入 **学习成果**:完成本阶段可掌握LED/按键控制、PWM调光、串口通信、定时器应用等基础开发能力,并能实现温湿度传感器读取、电机控制等综合项目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值