国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32 HAL庫 STM32CubeMX -- ADC

這篇具有很好參考價值的文章主要介紹了STM32 HAL庫 STM32CubeMX -- ADC。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


一、ADC 簡介

ADC(Analog-to-Digital Converter)指模/數(shù)轉換器或者模擬/數(shù)字轉換器。 是指將連續(xù)變量的模擬信號轉換為離散的數(shù)字信號的器件。

也就是將模擬信號轉化為數(shù)字信號。

STM32f103 系列有3 個ADC,精度為12 位,每個ADC 最多有16 個外部通道和2個內部信號源。其中ADC1 和ADC2 都有16 個外部通道,ADC3 根據(jù)CPU 引腳的不同通道數(shù)也不同,一般都有8 個外部通道。

各通道的A/D轉換可以單次、連續(xù)、掃描或間斷模式執(zhí)行。

ADC的結果可以左對齊或右對齊方式存儲在16位數(shù)據(jù)寄存器中。

二、ADC功能框圖

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

電壓輸入范圍

ADC 輸入范圍為:VREF- ≤ VIN ≤ VREF+。
由VREF-、VREF+ 、VDDA 、VSSA、這四個外部引腳決定。
一般把VSSA 和VREF- 接地,把VREF+ 和VDDA 接3V3,得到ADC 的輸入電壓范圍為:0~3.3V。

如果想讓輸入的電壓范圍變寬,去到可以測試負電壓或者更高的正電壓,我們可以在外部加一個電壓調理電路,把需要轉換的電壓抬升或者降壓到0~3.3V,這樣ADC 就可以測量了。

輸入通道

STM32的ADC 多達18 個通道,其中外部的16 個通道就是框圖中的ADCx_IN0、ADCx_IN1 ? ADCx_IN5。

這16 個通道對應著不同的IO 口,具體是哪一個IO 口可以從手冊查詢到。

其中ADC1/2/3 還有內部通道
ADC1 的通道16 連接到了芯片內部的溫度傳感器,Vrefint 連接到了通道17。
ADC2 的模擬通道16 和17 連接到了內部的VSS。
ADC3 的模擬通道9、14、15、16 和17 連接到了內部的VSS。

STM32F103ZET6 ADC IO 分配 :

ADC1 IO ADC2 IO ADC3 IO
通道0 PA0 通道0 PA0 通道0 PA0
通道1 PA1 通道1 PA1 通道2 PA1
通道2 PA2 通道2 PA2 通道2 PA2
通道3 PA3 通道3 PA3 通道3 PA3
通道4 PA4 通道4 PA4 通道4 PF6
通道5 PA5 通道5 PA5 通道5 PF7
通道6 PA6 通道6 PA6 通道6 PF8
通道7 PA7 通道7 PA7 通道7 PF9
通道8 PB0 通道8 PB0 通道8 PF10
通道9 PB1 通道9 PB1 通道9 連接內部VSS
通道10 PC0 通道10 PC0 通道10 PC0
通道11 PC1 通道11 PC1 通道11 PC1
通道12 PC2 通道12 PC2 通道12 PC2
通道13 PC3 通道13 PC3 通道13 PC3
通道14 PC4 通道14 PC4 通道14 連接內部VSS
通道15 PC5 通道15 PC5 通道15 連接內部VSS
通道16 連接內部溫度傳感器 通道16 連接內部VSS 通道16 連接內部VSS
通道17 連接內部Vrefint 通道17 連接內部VSS 通道17 連接內部VSS

外部的16 個通道在轉換的時候又分為規(guī)則通道注入通道,其中規(guī)則通道最多有16 路,注入通道最多有4 路。

規(guī)則通道
普通通道,大部分時候都用這個。

注入通道
注入,可以理解為插入,插隊的意思。它是一種在規(guī)則通道轉換的時候強行插入要轉換的一種通道
如果在規(guī)則通道轉換過程中,有注入通道插隊,那么就要先轉換完注入通道,等注入通道轉換完成后,再回到規(guī)則通道的轉換流程。

轉換順序

規(guī)則序列

規(guī)則序列寄存器有3 個,分別為SQR3、SQR2、SQR1。

SQR3 控制著規(guī)則序列中的第一個到第六個轉換,對應的位為:SQ1[4:0] ~ SQ6[4:0],第一次轉換的是位4:0 SQ1[4:0],如果通道16 想第一次轉換,那么在SQ1[4:0] 寫16 即可。

SQR2 控制著規(guī)則序列中的第7 到第12 個轉換,對應的位為:SQ7[4:0] ~ SQ12[4:0],如果通道1 想第8 個轉換,則SQ8[4:0] 寫1 即可。

SQR1 控制著規(guī)則序列中的第13 到第16 個轉換,對應位為:SQ13[4:0] ~ SQ16[4:0],如果通道6 想第10 個轉換,則SQ10[4:0] 寫6 即可。

具體使用多少個通道,由SQR1 的位L[3:0] 決定,最多16 個通道。

寄存器 寄存器位 功能 取值
SQR3 SQ1[4:0] 設置第1個轉換的通道 通道1 ~ 16
SQR3 SQ2[4:0] 設置第2個轉換的通道 通道1 ~ 16
SQR3 SQ3[4:0] 設置第3個轉換的通道 通道1 ~ 16
SQR3 SQ4[4:0] 設置第4個轉換的通道 通道1 ~ 16
SQR3 SQ5[4:0] 設置第5個轉換的通道 通道1 ~ 16
SQR3 SQ6[4:0] 設置第6個轉換的通道 通道1 ~ 16
SQR2 SQ7[4:0] 設置第7個轉換的通道 通道1 ~ 16
SQR2 SQ8[4:0] 設置第8個轉換的通道 通道1 ~ 16
SQR2 SQ9[4:0] 設置第9個轉換的通道 通道1 ~ 16
SQR2 SQ10[4:0] 設置第10個轉換的通道 通道1 ~ 16
SQR2 SQ11[4:0] 設置第11個轉換的通道 通道1 ~ 16
SQR2 SQ12[4:0] 設置第12個轉換的通道 通道1 ~ 16
SQR1 SQ13[4:0] 設置第13個轉換的通道 通道1 ~ 16
SQR1 SQ14[4:0] 設置第14個轉換的通道 通道1 ~ 16
SQR1 SQ15[4:0] 設置第15個轉換的通道 通道1 ~ 16
SQR1 SQ16[4:0] 設置第16個轉換的通道 通道1 ~ 16
SQR1 SQL[3:0] 需要轉換多少個通道 通道1 ~ 16

注入序列

注入序列寄存器JSQR 只有一個,最多支持4 個通道,具體多少個由JSQR 的JL[2:0] 決定。

如果JL 的值小于4 的話,則JSQR 跟SQR 決定轉換順序的設置不一樣,第一次轉換的不是JSQR1[4:0],而是JCQRx[4:0] ,x = (4-JL),跟SQR 剛好相反。

如果JL=00(1 個轉換),那么轉換的順序是從JSQR4[4:0] 開始,而不是從JSQR1[4:0] 開始,這個要注意,編程的時候不要搞錯。當JL 等于4 時,跟SQR 一樣。

寄存器 寄存器位 功能 取值
JSQR JSQ1[4:0] 設置第1個轉換的通道 通道 1 ~ 4
JSQR JSQ2[4:0] 設置第2個轉換的通道 通道 1 ~ 4
JSQR JSQ3[4:0] 設置第3個轉換的通道 通道 1 ~ 4
JSQR JSQ4[4:0] 設置第4個轉換的通道 通道 1 ~ 4
JSQR JL[1:0] 需要轉換多少個通道 通道 1 ~ 4

觸發(fā)源

ADC 轉換可以由ADC 控制寄存器2: ADC_CR2 的ADON 這個位來控制,寫1 的時候開始轉換,寫0 的時候停止轉換;

ADC 還支持觸發(fā)轉換,內部定時器觸發(fā)和外部IO 觸發(fā)。
觸發(fā)源有很多,具體選擇哪一種觸發(fā)源,由ADC 控制寄存器2:ADC_CR2 的EXTSEL[2:0] 和JEXTSEL[2:0] 位來控制。
EXTSEL[2:0] 用于選擇規(guī)則通道的觸發(fā)源,JEXTSEL[2:0] 用于選擇注入通道的觸發(fā)源。

選定好觸發(fā)源之后,由ADC 控制寄存器2:ADC_CR2 的EXTTRIG 和JEXTTRIG 這兩位來激活ADC。

其中ADC3 的規(guī)則轉換和注入轉換的觸發(fā)源與ADC1/2的有所不同。

轉換時間

ADC 時鐘

ADC 輸入時鐘ADC_CLK 由PCLK2 經(jīng)過分頻產(chǎn)生,最大是14M,分頻因子由RCC 時鐘配置寄存器RCC_CFGR 的位15:14 ADCPRE[1:0] 設置,可以是2/4/6/8 分頻,注意這里沒有1 分頻。一般我們設置PCLK2=HCLK=72M

采樣時間

ADC 使用若干個ADC_CLK 周期對輸入的電壓進行采樣,采樣的周期數(shù)可通過ADC 采樣時間寄存器ADC_SMPR1 和ADC_SMPR2 中的SMP[2:0] 位設置,ADC_SMPR2 控制的是通道0 ~ 9,ADC_SMPR1 控制的是通道10~17。
每個通道可以分別用不同的時間采樣。其中采樣周期最小是1.5 個,即如果我們要達到最快的采樣,那么應該設置采樣周期為1.5 個周期,這里說的周期就是1/ADC_CLK。

ADC 的轉換時間跟ADC 的輸入時鐘和采樣時間有關,公式為:Tconv = 采樣時間+ 12.5 個周期

當ADCLK = 14MHZ(最高),采樣時間設置為1.5 周期(最快),那么總的轉換時間(最短)Tconv = 1.5 周期+ 12.5 周期= 14 周期= 1us。
一般我們設置PCLK2=72M,經(jīng)過ADC 預分頻器能分頻到最大的時鐘只能是12M,采樣周期設置為1.5 個周期,算出最短的轉換時間為1.17us,這個才是最常用的。

數(shù)據(jù)寄存器

一切準備就緒后,ADC 轉換后的數(shù)據(jù)根據(jù)轉換組的不同,規(guī)則組的數(shù)據(jù)放在ADC_DR 寄存器,注入組的數(shù)據(jù)放在JDRx。

規(guī)則數(shù)據(jù)寄存器
ADC 規(guī)則組數(shù)據(jù)寄存器ADC_DR 只有一個,是一個32 位的寄存器,低16 位在單ADC 時使用,高16 位是在ADC1 中雙模式下保存ADC2 轉換的規(guī)則數(shù)據(jù),雙模式就是ADC1 和ADC2 同時使用。

在單模式下,ADC1/2/3 都不使用高16 位。因為ADC 的精度是12 位,無論ADC_DR 的高16 或者低16 位都放不滿,只能左對齊或者右對齊,具體是以哪一種方式存放,由ADC_CR2 的11 位ALIGN 設置。

規(guī)則通道可以有16 個這么多,可規(guī)則數(shù)據(jù)寄存器只有一個,如果使用多通道轉換,那轉換的數(shù)據(jù)就全部都擠在了DR 里面,前一個時間點轉換的通道數(shù)據(jù),就會被下一個時間點的另外一個通道轉換的數(shù)據(jù)覆蓋掉,所以當通道轉換完成后就應該把數(shù)據(jù)取走,或者開啟DMA 模式,把數(shù)據(jù)傳輸?shù)絻却胬锩?/strong>,不然就會造成數(shù)據(jù)的覆蓋。

對于多通道采集這里提出三個解決辦法:
(1)使用間斷模式,采集一個存儲一個
(2)使用中斷,采集到一個數(shù)據(jù),進入中斷,把這個數(shù)據(jù)保存
(3)使用DMA,直接將采集到的數(shù)據(jù)搬運到內存

注入數(shù)據(jù)寄存器

ADC 注入組最多有4 個通道,剛好注入數(shù)據(jù)寄存器也有4 個,每個通道對應著自己的寄存器,不會跟規(guī)則寄存器那樣產(chǎn)生數(shù)據(jù)覆蓋的問題。ADC_JDRx 是32 位的,低16 位有效,高16 位保留,數(shù)據(jù)同樣分為左對齊和右對齊,具體是以哪一種方式存放,由ADC_CR2 的11 位ALIGN 設置。

中斷

轉換結束中斷

數(shù)據(jù)轉換結束后,可以產(chǎn)生中斷,中斷分為三種:規(guī)則通道轉換結束中斷,注入轉換通道轉換結束中斷,模擬看門狗中斷。

其中轉換結束中斷很好理解,跟我們平時接觸的中斷一樣,有相應的中斷標志位和中斷使能位,我們還可以根據(jù)中斷類型寫相應配套的中斷服務程序。

模擬看門狗中斷

當被ADC 轉換的模擬電壓低于低閾值或者高于高閾值時,就會產(chǎn)生中斷,前提是我們開啟了模擬看門狗中斷,其中低閾值和高閾值由ADC_LTR 和ADC_HTR 設置。

例如我們設置高閾值是2.5V,那么模擬電壓超過2.5V 的時候,就會產(chǎn)生模擬看門狗中斷,反之低閾值也一樣。

DMA 請求

規(guī)則和注入通道轉換結束后,除了產(chǎn)生中斷外,還可以產(chǎn)生DMA 請求,把轉換好的數(shù)據(jù)直接存儲在內存里面。

要注意的是只有ADC1 和ADC3 可以產(chǎn)生DMA 請求。

一般我們在使用ADC 的時候都會開啟DMA 傳輸。

電壓轉換

模擬電壓經(jīng)過ADC 轉換后,是一個12 位的數(shù)字值,如果通過串口以16 進制打印出來的話,可讀性比較差,那么有時候我們就需要把數(shù)字電壓轉換成模擬電壓,也可以跟實際的模擬電壓(用萬用表測)對比,看看轉換是否準確。

我們一般在設計原理圖的時候會把ADC 的輸入電壓范圍設定在:0~3.3v,因為ADC 是12 位的,那么12 位滿量程對應的就是3.3V,12 位滿量程對應的數(shù)字值是:2^12。數(shù)值0 對應的就是0V。

如果轉換后的數(shù)值為X ,X 對應的模擬電壓為Y,那么會有這么一個等式成立: 2^12 / 3.3 = X/ Y,=> Y = (3.3 * X ) / 2^12。

三、STM32Cube MX配置

基礎STM32Cube MX的配置可以參考這篇博客:STM32 CubeMx教程 – 基礎知識及配置使用教程

配置RCC,選擇使用外部晶振模式

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

配置SYS,debug配置為Serial Wire

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

配置一個串口,使用異步通信模式

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

ADC界面:

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

IN0~IN15: 16路12位ADC采樣通道,外部模擬量信號輸入

Temperature Sensor Channel: MCU內置溫度傳感器采樣通道,用來測量器件周圍的溫度。在MCU內部與ADC1_IN16通道相連

Vrefint Channel: 內部參考電壓檢測通道,ADC 的參考電壓都是通過 Vref+ 引腳提供的并作為ADC轉換器的基準電壓,當Vref+直接取自VDD電壓時,易受VDD波動而影響,因此可以該通道對參考電壓進行校準,以提升ADC計算精度。在MCU內部與ADC1_IN17通道相連

EXTI Conversion Trigger: 外部觸發(fā)轉換。
ADC轉換可由外部事件觸發(fā),EXTSEL[2:0]和JEXTSEL[2:0]控制位允許應用程序選擇8個可能的事件中的某一個,觸發(fā)規(guī)則通道組合注入通道組的采樣。這里若選擇Disable,則可以在6個來自片上定時器的內部信號中選擇一個作為觸發(fā)源;
若選擇Injected Trigger/Regular Trigger/Injected and Regular Trigger,表示由外部引腳信號觸發(fā)相應的通道組。

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

ADCs_Common_Settings:(ADC模式設置)

Mode:Independent mode
獨立模式。此模式中,雙ADC同步不工作,ADC1和ADC2相互獨立工作。
如果不需要ADC同步或者只是用了一個ADC的時候,應該設成獨立模式,多個ADC同時使用時會有其他模式,如雙重ADC同步模式,兩個ADC同時采集一個或多個通道,可以提高采樣率。對應ADC控制寄存器1(ADC_CR1)中的DUALMOD[3:0]位。

ADC_Settings:(ADC設置)

Data Alignment:(數(shù)據(jù)對齊方式)
數(shù)據(jù)左對齊/右對齊,一般選擇使用右對齊。

Scan Conversion Mode:(掃描模式)
掃描模式使能。對應ADC控制寄存器1(ADC_CR1)中的SCAN位。
如果只是用了一個通道的話,設置為DISABLE;
如果使用了多個通道的話,可以選擇設置ENABLE或者DISABLE;(后面結合具體場景介紹)

Continuous Conversion Mode:(連續(xù)轉換模式)
數(shù)據(jù)的連續(xù)轉換,對應ADC控制寄存器2(ADC_CR2)中的CONT位。
設置為ENABLE,即使能連續(xù)轉換;設置為DISABLE,則是單次轉換。
兩者的區(qū)別在于連續(xù)轉換直到所有的數(shù)據(jù)轉換完成后才停止轉換,而單次轉換則只轉換一次數(shù)據(jù)就停止,要再次觸發(fā)轉換才可以進行轉換

Discontinuous Conversion Mode:(間斷模式)
間斷模式,對應ADC控制寄存器1(ADC_CR1)中的DISCEN位。
如果單通道不需要采用間斷,多通道具體分析,后面示例中具體介紹

ADC_Regular_ConversionMode:規(guī)則通道組采樣設置

Enable Regular Conversions:(常規(guī)轉換模式)
使能規(guī)則通道組轉換。

Number of Conversion:(轉換通道數(shù)量)
規(guī)則通道組序列長度為3,即包含3個采樣通道。

External Trigger Conversion Source:(外部觸發(fā)轉換源)
選擇外部觸發(fā)源,
Regular Conversion launched by software 規(guī)則的軟件觸發(fā) 調用函數(shù)觸發(fā)
Timer X Capture Compare X event 外部引腳觸發(fā),
Timer X Trigger Out event 定時器通道輸出觸發(fā)
stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

Rank:ADC轉換通道順序
當使用多通道采集的時候,可以在這里設置每個通道采集的先后順序

ADC_Injected_ConversionMode:注入通道設置
參數(shù)和上面的規(guī)則通道一樣;
需要注意的是,注入通道的功能和規(guī)則通道的一樣,但是注入通道的優(yōu)先級要比規(guī)則通道的高;

WatchDog: 模擬看門狗中斷

四、應用示例

涉及到的HAL庫函數(shù)


開啟ADC 3種模式 ( 輪詢模式 中斷模式 DMA模式 )

? HAL_ADC_Start(&hadcx); ? ? ? //輪詢模式開啟ADC
? HAL_ADC_Start_IT(&hadcx); ? ? ? //中斷輪詢模式開啟ADC
? HAL_ADC_Start_DMA(&hadcx); ? ? ? //DMA模式開啟ADC

關閉ADC 3種模式 ( 輪詢模式 中斷模式 DMA模式 )

? HAL_ADC_Stop()
? HAL_ADC_Stop_IT()
? HAL_ADC_Stop_DMA()

ADC校準函數(shù) :

? HAL_ADCEx_Calibration_Start(&hadcx); ? ? ?//F4系列不支持

讀取ADC轉換值

? HAL_ADC_GetValue()

等待轉換結束函數(shù)

? HAL_ADC_PollForConversion(&hadc1, 50);

第一個參數(shù)為那個ADC,第二個參數(shù)為最大等待時間

ADC中斷回調函數(shù)
? HAL_ADC_ConvCpltCallback()

轉換完成后回調,DMA模式下DMA傳輸完成后和中斷中調用

規(guī)則通道及看門狗配置

? HAL_ADC_ConfigChannel() 配置規(guī)則組通道
? HAL_ADC_AnalogWDGConfig(

結合ADC的不同傳輸辦法;
這里給出六個例子

(1)單通道數(shù)據(jù)采集
(2)多通道間斷模式輪詢采集
(3)多通道中斷采集
(4)多通道定時器中斷采集
(5)多通道DMA采集
(6)多通道定時器MDA采集

如果使用串口打印數(shù)據(jù),要記得串口重定向,參考這兩篇博客:
STM32 HAL庫 STM32CubeMx – 串口的使用(USART/UART)
STM32 HAL庫 使用printf函數(shù) Use MicroLIB配置

(1)單通道數(shù)據(jù)采集

在STM32 Cube MX里面配置一個通道IN1;
ADC采集模式設置為獨立模式;
數(shù)據(jù)設置為右對齊模式;
由于只有單通道,數(shù)據(jù)都是一個通道的,設置為連續(xù)轉換模式;
由于只有一個通道,下面的規(guī)則通道設置,rank順序設置可以不用管;

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
	/* 單通道 數(shù)據(jù)定義 */
	uint16_t ADC_value;		//ADC采集到的數(shù)據(jù)	
	float  volt_value;	//電壓值
	
/* USER CODE END PD */
/* USER CODE BEGIN 1 */

/* 自定義的數(shù)據(jù)采集函數(shù),需要在.h 函數(shù)里面聲明 */
/* 自定義了一個數(shù)據(jù)采集函數(shù),我放到了adc.c 里面,放到main.c里面也行*/
uint16_t ADC_X_Get()
	{
		HAL_ADC_Start(&hadc1);     //啟動ADC轉換
		HAL_ADC_PollForConversion(&hadc1, 50);   //等待轉換完成,50為最大等待時間,單位為ms
 
		if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
		{
			return(HAL_ADC_GetValue(&hadc1));	//返回ADC的值
		}
		return 0;
	}

/* USER CODE END 1 */
  while (1)
  {
		
		/* 單通道數(shù)據(jù)采集 + 連續(xù)轉換模式 */
		/* 在主函數(shù)中采集數(shù)據(jù),并且輸出數(shù)據(jù) */		
		ADC_value = ADC_X_Get();
		volt_value = ADC_value*3.3f/4096; //內部電壓轉換公式
		
		printf("ADC read value : %d \r\n",ADC_value);
		printf("change voltage value : %.4f \r\n",volt_value);
		HAL_Delay(1000);
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

(2)多通道間斷模式輪詢采集

STM32Cube MX里面配置了五個通道;
設置為獨立模式;
在規(guī)則通道設置里面,設置5個通道;
可以在Rank里面設置每個通道采集的順序;
由于是多通道數(shù)據(jù)采集,必須使能掃描模式

如果不使用中斷 DMA,要想采集到多通道的數(shù)據(jù),可以采用間斷模式
所以使能間斷模式;
stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件
stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */	
	/* 多通道 間斷 輪詢模式 數(shù)據(jù)定義 */
	#define ADC_value_max 5 	//五通道數(shù)據(jù)
	uint16_t ADC_value[ADC_value_max] = {0};		//ADC采集數(shù)值
	float  volt_value;		//電壓值
	float  tem_value;		//溫度值
/* USER CODE END PD */
/* USER CODE BEGIN 1 */

/* 自定義的數(shù)據(jù)采集函數(shù),需要在.h 函數(shù)里面聲明 */
/* 自定義了一個數(shù)據(jù)采集函數(shù),我放到了adc.c 里面,放到main.c里面也行*/
uint16_t ADC_X_Get()
	{
		HAL_ADC_Start(&hadc1);     //啟動ADC轉換
		HAL_ADC_PollForConversion(&hadc1, 50);   //等待轉換完成,50為最大等待時間,單位為ms
 
		if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
		{
			return(HAL_ADC_GetValue(&hadc1));	//返回ADC的值
		}
		return 0;
	}

/* USER CODE END 1 */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	HAL_ADCEx_Calibration_Start(&hadc1);    //ADC校準
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {		
		/* 多通道數(shù)據(jù)采集 + 掃描模式 + 間斷模式 */
		for(uint8_t i=0;i<5;i++)
		{
		ADC_value[i] = ADC_X_Get();			//獲取ADC采集到的值
		}
		volt_value = ADC_value[3]*3.3f/4096; //內部電壓轉化公式
		tem_value = (1.43 - ADC_value[4]*3.3f/4096) / 0.0043 + 25;		//內部溫度轉換公式
		
		printf("ADC value 0 : %d \r\n",ADC_value[0]);
		printf("volt  : %.4f \r\n",volt_value);
		printf("tem : %.2f \r\n",tem_value);
		HAL_Delay(1000);
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

(3)多通道中斷采集

STM32Cube MX里面配置了五個通道;
設置為獨立模式;
在規(guī)則通道設置里面,設置5個通道;
可以在Rank里面設置每個通道采集的順序;
由于是多通道數(shù)據(jù)采集,必須使能掃描模式;

為了采集到多通道的數(shù)據(jù),這里使用的辦法是使用中斷
配置使能連續(xù)轉換模式,配置打開ADC中斷;
這里觸發(fā)中斷的方式是軟件觸發(fā),也就是ADC每轉化一次觸發(fā)一次中斷;(這樣會很浪費資源)

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件
stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件
打開中斷
stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
	/* 多通道 中斷 數(shù)據(jù)定義 */
	/* 用到全局變量,所以在main.h里面聲明 */
	uint16_t ADC_value[ADC_value_max] = {0};		//ADC采集數(shù)值
	uint8_t ADC_value_flag = 0;		//ADC標志位
	float  volt_value;	//電壓值
	float  tem_value;		//溫度值
/* USER CODE END PD */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
#define ADC_value_max 5 //3組ADC,每組最多存儲5個值

extern uint16_t ADC_value[ADC_value_max];		//ADC采集數(shù)值
extern uint8_t ADC_value_flag;		//ADC標志位
/* USER CODE END ET */
/* USER CODE BEGIN 1 */

/* ADC轉換完成之后,觸發(fā)ADC中斷 */
/* 為了方便歸類,這里我把ADC處理函數(shù)放在了adc.c里面 */
/* 如果要更改一些數(shù)值,需要將變量設置為全局變量 */	
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{    
   ADC_value[ADC_value_flag++]=HAL_ADC_GetValue(hadc);		 //獲取值并存儲
 
   if(ADC_value_flag == ADC_value_max) //最大值的下一位
    {
         ADC_value_flag=0;//清零下標
    } 
}

/* USER CODE END 1 */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	HAL_ADCEx_Calibration_Start(&hadc1);    //ADC校準
	
	HAL_ADC_Start_IT(&hadc1);		//開啟ADC中斷
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		/* 多通道采集 + 掃描模式 + 連續(xù)轉換模式 + 中斷 */
		volt_value = ADC_value[3]*3.3f/4096;
		tem_value = (1.43 - ADC_value[4]*3.3f/4096) / 0.0043 + 25;
		
		printf("tem : %.2f \r\n",tem_value);
		printf("demo1 : %d \r\n",ADC_value[4]);
		printf("volt  : %.4f \r\n",volt_value);
		HAL_Delay(1000);
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

(4)多通道定時器中斷采集

由于直接使用中斷,每采集一次數(shù)據(jù),就會進入中斷一次,比較浪費資源,所以這里介紹,定時器觸發(fā)中斷采集數(shù)據(jù);

STM32Cube MX里面配置了五個通道;
設置為獨立模式;
在規(guī)則通道設置里面,設置5個通道;
可以在Rank里面設置每個通道采集的順序;
由于是多通道數(shù)據(jù)采集,必須使能掃描模式

為了采集到多通道的數(shù)據(jù),這里使用的辦法是使用中斷
配置使能連續(xù)轉換模式,配置打開ADC中斷;
這里觸發(fā)中斷的方式是定時器觸發(fā),也就是定時器沒溢出一次觸發(fā)一次中斷;

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

配置一個定時器,使用內部時鐘,自動重裝載值,配置為觸發(fā)事件更新

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

設置為定時器3 外部事件觸發(fā)

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件
打開定時器的中斷

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
	/* 多通道 中斷 數(shù)據(jù)定義 */
	/* 用到全局變量,所以在main.h里面聲明 */
	uint16_t ADC_value[ADC_value_max] = {0};		//ADC采集數(shù)值
	uint8_t ADC_value_flag = 0;		//ADC標志位
	float  volt_value;	//電壓值
	float  tem_value;		//溫度值
/* USER CODE END PD */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
#define ADC_value_max 5 //3組ADC,每組最多存儲5個值

extern uint16_t ADC_value[ADC_value_max];		//ADC采集數(shù)值
extern uint8_t ADC_value_flag;		//ADC標志位
/* USER CODE END ET */
/* USER CODE BEGIN 1 */

/* 定時器回調函數(shù),定時器溢出以后觸發(fā)回調函數(shù) */
/* 在定時器里面開啟ADC中斷轉換 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    HAL_ADC_Start_IT(&hadc1); //定時器中斷里面開啟ADC中斷轉換,1s開啟一次采集    
}


/* ADC轉換完成回調函數(shù),在回調函數(shù)里面,關閉中斷,保存數(shù)據(jù) */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    HAL_ADC_Stop_IT(&hadc1);			//關閉ADC中斷
    HAL_TIM_Base_Stop_IT(&htim3);	//關閉定時器
    ADC_value[ADC_value_flag++]=HAL_ADC_GetValue(hadc);		 //獲取值并存儲
 
   if(ADC_value_flag == ADC_value_max) //最大值的下一位
    {
         ADC_value_flag=0;//清零下標
    } 
    HAL_TIM_Base_Start_IT(&htim3); //開啟定時器
}


/* USER CODE END 1 */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
	HAL_ADCEx_Calibration_Start(&hadc1);    //ADC校準
	
	HAL_TIM_Base_Start_IT(&htim3);	//開啟定時器中斷
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		
		/* 多通道采集 + 掃描模式 + 連續(xù)轉換模式 + 中斷 */
		volt_value = ADC_value[3]*3.3f/4096;
		tem_value = (1.43 - ADC_value[4]*3.3f/4096) / 0.0043 + 25;
		
		printf("tem : %.2f \r\n",tem_value);
		printf("demo1 : %d \r\n",ADC_value[4]);
		printf("volt  : %.4f \r\n",volt_value);
		HAL_Delay(1000);
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

(5)多通道DMA采集

STM32Cube MX里面配置了五個通道;
設置為獨立模式;
在規(guī)則通道設置里面,設置5個通道;
可以在Rank里面設置每個通道采集的順序;
由于是多通道數(shù)據(jù)采集,必須使能掃描模式

為了采集到多通道的數(shù)據(jù),這里使用的辦法是DMA

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

配置DMA ,設置為循環(huán)模式

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
	/* DMA 數(shù)據(jù)定義 */
	uint16_t ADC_value[ADC_value_max] = {0};		//ADC采集數(shù)值
	float  volt_value;	//電壓值
	float  tem_value;		//溫度值
/* USER CODE END PD */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
	HAL_ADCEx_Calibration_Start(&hadc1);    //ADC校準
	HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_value,sizeof(ADC_value) / sizeof(ADC_value[0]));  //開啟DMA

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		/* 多通道采集 + 掃描模式 + DMA */
		HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_value,sizeof(ADC_value) / sizeof(ADC_value[0]));

		volt_value = ADC_value[3]*3.3f/4096;
		tem_value = (1.43 - ADC_value[4]*3.3f/4096) / 0.0043 + 25;
		
		printf("tem : %.2f \r\n",tem_value);
		printf("demo1 : %d \r\n",ADC_value[4]);
		printf("volt  : %.4f \r\n",volt_value);
		HAL_Delay(1000);	
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

(6)多通道定時器MDA采集

STM32Cube MX里面配置了五個通道;
設置為獨立模式;
在規(guī)則通道設置里面,設置5個通道;
可以在Rank里面設置每個通道采集的順序;
由于是多通道數(shù)據(jù)采集,必須使能掃描模式;

為了采集到多通道的數(shù)據(jù),這里使用的辦法是DMA
為了減少資源占用,選擇又定時器驅動DMA

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

配置一個定時器,使用內部時鐘,自動重裝載值,配置為觸發(fā)事件更新

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

打開定時器的中斷

stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件
配置ADC參數(shù),配置為定時器3觸發(fā)
stm32cube 定時器觸發(fā)adc,stm32,單片機,嵌入式硬件

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
	/* DMA 數(shù)據(jù)定義 */
	uint16_t ADC_value[ADC_value_max] = {0};		//ADC采集數(shù)值
	float  volt_value;	//電壓值
	float  tem_value;		//溫度值
/* USER CODE END PD */

/* 定時器 DMA */
/* 定時器回調函數(shù),定時器溢出以后觸發(fā)回調函數(shù) */
/* 在定時器里面開啟ADC DMA采集 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_value,sizeof(ADC_value) / sizeof(ADC_value[0]));
	//定時器中斷里面開啟ADC DMA 轉換,1s開啟一次采集    
}
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
	HAL_ADCEx_Calibration_Start(&hadc1);    //ADC校準
	HAL_TIM_Base_Start_IT(&htim3);	//開啟定時器
	HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_value,sizeof(ADC_value) / sizeof(ADC_value[0]));  //開啟DMA

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		/* 多通道采集 + 掃描模式 + DMA + 定時器*/
		
		volt_value = ADC_value[3]*3.3f/4096;
		tem_value = (1.43 - ADC_value[4]*3.3f/4096) / 0.0043 + 25;
		
		printf("tem : %.2f \r\n",tem_value);
		printf("demo1 : %d \r\n",ADC_value[4]);
		printf("volt  : %.4f \r\n",volt_value);
		HAL_Delay(1000);	
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

附錄

本文涉及到的程序:STM32 HAL庫 ADC數(shù)據(jù)采集(設置的0積分,無法下載,留言發(fā)給你)文章來源地址http://www.zghlxwxcb.cn/news/detail-617523.html

到了這里,關于STM32 HAL庫 STM32CubeMX -- ADC的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【HAL庫】STM32CubeMX開發(fā)----非阻塞延時實驗----SysTick(滴答定時器)中斷

    【HAL庫】STM32CubeMX開發(fā)----非阻塞延時實驗----SysTick(滴答定時器)中斷

    STM32CubeMX 下載和安裝 詳細教程 【HAL庫】STM32CubeMX開發(fā)----STM32F103/F207/F407----目錄 HAL庫 有自帶的 ms級 延時函數(shù): HAL_Delay(); 缺點: 這是 阻塞延時 方式,就是延時期間,什么都不能干,這樣很浪費資源。 這篇文章主要介紹,利用 SysTick(滴答定時器)中斷 實現(xiàn) 非阻塞延時 的實驗

    2024年02月16日
    瀏覽(96)
  • 基于CubeMX(hal庫)stm32中hrtim高分辨率定時器的基本使用(自存)

    基于CubeMX(hal庫)stm32中hrtim高分辨率定時器的基本使用(自存)

    1、選通道 單通道輸出or雙通道輸出 2、Timer A~F配置 (Master Timer不用管) 比較值Compare 個人感覺跟CCR差不多的意思, 注意不要大于上面的Period就行 設置上升沿和下降沿時間: 若想讓上設Compare=CCR 如圖設置 即可 即在 計數(shù)到Compare1時拉低,計數(shù)溢出時拉高 所以上圖輸出頻率10kHz占

    2024年02月04日
    瀏覽(25)
  • 2.基于正點原子STM32F103的定時器中斷實驗(HAL庫實現(xiàn))(cubeMX)

    2.基于正點原子STM32F103的定時器中斷實驗(HAL庫實現(xiàn))(cubeMX)

    ? 基本上每一款MCU都會配備定時器這個外設,STM32 的每個通用定時器都是完全獨立的,沒有互相共享的任何資源。 同樣,STM32F1系列的定時器功能也很強大,包括: TIM1和TIM8兩個高級定時器; TIM2~TIM5是個通用寄存器; TIM7,TIM8,兩個基本定時器。 由于本次實驗適用于新手入門

    2023年04月26日
    瀏覽(27)
  • STM32 HAL庫 CubeMX配置 定時器學習 F103C8T6

    STM32 HAL庫 CubeMX配置 定時器學習 F103C8T6

    開發(fā)板: STM32F103C8T6最小系統(tǒng)板 編譯環(huán)境: Keil5 MDK 輔助軟件: STM32 CubeMX 課程教學: 基于正點原子HAL庫學習教程 其余配件: 江科大STM32配件包?和 示波器一臺 備注: ?因為這塊開發(fā)板沒有基本定時器,所以本文也 沒有基本定時器的內容 ????????????本文1.3和2.1部分的

    2024年04月26日
    瀏覽(21)
  • STM32 HAL庫 通用定時器介紹及相關應用例程 定時器中斷 輸出PWM (點亮LED呼吸燈、輸出PWM、輸入捕獲) CubeMX

    STM32 HAL庫 通用定時器介紹及相關應用例程 定時器中斷 輸出PWM (點亮LED呼吸燈、輸出PWM、輸入捕獲) CubeMX

    (部分圖引自于ATK) 前情提要(基本定時器) 點此進入 通用定時器類別 通用定時器和基本定時器相比大致的工作方式是相似的,不過通用定時器比基本定時器多了一些很好用的功能,比如: 外部輸入捕獲 輸出比較 輸出PWM 時鐘源 CubeMX為我們提供了配置時鐘的非常方便的工

    2024年04月15日
    瀏覽(39)
  • 【STM32筆記】STM32的定時器開發(fā)基礎(二)(基于STM32CubeMX實現(xiàn)定時器中斷)

    【STM32筆記】STM32的定時器開發(fā)基礎(二)(基于STM32CubeMX實現(xiàn)定時器中斷)

    ? 傳統(tǒng)STM32外部中斷 的設計步驟: ?(1)將GPIO初始化為輸入端口。 ?(2)配置相關I/O引腳與中斷線的映射關系。 ?(3)設置該I/O引腳對印的中斷觸發(fā)條件。 ?(4)配置NVIC,并使能中斷。 ?(5)編寫中斷服務函數(shù)。 ? 基于STM32CubeMX的外部中斷 設計步驟 ?(1)在STM3

    2024年02月20日
    瀏覽(98)
  • STM32CubeMX——定時器配置

    STM32CubeMX——定時器配置

    本文將會以STM32F103C8T6為例配置定時器2定時5 ms SMT32F1系列共有8個定時器: 基本定時器(TIM6、TIM7) 通用定時器(TIM2、TIM3、TIM4、TIM5) 高級定時器(TIM1、TIM8) 16位向上、向下、向上/下自動裝載計數(shù)器 16位可編程(可以實時修改)預分頻器,計數(shù)器時鐘頻率的分頻系數(shù)為 1~6553

    2023年04月10日
    瀏覽(22)
  • 最詳細STM32,cubeMX 定時器

    最詳細STM32,cubeMX 定時器

    這篇文章將詳細介紹 STM32,cubeMX 定時器的配置和使用。 實驗開發(fā)板:STM32F103C8T6。 所需軟件:keil5 , cubeMX 。 實驗目的:了解 cubeMX 定時器 的配置和使用。 實驗:使用定時器控制 led 閃爍。 STM32的定時器是用于時間測量和事件生成的復雜工具??梢允褂脙炔炕蛲獠繒r鐘源。時

    2024年02月07日
    瀏覽(29)
  • STM32CubeMX教程5 TIM 定時器概述及基本定時器

    開發(fā)板(STM32F407G-DISC1) STM32CubeMX軟件(Version 6.10.0) keil μVision5 IDE(MDK-Arm) ST-LINK/V2驅動 邏輯分析儀nanoDLA 使用STM32CubeMX軟件配置STM32F407開發(fā)板 使用基本定時器TIM6實現(xiàn)每500ms控制綠燈狀態(tài)變化一次,基本定時器TIM7實現(xiàn)每1s控制紅燈狀態(tài)變化一次 STM32F407擁有2個基礎定時器、

    2024年02月03日
    瀏覽(27)
  • STM32CubeMX系列06——定時器(定時、PWM、輸入捕獲)

    STM32CubeMX系列06——定時器(定時、PWM、輸入捕獲)

    ==== 文章匯總(有代碼匯總) ==== 正點原子Mini板,主控 STM32F103RCT6. 定時器簡介 這里主要討論通用定時器(系統(tǒng)嘀嗒定時器、看門狗定時器、RTC定時器不考慮在內) 對于STM32F103RCT6 單片機: 2個基本定時器。分別是 TIM6 、 TIM7 。只能16位向上計數(shù)、沒有IO口,沒有捕獲和比較通

    2024年02月01日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包