IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 嵌入式设计与开发项目-ADC应用程序设计(解决多通道冲突问题) -> 正文阅读

[嵌入式]嵌入式设计与开发项目-ADC应用程序设计(解决多通道冲突问题)

一、实现的功能

ADC有18个转换通道,其中通道0~通道15是外部通道,使用的GPIO如下图:在这里插入图片描述
ADC1的通道16与内部的温度传感器相连(推荐采样17.1us),通道17与参考电源VREFINT 相连,使用ADC_TempSensorVrefintCmd()使能。

  • ①通过LED1 ~ LED8显示0 ~ 255的数据,每隔1s增加1;
  • ②每隔1s获取一次内部温度AD值和通道8外接电位器的AD值,并将其AD值和电压值打印到串口上面;
  • ③把内部温度的AD值转化为温室值;
    串口效果图:在这里插入图片描述

二、根据功能实现代码

1、主文件main.c

#include"key.h"
#include"led.h"
#include"lcd.h"
#include "usart.h"
#include "i2c.h"
#include "adc.h"

unsigned int uiAdc_Val;
unsigned char ucSec,ucSec1;
unsigned char pucStr[21];
unsigned long ulTick_ms;

void ADC_Proc(void);

int main(void)
{
	SysTick_Config(72000);	//定时1ms(HCLK = 72MHz)
	KEY_Init();
	LED_Init();
	
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	USART2_Init(9600);
	i2c_init();
	ADC1_Init();
	
	sprintf((char *)pucStr,"	ADC DEMO");
	printf("%s\r\n",pucStr);
		
	while(1)
	 {
		LED_Disp(ucSec);
		ADC_Proc();
	 }
	}
	
	void ADC_Proc(void)
	{
		float fAdc_Val;
		if(ucSec != ucSec1)
		{
			ucSec1 = ucSec;
			
			uiAdc_Val = ADC1_Conv();
			fAdc_Val = (float)uiAdc_Val*3.3/4095;
			sprintf((char *)pucStr,"	%04u %5.2f",uiAdc_Val,fAdc_Val);
			printf("%s",pucStr);
			
			uiAdc_Val = ADC1_InjeConv();
			fAdc_Val = (float)25+(5855.85-3.3*uiAdc_Val)/17.6085;
			sprintf((char *)pucStr,"	%04u %5.2f",uiAdc_Val,fAdc_Val);
			LCD_DisplayStringLine(Line6,pucStr);
			printf("%s\r\n",pucStr);
		}
	}
//SysTick 中断处理程序
	void SysTick_Handler(void)
	{
		ulTick_ms++;
		if(ulTick_ms % 1000 ==0)
		ucSec++;
		
	}
	

主函数分析:?? ?? ??

  1. 通过ucSec1和ucSec变量判断是否相等,判断上一次的状态是否与现在不同,从而实现1s采集一次ADC值;
  2. ADC值与电压的转化关系(分辨率为12,参考电压为3.3v),采集的电压 = 采集的ADC值 / 4095(212-1) * 3.3
  3. %04u 表示用4位数字表示uiAdc_Val,如果不够4位往前面补0,%5.2f 表示用5位数并包含2位小数表示fAdc_Val;
  4. 通道16所连内部温度的计算,芯片内部温度 = 25 + (5855.85 - 3.3 * ADC值) / 17.6085;

2、ADC头文件“adc.h”

#include"stm32f10x.h"

void ADC1_Init(void);
unsigned int ADC1_Conv(void);
unsigned int ADC1_InjeConv(void);

简要分析:?? ??

  1. 包含通道8对于的引脚PB0和通道16以及ADC1的初始化;
  2. 转换通道使用规则通道返回的ADC值;
  3. 转换通道使用注入通道返回的ADC值;

3、ADC源文件“adc.c”

#include"adc.h"
void ADC1_Init(void)
{
	//初始化结构体
	GPIO_InitTypeDef GPIO_InitStruct;
	ADC_InitTypeDef ADC_InitStruct;
	
	//允许GPIOB和ADC1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	
	//PB0-IN8模拟输入
	GPIO_InitStruct.GPIO_Pin =GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Mode =GPIO_Mode_AIN;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	//初始化ADC1
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;		//独立工作模式
	ADC_InitStruct.ADC_ScanConvMode =DISABLE;		//非扫描模式,采集多通道才使能
	ADC_InitStruct.ADC_ContinuousConvMode =DISABLE;		//关闭连续转换 
	ADC_InitStruct.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None;		//禁止触发检测,使用软件触发 
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;		//右对齐
	ADC_InitStruct.ADC_NbrOfChannel = 1;		//顺序进行规则转换的ADC通道的数目(根据ADC采集通道数量修改)
	ADC_Init(ADC1,&ADC_InitStruct);		//ADC1初始化
	
	//配置通道8
	ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1,
	ADC_SampleTime_1Cycles5);		//设置指定 ADC 的规则组通道8,一个序列,采样时间1.5个周期
	//配置通道16
	ADC_InjectedChannelConfig(ADC1, ADC_Channel_16, 1,
	ADC_SampleTime_239Cycles5);		//设置指定 ADC 的注入组通道16,一个序列,采样时间239.5个周期
	
	ADC_TempSensorVrefintCmd(ENABLE);	//使能内部通道	
	ADC_AutoInjectedConvCmd(ADC1,ENABLE);  //用于使能或失能规则通道组转换结束后自动的注入通道组转换
	
	//启动ADC1
	ADC_Cmd(ADC1,ENABLE);
	//校准ADC1
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1));		//等待校准结束
}

unsigned int ADC1_Conv(void)
{
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);		//使能指定的ADC1的软件转换启动功能
	while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
			return ADC_GetConversionValue(ADC1);
}

unsigned int ADC1_InjeConv(void)
{
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能
	while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_JEOC));
			return ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
}

简要分析:?? ??

  1. 通道8所对应的PB0的GPIO初始化顺序:①初始化GPIO结构体②使能GPIOB对应的APB2时钟③配置引脚、模拟输入模式④初始化GPIO的结构体
  2. 配置ADC1的顺序:①初始化ADC结构体②使能ADC1对应的APB2时钟③配置工作模式、(禁止)使能扫描模式、(禁止)使能连续转换模式、不使用外部中断触发、向右对齐、ADC转换通道一个④初始化ADC1的结构体⑤配置通道的采样顺序与周期⑥使能规则和注入通道⑦启动ADC1⑧进行ADC的校准
  3. 获取规则通道ADC值unsigned int ADC1_Conv(void),先启动ADC1的软件转换功能,然后检测是否获取到ADC的标志位,最后**ADC_GetConversionValue()**获取规则通道的值;
  4. 获取注入通道ADC值unsigned int ADC1_InjeConv(void),先启动ADC1的软件转换功能,然后检测是否获取到ADC1的标志位,清除标志位,最后通过**ADC_GetInjectedConversionValue()**返回标志位;

三、实现功能过程的注意与学习点

1、注意点

1、同一个ADC进行多个规则通道采集,会产生串联干扰,可分别设置规则通道和注入通道进行ADC采集,解决多通道采集干扰问题;
2、配置ADC参数可根据实际需求进行配置,可灵活更换一些参数;

2、学习的知识点

  1. 规则通道由最多16个通道组成,按顺序转换,使用ADC_RegularChannelConfig()进行配置,使用ADC_GetConversionValue()获取转换值;
  2. 注入通道由最多4个通道组成,可插入转换,使用ADC_InjectedChannelConfig()进行配置,使用ADC_GetInjectedConversionValue()获取转换值
  3. ADC通道配置的一个主要参数是采样时间,采样时间通过采用周期数进行配置,两者的关系是 : ` `` 采样时间 = (采样周期数 + 12.5) / fADCCLK (ADC时钟频率)
  4. 默认状态下,ADCCLK为36MHz,改变规则通道8会引起内部通道16的波动,是因为采样时间有问题,RCC_ADCCLKConfig(RCC_PCLK2_Div6)设置ADCCLK为12MHz温度基本保持稳定。
    ?? ?? ?? ?? ?? ??
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:58:46  更:2022-04-18 17:59:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:33:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码