久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標(biāo)題:
STM8L的ADC之測量外部電壓(使用了DMA)
[打印本頁]
作者:
51hei小林
時間:
2016-10-9 23:58
標(biāo)題:
STM8L的ADC之測量外部電壓(使用了DMA)
本帖最后由 51hei小林 于 2016-10-9 23:59 編輯
之前介紹ADC時,是用ADC測量內(nèi)部1.225V的參考電壓,通過這個參考電壓的轉(zhuǎn)化值反推參考電壓的實際值.這里要注意,我說的內(nèi)部參考電壓和參考電壓是兩個不同的概念,內(nèi)部參考電壓就是內(nèi)部的一個1.225V基準(zhǔn)電壓,這個電壓比較準(zhǔn)確,不會受外接干擾,其值也不會改變,一直是1.225V.在STM8L里,這個電壓作為一個獨立的通道,
可以連接到ADC中,供ADC采樣,校準(zhǔn)自己的參考電壓
,
也可以連接到STM8L的內(nèi)部比較器的輸入端作為一個基準(zhǔn)電壓
,
還可以通過引腳輸出這個電壓.
參考電壓,是Vref+和Vref-引腳之間的電壓,這個電壓是外部的,會隨著外部電壓的變化而變化,在ADC采樣時,這個電壓是采樣時的參考電壓. 上次的例程根據(jù)比例關(guān)系:
(參考電壓/4096)
=
(內(nèi)部參考電壓/內(nèi)部參考電壓轉(zhuǎn)換值)
已經(jīng)求出了參考電壓的值為2.99V,好吧上次測的其實是2.98V,今天用萬用表量了下,是2.99V.為了這次程序的采集數(shù)據(jù)的準(zhǔn)確,還是用2.99V.
本例程和上次的ADC測量內(nèi)部參考電壓例程,并沒有太大卻別,只是增加了DMA部分.原以為,采樣內(nèi)部通道和外部通道會有很大區(qū)別,實際上,只要選擇一下采樣的外部通道,同時關(guān)閉對應(yīng)的施密特觸發(fā)器,其余程序和上次一樣就可以了.也不需要去設(shè)置引腳的輸入輸出狀態(tài),保持默認(rèn)就行.
使用DMA將ADC
轉(zhuǎn)換后的數(shù)據(jù)傳輸?shù)揭粋數(shù)組中,本例程采樣9次數(shù)據(jù),傳輸完9次數(shù)據(jù)后會產(chǎn)生一個傳輸完成中斷,在中斷中求9次的和,計算平均值,同時計算采樣的電壓.
DMA的四個通道都可以作為ADC傳輸數(shù)據(jù)通道,我們需要使用
SYSCFG_RMPCR1
這個寄存器來設(shè)置具體使用的通道.本例程使用DMA的通道一來傳輸數(shù)據(jù).
在本例程中,仍然使用IAR強大的查看變量功能,進(jìn)行數(shù)據(jù)的顯示,沒有使用板子上的LCD液晶屏,主要原因是為了程序簡單,其實是因為我比較懶.本來對數(shù)據(jù)的處理應(yīng)該進(jìn)行濾波處理的,我也僅僅簡單的算了下9次采樣的平均值,起不到平滑數(shù)據(jù)的作用,ADC采樣的數(shù)據(jù)確實每次都不一樣,軟件濾波很重要.
在IAR查看變量,如果變量不是全局變量,在Live Watch窗口或Watch窗口中是看不到數(shù)據(jù)的,所以只好把這個變量聲明為局部靜態(tài)變量,同樣可以顯示出數(shù)值.
下圖是實際的硬件連接圖,用來一個電位器,三個腳分別連接到板子的VDD,GND,PD5腳,具體連接是:電位器兩邊的腳接VDD,GND,中間接PD5.
/*硬件連接*/
// PD5(ADC1_IN9) <----
/****************************************************************************************
*開發(fā)環(huán)境:IAR for stm8 v1.40.1
*硬件平臺:STM8L-DISCOVERY
*功能說明:測量ADC通道9的外部電壓,通道9對應(yīng)的引腳為PD5,在此引腳接了一個電位器,用于輸出一個
* 可變的電壓,提供給ADC測量
*作 者:茗風(fēng)
****************************************************************************************/
#include"iostm8l152c6.h"
#include"stdbool.h"
#include"stdint.h"
#define ADC_DRH_ADRESS 0x5344
uint16_t ui16RX_buffer[9]={0};
/******************************************************************************************************
* 名 稱:void delay_10ms(uint8_t x_ms)
* 功 能:延時10ms
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 范 例:無
******************************************************************************************************/
void delay_100ms(void)
{
uint8_t i,j;
for(i=0;i<255;i++)//2*255個指令周期
for(j=0;j<255;j++);//2*255個指令周期
//delay_10ms共消耗 x_ms*2*255+2*x_ms個指令周期
//255*2*255+2*255=130610us=130ms
//此延時函數(shù),延時時間為130ms
//16M/8/2=1M 一個指令周期為1us
}
/******************************************************************************************************
* 名 稱:void GPIO_Init(void)
* 功 能:初始化PC7為高速推挽輸出
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 范 例:無
******************************************************************************************************/
void GPIO_Config(void)
{
PC_CR1_C17 =1;//推挽輸出
PC_CR2_C27 =1;//高速輸出
PC_DDR_DDR7 =1;//PC7輸出
PC_ODR_ODR7 =0;//輸出低電平
}
/******************************************************************************************************
* 名 稱:void ADC_Init(void)
* 功 能:初始化ADC
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:ADC1的測量通道為ADC1_IN9,單次轉(zhuǎn)換模式
* 范 例:無
******************************************************************************************************/
void ADC_Init(void)
{
CLK_PCKENR2_PCKEN20=1; //國際慣例,開啟ADC1外設(shè)時鐘
ADC1_CR1_ADON=1; //wakes up the ADC from Power down mode.
ADC1_CR2_PRESC=1;//Select a sample time of 10 μs
// 0: f(ADC_CLK) = CK
// 1: f(ADC_CLK) = CK/2 //系統(tǒng)時鐘此時為默認(rèn)的16M/8=2M,這里分頻后,fadc=2M/2=1M
ADC1_SQR1_DMAOFF=0; //使能DMA
ADC1_CR3_SMTP2=0x06;//采樣時間為24 ADC clock cycles,也就是24*1us=24us
//000: 4 ADC clock cycles
//001: 9 ADC clock cycles
//010: 16 ADC clock cycles
//011: 24 ADC clock cycles
//100: 48 ADC clock cycles
//101: 96 ADC clock cycles
//110: 192 ADC clock cycles
//111: 384 ADC clock cycles
ADC1_SQR3_CHSEL_S9=1; //選擇通道9
ADC1_TRIGR3_TRIG9=1; //關(guān)閉通道9的施密特觸發(fā)器
// ADC1_CR1_EOCIE=1;
}
/******************************************************************************************************
* 名 稱:void DMA_Config(void)
* 功 能:啟用DMA
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 范 例:無
******************************************************************************************************/
void DMA_Config(void)
{
//------打開DAM時鐘------
CLK_PCKENR2_PCKEN24=1;
//----設(shè)置ADC的DMA通道----
SYSCFG_RMPCR1_ADC1DMA_REMAP=1;
/* 00: ADC1 DMA request/acknowledge mapped on DMA1 channel 0
01: ADC1 DMA request/acknowledge mapped on DMA1 channel 1
10: ADC1 DMA request/acknowledge mapped on DMA1 channel 2
11: ADC1 DMA request/acknowledge mapped on DMA1 channel 3 */
//------設(shè)置傳送的字節(jié)數(shù),------
DMA1_C1NDTR=9;
//------設(shè)置通道優(yōu)先級------
DMA1_C1SPR_PL0=0;DMA1_C1SPR_PL1=1;
//------設(shè)置傳送方向------
DMA1_C1CR_DIR=0;
/* 0: Transfer from the peripheral to the memory.
1: Transfer from the memory to the peripheral.*/
//------設(shè)置模式------
DMA1_C1CR_CIRC=1;
/* Auto-reload mode
0: Circular mode disabled.
1: Circular mode enabled. */
//------設(shè)置增還是減地址------
DMA1_C1CR_MINCDEC=1;
/* 0: Decrement mode.
1: Increment mode.*/
//------設(shè)置傳送數(shù)據(jù)位數(shù)------
DMA1_C1SPR_TSIZE=1;
/* 0: 8-bit mode
1: 16-bit mode */
// DMA1_C3CR_HTIE=1;
DMA1_C1CR_TCIE=1;//使能DMA傳輸完一組數(shù)據(jù)中斷
//------設(shè)置DMA通道1外設(shè)地址------
DMA1_C1PARH=(uint8_t)((uint16_t)ADC_DRH_ADRESS >> (uint8_t)8);
DMA1_C1PARL=(uint8_t)ADC_DRH_ADRESS;
//------設(shè)置DMA通道1內(nèi)存地址------
DMA1_C1M0ARH=(uint8_t)((uint16_t)&ui16RX_buffer >> (uint8_t)8);
DMA1_C1M0ARL=(uint8_t)&ui16RX_buffer;
DMA1_C1CR_EN=1;
DMA1_GCSR_GEN=1;
}
void main(void)
{
GPIO_Config();
ADC_Init();
DMA_Config();
asm("rim"); //enable interrupts
while(1)
{
delay_100ms();
ADC1_CR1_START=1;
}
}
/******************************************************************************************************
* 名 稱: DMA中斷
* 功 能: DMA事件處理函數(shù)
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 范 例:無
******************************************************************************************************/
#pragma vector=DMA1_CH1_TC_vector
__interrupt void DMA1_CH1_TC_ISR(void)
{
static uint16_t tmp=0,voltage=0;//static是為了便于使用調(diào)試窗口查看變量值
uint8_t i=0;
tmp=0;
voltage=0;
if(DMA1_C1SPR_TCIF==1)
{
PC_ODR_ODR7 ^=0x01;//反轉(zhuǎn)藍(lán)燈電平,僅僅是為了指示ADC和DMA在工作,可去掉
DMA1_C1SPR_TCIF=0;//不軟件清除此中斷標(biāo)志位,會導(dǎo)致無法退出此中斷
for(i=0;i<9;i++)tmp+=ui16RX_buffer[i];
tmp /=9;//求九次采樣平均值
voltage=(uint32_t)299*tmp/4096;//計算最終輸出的電壓,結(jié)果擴大了100倍
//299是2.99V參考電壓,擴大了100倍
asm("nop");
}
}
/******************************************************************************************************
* 名 稱: ADC中斷
* 功 能: EOC事件處理函數(shù)
* 入口 參數(shù):無
* 出口 參數(shù):無
* 說 明:
* 范 例:無
******************************************************************************************************/
//#pragma vector=COMP_EF2_vector
//__interrupt void ADC1_ISR(void)
//{
// static uint16_t tmp=0;
// if(ADC1_SR_EOC==1)
// {
// PC_ODR_ODR7 ^=0x01;
// ADC1_SR_EOC=0;
// tmp = ADC1_DRH;
// tmp = (tmp<<8)+ADC1_DRL;
// tmp=(uint32_t)299*tmp/4096;
//// VDD_Value=(uint32_t)1225*4096/temp;//得到的數(shù)值單位為mv
// asm("nop");
// }
//}
復(fù)制代碼
作者:
hy345612553
時間:
2018-2-3 11:35
請教一個問題:我用的STM8L151K4 查看配置資料和STM8L152C6大概一致,我用AIN0測熱敏電子電壓,發(fā)現(xiàn)DMA1_CH1_TC_vector中斷始終進(jìn)不來,而你的另一份文檔測內(nèi)部VDD電壓運行正常,請教問題可能是哪里。我用的是IAR for STM8,中斷向量表已經(jīng)對過,沒問題
作者:
hy345612553
時間:
2018-2-3 11:37
請教STM8L151K4 使用DMA ,按照你的文檔COPY的,進(jìn)不了中斷
作者:
hy345612553
時間:
2018-2-6 14:56
謝謝!測量次數(shù)不夠沒進(jìn)中斷,非常感謝分享
作者:
jxchen
時間:
2019-3-2 14:28
按照你的文檔COPY的,進(jìn)不了中斷
你說,測量次數(shù)不夠沒進(jìn)中斷,不懂你的意思
可以說清處一點?
作者:
zhuizhuizhui135
時間:
2019-11-21 15:34
你好!請問我copy你這個程序在IAR上為什么進(jìn)入不了中斷?謝謝
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
中文字幕不卡在线观看
|
久久久久久久夜
|
美女黄色在线观看
|
午夜精品一区二区三区免费视频
|
欧美激情视频一区二区三区在线播放
|
亚洲视频一区二区三区四区
|
日韩欧美国产精品综合嫩v 一区中文字幕
|
五十女人一级毛片
|
伊人成人免费视频
|
欧美一级黄色片免费观看
|
中文字幕在线看人
|
拍戏被cao翻了h承欢
|
欧美日韩综合精品
|
久久精品国产99国产精品
|
亚洲视频在线播放
|
欧美a区
|
亚洲iv一区二区三区
|
成人久久
|
国产欧美二区
|
日韩精品一区二区三区在线播放
|
免费看黄视频网站
|
午夜视频在线免费观看
|
欧美v在线
|
精品1区
|
91在线精品一区二区
|
欧美一级视频免费看
|
亚洲网址
|
日韩电影免费观看中文字幕
|
一级黄在线观看
|
国产一区久久久
|
欧美亚洲综合久久
|
91日日
|
国产成人精品一区
|
精品一区二区久久
|
午夜免费福利片
|
欧美日本韩国一区二区
|
免费h在线
|
一级毛片免费看
|
久久久国产一区
|
成人在线精品
|
日韩国产一区二区
|