99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

ReCclay
認證:VIP會員
所在專題目錄 查看專題
藍橋嵌入式之 AT24C02
藍橋嵌入式之 PWM波輸出相關總結
藍橋嵌入式之 輸入捕獲(一)
藍橋嵌入式之 輸入捕獲(二)
藍橋嵌入式之 實時時鐘RTC
藍橋嵌入式之 ADC電壓采集與顯示
作者動態 更多
【FPGA基礎】基于 Pango Design Suite(PDS) 的FPGA開發流程
2021-05-14 11:22
【FPGA基礎】基于Quartus Prime 17.1 的FPGA開發流程
2021-05-08 17:49
【AD快速入門】8051最小系統繪制
2021-04-22 10:03
藍橋嵌入式之 ADC電壓采集與顯示
2021-04-14 11:48
藍橋嵌入式之 實時時鐘RTC
2021-04-13 14:50

藍橋嵌入式之 ADC電壓采集與顯示

?導讀:《藍橋杯嵌入式組》專欄文章是博主2019年參加藍橋杯的嵌入式組比賽所做的學習筆記,在當年的比賽中,由于忙于準備考研及保研相關工作,博主僅僅參加了當年的省賽,并獲得了省賽一等獎的成績。成績雖談不上最好,但至少問心無愧。如今2021年回頭再看該系列文章,仍然感觸頗多。為了能更好地幫助到單片機初學者,今年特地抽出時間對當年的文章邏輯和結構進行重構,以達到初學者快速上手的目的。需要指出的是,由于本人水平有限,如有錯誤還請讀者指出,非常感謝。那么,接下來讓我們一起開始愉快的學習吧。

“一葉遮目,不見泰山”。不論何事,只有把握事情的總體趨勢,才能做到心中有數。


1個留待補充的程序:


“為了確保不產生丟失數據的情況,開啟 DMA 傳輸模式,將數據傳輸到內存中”嘗試編程

一、ADC入門

1、基礎知識

模數轉換器(Analog To Digital Converter)簡稱 ADC(也可以寫成 A/D),是指將連續變化的模擬信號轉換為離散的數字信號的器件。 ADC 分為積分型、逐次逼近型、并行/串行比較型、Σ-Δ型等多種類型,STM32F103 自帶的 ADC 屬于逐次逼近型。

逐次逼近型 ADC 與天平稱物重非常相似,從高位到低位逐位比較。首先從最重的砝碼開始試放,與被稱物體行進比較,若物體重于砝碼,則該砝碼保留,否則移去,然后用次重砝碼繼續比較,照此一直到最小一個砝碼為止,將所有留下的砝碼重量相加,就得此物體的重量。逐次逼近型 A/D 轉換器,就是將輸入模擬信號與不同的參考電壓作多次比較,使轉換所得的數字量在數值上逐次逼近輸入模擬量對應值。


2、STM32F103RBT6的ADC時鐘及轉換時間

藍橋板載STM32F103RBT6擁有2路12位(0~4096)ADC,ADC掛載在APB2總線上,且ADC最大時鐘不超過14MHz。所以當APB2總線設置為72M,有必要對其分頻再用于ADC,分頻用到的庫函數是:void ADC_ADCCLKConfig(u32 RCC_ADCCLKSource);

ADC的轉換時間 = 采樣時間 + 12.5周期

采樣時間和實際電路有著莫大的關系,但是對于藍橋的板子而言,對于轉換速度沒有太大要求我們一般設置為:ADC_SampleTime_239Cycles5239.5個周期即可。

3、ADC輸入通道

注意到了兩個ADC模塊,共用了一些通道,不同ADC應用不同通道時,可以同時進行采樣和轉換,但不可以對相同通道同時采樣。

板子對應ADC部分原理圖

PB0管腳可復用為ADC_IN8

ADC1和ADC2兩個通道的都歐克,所以本博客選用了ADC1。

4、ADC的注入組和規則組

在使用 ADC 外部通道時,可以設定為規則組和注入組。規則組就是設定好轉換順序后,按照規則正常轉換;注入組類似于中斷,可以插隊,當觸發信號觸發注入組通道時,優先轉換注入組,轉換完后再繼續轉換規則組;如果正在轉換規則通道期間,注入通道被觸發,當前規則組轉換被復位,注入通道序列被以單次掃描方式轉換,完成轉換后恢復上次被中斷的規則通道轉換。規則組最多可以使用 16 個通道,注入組最多可以使用 4 個通道。

藍橋板子也沒有用到多么復雜,我們就直接使用規則組就好了。

5、ADC的單通道和多通道

當“轉換組”只有一個通道轉換時稱之為單通道模式,當有多個通道按順序轉換時稱之為多通道模式或者掃描模式。

藍橋板子,使用單通道即可。

6、ADC的單次轉換和連續轉換

當規則組或注入組的通道按照設定順序執行一次采轉換后即停止工作,這種模式稱之為單次轉換模式;如果執行完一次轉換后,ADC 沒有停止,而是立即啟動新一輪轉換,這種模式稱之為連續轉換模式。

藍橋板子,使用單次轉換即可。

7、觸發源

觸發啟動轉換:觸發啟動轉換分為兩種方式,分別是軟件觸發和外部事件觸發(外部是相對于 ADC 外設來講),其中外部事件觸發又分為定時器觸發和外部觸發(這里的外部指的是芯片外部信號)。

藍橋板子,使用軟件觸發即可

8、轉換后的數據儲存

①、規則組存儲

在獨立 ADC 模式下,規則組通道轉換完成后,轉換后的數據被存儲在對應的 ADC 規則數據寄存器 ADC_DR 的低 16 位。

雙 ADC 模式是 ADC1 和 ADC2 同時采集某些參數,比如要獲取瞬時功率需要同時采集電壓和電流參數才能準確計算結果,這種場合就必須使用雙 ADC 模式。這種模式下 ADC1所對應的 ADC_DR 的高 16 位存儲 ADC2 的規則數據,低 16 位存儲 ADC1 的規則數據。

由于 ADC 的精度是 12 位,因此在將 ADC 的 12 位數據存入 16 位的數據寄存器中時,可以通過 ADC_CR2 寄存器的 ALIGN 位來選擇數據是左對齊還是右對齊。

規則通道最多有 16 個通道,但規則數據寄存器只有一個,因此當使用多通道轉換時,前一個轉換的通道數據,會被后一個通道轉換的數據覆蓋掉,因此理論上必須在后一個通道轉換完畢之前就把數據取走

為了確保不產生丟失數據的情況,開啟 DMA 傳輸模式,將數據傳輸到內存中是一個好辦法,這個到時候作為擴展例程寫。

②、注入組存儲

ADC 注入組最多有 4 個通道,每個通道都有對應的數據寄存器 ADC_JDRx(x=1..4),ADC_JDRx 是 32 位的,高 16 位保留,低 16 位用來保存數據,選擇數據是左對齊還是右對齊都由 ALIGN 決定。

9、中斷處理

如果打開相應的中斷,有三種情況可以進入中斷。 (1)規則通道轉換完成中斷

  1. 轉換數據被存儲在 16 位的 ADC_DR 寄存器中。
  2. EOC(轉換結束)標志被置位。
  3. 如果設置了 EOCIE 位,則產生中斷。

(2)注入通道轉換完成中斷

  1. 轉換數據被存儲在 16 位的 ADC_DRJx 寄存器中。
  2. JEOC(注入轉換結束)標志被置位。
  3. 如果設置了 JEOCIE 位,則產生中斷。

(3)模擬看門狗中斷 如果開啟了模擬看門狗中斷,并且設置ADC低閾值ADC_LTR和高閾值ADC_HTR, 當采集到的電壓高于高閾值或者低于低閾值時,就會產生模擬看門狗中斷。

關于ADC中斷這部分,這里也沒有具體涉及到,等日后做題做到了再補充吧。目前也只用到了查詢的方式。

10、ADC校準

ADC 有一個內置自校準模式,可以大幅減小由于內部電容的變化而造成的精準度誤差。通過設置 ADC_CR2 寄存器的 CAL 位啟動校準,一旦校準結束,CAL 位被硬件復位。建議在每次上電時執行一次 ADC 校準,啟動校準前,ADC 必須處于上電狀態(ADON=‘1’)(言外之意必須先使能ADC),至少超過兩個 ADC 時鐘周期。

校準代碼是固定的,參考下面的代碼即可。

11、 使能通道觸發轉換

規則組和注入組觸發方式方式分為軟件觸發和外部觸發,其中外部觸發包括定時器觸發和外部信號觸發。如果設置了規則組或注入組觸發方式,還需要使能相應觸發,保證在觸發到來時啟動轉換。

規則組軟件觸發相應函數為void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

12、轉換結束標志位

看手冊介紹

可以由軟件清除或者讀取數據寄存器清除!

13、總結配置流程

1、初始化 ADC1 通道引腳(內部溫度傳感器和參照電壓通道不需要進行引腳初始化) 2、配置 ADC1 中斷優先級(如果使用 ADC 中斷,本節未使用) 3、使能 ADC1 外設時鐘 4、設置 ADC1 預分頻系數 5、復位 ADC1 6、配置 ADC1 初始化結構體 7、設置規則組轉換順序和采樣時間 8、使能 ADC1 中斷(本節未使用) 9、使能 ADC1 外設 10、校準 ADC1 11、使能 ADC1 軟件觸發或外部觸發轉換 12、編寫中斷服務函數(如果使用 ADC 中斷,本節未使用)

二、主要代碼

main.c

/*******************************************************************************
* 文件名:main.c
* 描  述:
* 作  者:CLAY
* 版本號:v1.0.0
* 日  期: 2019年1月27日
* 備  注:ADC轉換實現電壓測量
*         
*******************************************************************************
*/

#include "config.h"
#include "led.h"
#include "key.h"
#include "timer.h"
#include "beep.h"
#include "lcd.h"
#include "stdio.h"
#include "rtc.h"
#include "adc.h"

u8 ADC_Flag = 0;
u8 string[20];
float adc_val;

int main(void)
{

	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	LEDInit();
	KeyInit();
	BeepInit();
	TIM2Init(2000, 72);//定時2ms
	
	ADC1Init();
	
	while(1)
	{	
		KeyDriver();
		if(ADC_Flag )
		{
			ADC_Flag = 0;
			adc_val = Get_ADC(8) * 3.3 / 4096;
			sprintf((char*)string,"ADC_VAL : %.2f    ",adc_val);
			LCD_DisplayStringLine(Line2, string);
		
		}
	}
}

void KeyAction(int code)
{
	if(code == 1)//按下B1,切換燈狀態,蜂鳴器鳴叫0.1s
	{
		GPIOC->ODR ^= (1<<8);//PC8不斷取反
		GPIOD->ODR |= (1<<2);//PD2置1,使能573鎖存器
		GPIOD->ODR &= ~(1<<2);//PD2清0,關閉573鎖存器
		Beep(100);
	}
	else if(code == 2)
	{
		Beep(-1);
	}
	else if(code == 3)
	{
		Beep(0);
	}
	else if(code == 4)
	{
		
	}
}



adc.c

#include "adc.h"

void ADC1_IOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB口時鐘
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//選中PB0引腳
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模擬輸入
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化IO
}

void ADC_Cali(void)
{
	ADC_ResetCalibration(ADC1);//使能復位校準
	while(ADC_GetResetCalibrationStatus( ADC1));//等待復位校準結束
	ADC_StartCalibration( ADC1);//開啟AD校準
	while(ADC_GetCalibrationStatus(ADC1));//等待校準結束
}

void ADC1Init(void)
{
	ADC_InitTypeDef ADC_InitStructure;
	
	ADC1_IOInit();//ADC的GPIO配置
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//使能ADC時鐘,APB2總線
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADC最大時鐘不超過14M,這里盡心了對APB2時鐘進行6分頻=12M
	ADC_DeInit(ADC1);//復位ADC
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC獨立模式
	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_Cmd(ADC1, ENABLE);//使能ADC
	ADC_Cali();//ADC校準
}

u16 Get_ADC(u8 channel)
{
	u16 temp;
	
	ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);//ADC采樣時間239.5周期 總轉換時間=采樣時間+12.5周期
	ADC_SoftwareStartConvCmd( ADC1,ENABLE);//使能ADC1軟件觸發轉換,觸發一次ADC轉換
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == 0);//等待ADC轉換完畢
	temp = ADC_GetConversionValue( ADC1);//獲取轉換結果,注意此時已經自動清除EOC位
	ADC_SoftwareStartConvCmd( ADC1,DISABLE);//失能ADC轉換
	
	return temp;
}




adc.h

#ifndef _ADC_H
#define _ADC_H


#include "config.h"

void ADC1Init(void);
u16 Get_ADC(u8 channel);

#endif


stm32f10x_it.c

extern u8 ADC_Flag;

void TIM2_IRQHandler(void)
{
	static u16 tmr500ms = 0;
	
	if(TIM_GetITStatus(TIM2, TIM_FLAG_Update))
	{
		TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);
		
		tmr500ms++;
		
		KeyScan();
		BeepScan(2);//2ms掃描
		if(tmr500ms >= 250)
		{
			tmr500ms = 0;
			ADC_Flag = 1;
		}
	}
}

三、注意事項

定時器設定500ms讀取一次AD值

結語:以上就是本篇文章的全部內容啦,希望大家可以多多支持我的原創文章。如有錯誤,請及時指正,非常感謝。

聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 146
收藏 146
關注 431
成為作者 賺取收益
全部留言
0/200
  • dy-i2UfRuvP 2021-05-19 13:17
    對我很有幫助
    回復
  • dy-iipPZRPN 2021-05-13 22:38
    思路清晰,受益匪淺
    回復
  • dy-3EbVR6Ei 2021-05-13 22:27
    比論文強一萬倍
    回復
  • dy-Xq2JxpfN 2021-05-13 22:12
    比論文強一萬倍
    回復
  • dy-9g42stbW 2021-05-13 21:55
    什么時候更新
    回復
  • dy-mLj7kl5v 2021-05-13 20:31
    大開眼界,真是好文
    回復
  • dy-apcih3c1 2021-05-13 20:11
    感謝分享
    回復
  • dy-k78ZHtFD 2021-05-13 20:01
    學習了
    回復
  • dy-nAWdnPGS 2021-05-13 18:49
    比論文強一萬倍
    回復
  • dy-prSX6RBY 2021-05-13 18:38
    圍觀學習
    回復
  • dy-jqGVYqsF 2021-05-13 16:05
    大開眼界,真是好文
    回復
  • dy-VIQ9auhf 2021-05-13 14:54
    圍觀學習
    回復
  • dy-7mura2gg 2021-05-13 14:44
    對我很有幫助
    回復
  • dy-YN3DYTeH 2021-05-13 14:34
    講的真好!
    回復
  • dy-9hjGevyn 2021-05-13 13:32
    佩服樓主
    回復
  • dy-H1WY5jXH 2021-05-13 13:13
    什么時候更新
    回復
  • dy-wVQjSHHX 2021-05-13 12:59
    對我很有幫助
    回復
  • dy-88VlYaFf 2021-05-12 15:35
    不亞于看了一篇高質量論文
    回復
  • dy-9QTV6UZW 2021-05-12 15:23
    精彩,很多東西還沒接觸到
    回復
  • dy-WYS5BCmB 2021-05-12 15:10
    大開眼界,真是好文
    回復
主站蜘蛛池模板: 蜜芽国产成人精品区 | 久久婷av| 扒开双腿猛进入喷水高潮视频 | 欧美大BBBB流白水 | www在线免费 | 一本一道波多野结衣av黑人 | 日韩毛片网站 | 国产精品泄火熟女 | 1024久久 | 日本黄色xxxxx | 免费成人在线观看 | 亚洲永久经典 | 成人毛片视频网站 | 欧美熟妇大胆bbww | 羞羞答答xxdd在线播放 | 国产v精品成人免费视频400条 | 四虎影院www | 国产不卡免费视频 | 美女把尿口扒开让男人桶爽 | 亚洲精品少妇30p | 扒开粉嫩的小缝喷白浆 | 国产视频在线播放 | aⅴ免费一区二区三区 | yuozzij视频zzij欧美 | 爆乳无码中文字幕在线观看 | 精品一区二区免费视频 | 视频一区视频二区国产精品 | 蜜臀av免费一区二区三区久久乐 | 日本成片区免费久久 | 国产一级视频免费看 | 午夜国产| 久久一区二区三区精华液介绍 | 亚洲国产成在人网站天堂 | 日韩综合av| 人妻互换一二三区激情视频 | 久久国产精品成人免费网站 | 蜜桃av网站 | 秋霞无码一区二区视频在线观看 | 一二三四在线观看免费中文在线观看 | 青娱乐99| 91国在线 |