<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > MCU怎么做一個(gè)簡(jiǎn)單的ADC?

MCU怎么做一個(gè)簡(jiǎn)單的ADC?

作者: 時(shí)間:2018-08-03 來(lái)源:網(wǎng)絡(luò ) 收藏

  STM32的優(yōu)點(diǎn)在哪里?除去宣傳環(huán)節,細細分析,STM32時(shí)鐘不算快,72MHZ,也不能擴展大容量的RAM FLASH,同樣沒(méi)有DSP那樣強大的指令集。它的優(yōu)勢在哪里呢?

本文引用地址:http://dyxdggzs.com/article/201808/390000.htm

  ---就在快速采集數據,快速處理上。

  ARM的特點(diǎn)就是方便?!∵@個(gè)快速采集,高性能的就是一個(gè)很好的體現,12位精度,最快1uS的轉換速度,通常具備2個(gè)以上獨立的控制器,這意味著(zhù),STM32可以同時(shí)對多個(gè)模擬量進(jìn)行快速采集,這個(gè)特性不是一般的具有的。以上高性能的,配合相對比較塊的指令集和一些特色的算法支持,就構成了STM32在電機控制上的強大特性。

  好了,正題,怎么做一個(gè)簡(jiǎn)單的ADC?

  注意是簡(jiǎn)單的,ADC是個(gè)復雜的問(wèn)題,涉及硬件設計,電源質(zhì)量,參考電壓,信號預處理等等問(wèn)題。我們只就如何在內完成一次ADC作討論。

  談到ADC,我們還要第一次引入另外一個(gè)重要的設備DMA。DMA是什么東西呢。

  通常在8位單片機時(shí)代,很少有這個(gè)概念。在外置資源越來(lái)越多以后,我們把一個(gè)內部分為 主處理器 和 外設兩個(gè)部分。主處理器當然是執行我們指令的主要部分,外設則是 串口 I2C ADC 等等用來(lái)實(shí)現特定功能的設備,回憶一下,8位時(shí)代,我們的主處理器最常干的事情是什么?邏輯判斷?不是。那才幾個(gè)指令計算算法?不是。大部分時(shí)候算法都很簡(jiǎn)單?!∈聦?shí)上,主處理器就是作個(gè)搬運工,

  把USART的數據接收下來(lái),存起來(lái)

  把ADC的數據接收下來(lái),存起來(lái)

  把要發(fā)送的數據,存起來(lái),一個(gè)個(gè)的往USART里放。

  …………

  為了解決這個(gè)矛盾,人們想到一個(gè)辦法,讓外設和內存間建立一個(gè)通道,在主處理器允許下,讓外設和內存直接 讀寫(xiě),這樣就釋放了主處理器,這個(gè)東西就是DMA。

  打個(gè)比方:

  一個(gè)MCU是個(gè)公司。老板就是主處理器員工是外設,倉庫就是內存.

  從前 倉庫的東西都是老板管的。員工需要原料工作,就一個(gè)個(gè)報給老板,老板去倉庫里一個(gè)一個(gè)拿。員工作好的東西,一個(gè)個(gè)給老板,老板一個(gè)個(gè)放進(jìn)倉庫里。老板很累,雖然老板是超人,也受不了越來(lái)越多的員工和單子。

  最后老板雇了一個(gè)倉庫保管員,它就是DMA

  他專(zhuān)門(mén)負責 入庫和出庫,只需要把出庫 和入庫計劃給老板過(guò)目老板說(shuō)OK,就不管了。

  后面的入庫和出庫過(guò)程,員工只需要和這個(gè)倉庫保管員打交道就可以了。

  --------閑話(huà),馬七時(shí)常想,讓設備與設備之間開(kāi)DMA,豈不更牛X,比喻完成。

  ADC是個(gè)高速設備,前面提到。而且ADC采集到的數據是不能直接用的。即使你再小心的設計外圍電路,測的離譜的數據總會(huì )出現。那么通常來(lái)說(shuō),是采集一批數據,然后進(jìn)行處理,這個(gè)過(guò)程就是軟件濾波。

  DMA用到這里就很合適。讓ADC高速采集,把數據填充到RAM中,填充一定數量,比如32個(gè),64個(gè)MCU再來(lái)使用。

  -----多一句,也可以說(shuō),單次ADC毫無(wú)意義。

  下面我們來(lái)具體介紹,如何使用DMA來(lái)進(jìn)行ADC操作。初始化函數包括兩部分,DMA初始化和 ADC初始化我們有多個(gè)管理員--DMA,一個(gè)管理員當然不止管一個(gè)DMA操作。所以DMA有多個(gè)Channel

  //ADC with DMA Init

  #define ADC_Channel ADC_Channel0

  #define ADC1_DR_Address ((u32)0x4001244C)

  void ADCWithDMAInit()

  {

  //DMA init; Using DMA channel 1

  DMA_DeInit(DMA1_Channel1); //開(kāi)啟DMA1的第一通道

  DMA_InitStruct.DMA_PeripheralBaseAddr = ADC1_DR_Address; //DMA對應的外設基地址,這個(gè)地址走Datasheet查

  DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //轉換結果的數據大小

  DMA_InitStruct.DMA_MemoryBaseAddr = (unsigned long)&ADC_ConvertedValue; //

  DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA的轉換模式是SRC模式,就是從外設向內存中搬運,

  DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; //M2M模式禁止,memory to memory,這里暫時(shí)用不上,以后介

  紹

  DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //DMA搬運的數據尺寸,注意ADC是12位的,

  HalfWord就是16位

  DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable; //接收一次數據后,目標內存地址是否后移--重

  要概念,用來(lái)采集多個(gè)數據的

  DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //接收一次數據后,設備地址是否后移

  DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; //轉換模式,循環(huán)緩存模式,常用,M2M果果開(kāi)啟了,這個(gè)模式失效

  。

  DMA_InitStruct.DMA_Priority = DMA_Priority_High; //DMA優(yōu)先級,高

  DMA_InitStruct.DMA_BufferSize = 1; //DMA緩存大小,1個(gè)

  DMA_Init(DMA1_Channel1,&DMA_InitStruct);

  // Enable DMA1

  DMA_Cmd(DMA1_Channel1, ENABLE);

  }

  void ADCx_Init(unsigned char ADC_Channel)

  {

  ADC_DeInit(ADC1); //開(kāi)啟ADC1

  ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; //轉換模式,為獨立轉換。轉換模式太多了,以后深究

  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //對齊方式,ADC結果是12位的,顯然有個(gè)對齊左邊還是右邊

  的問(wèn)題。一般是右對齊

  ADC_InitStruct.ADC_ConTInuousConvMode = ENABLE; //連續轉換模式開(kāi)啟

  ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ADC外部出發(fā)開(kāi)關(guān),關(guān)閉

  ADC_InitStruct.ADC_NbrOfChannel = 2; //開(kāi)啟通道數,2個(gè)

  ADC_InitStruct.ADC_ScanConvMode = ENABLE; //掃描轉換模式開(kāi)啟

  ADC_Init(ADC1, &ADC_InitStruct);

  ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTIme_239Cycles5); //規則組通道設置,關(guān)鍵函數 轉

  換器ADC1,選擇哪個(gè)通道channel,規則采樣順序,1到16,以后解釋詳細含義,最后一個(gè)參數是轉換時(shí)間,越長(cháng)越準越穩定

  // ADC1 to DMA, Enable

  ADC_DMACmd(ADC1, ENABLE); //ADC命令,和DMA關(guān)聯(lián)。

  //ADC1 Enable

  ADC_Cmd(ADC1,ENABLE); //開(kāi)啟ADC1

  //Reset the CalibraTIon of ADC1

  ADC_ResetCalibraTIon(ADC1); //重置校準

  //wait until the Calibration‘s finish

  while(ADC_GetResetCalibrationStatus(ADC1)) //等待重置校準完成

  ;

  ADC_StartCalibration(ADC1); //開(kāi)始校準

  while(ADC_GetCalibrationStatus(ADC1)) //等待校準完成

  ;

  ADC_SoftwareStartConvCmd(ADC1, ENABLE); //連續轉換開(kāi)始,從選擇開(kāi)始,MCU可以不用管了,ADC將通過(guò)DMA不斷刷新

  制定RAM區

  // Attach them;

  }

  最后講講濾波算法

  濾波的方法以后會(huì )開(kāi)個(gè)專(zhuān)題。

  特別提一下---沒(méi)有完美的濾波算法,只有合適的濾波算法。

  需要綜合考慮信號特點(diǎn),噪聲特點(diǎn),控制對象等等,

  這里用個(gè)最簡(jiǎn)單的濾波算法,均值濾波。

  采樣16次,取平均值,吼吼,在豆皮上跳動(dòng)還是蠻小的,合適,吼吼

  //16ms finish a ADC detection

  // return mv

  unsigned int ADC_filter(void)

  {

  unsigned int result=“0”;

  unsigned char i;

  for(i=16;i》0;i--)

  {

  Delay_xms(1);

  result += ADC_ConvertedValue;

  }

  return (unsigned int)(((unsigned long)(result》》4))*3300》》12);

  }



關(guān)鍵詞: MCU ADC

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>