天天看點

STM8S003F3 使用ADC:固件庫版本與寄存器版本

      STM8S003F3這款小型MCU,隻有1K RAM與8K Flash,應用比較簡單,AD采樣,GPIO控制,PWM控制,還是不錯的嵌入式的應用。

     最近一個項目用到了幾路AD采樣,我平時一般喜歡下載下傳最新的官方标準固件庫,隻是,這次遇到的問題是,在使用PWM與ADC采樣後,代碼大小竟然大于8K,編譯失敗!!!後來,看了下Debug下的map檔案,發現,使用ADC的固件庫,大小竟然有1K的代碼空間。後來改為寄存器的,發現代碼還不到100位元組。

    (1)固件庫AD采樣的代碼如下,代碼易懂,但編譯後代碼較大:單通道采樣,多個的話,隻需要一個一個采集。

#include "adc.h"
#include "stm8s.h"


void InitAD(uint8_t channel)
{
  /* De-Init ADC peripheral*/
  ADC1_DeInit();
  //通道初始化
  ADC1_Init(ADC1_CONVERSIONMODE_SINGLE,
            (ADC1_Channel_TypeDef)channel,
            ADC1_PRESSEL_FCPU_D18,
            ADC1_EXTTRIG_TIM,
            DISABLE,
            ADC1_ALIGN_RIGHT,
            (ADC1_SchmittTrigg_TypeDef)channel,
            DISABLE);
}

void AD_Start(void)
{
  ADC1_ScanModeCmd(ENABLE);//啟用掃描模式
  ADC1_DataBufferCmd(ENABLE);//啟用緩存寄存器存儲資料
  //ADC1_ITConfig(ADC1_IT_EOCIE,DISABLE);//關閉中斷功能 
  ADC1_Cmd(ENABLE);//啟用ADC1
  ADC1_StartConversion();//開始轉換*/
}

uint16_t getADCValue(uint8_t channel)
{
  InitAD(channel);
  AD_Start();
  while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == RESET);
  return ADC1_GetConversionValue();
}
           

調用的方法如下:

VccAdc = getADCValue(6);
           

   (2)寄存器AD采樣的代碼如下:短小,能用,隻是不看手冊,很難了解。

#include "adc.h"
#include "stm8s.h"

void InitAD(void)
{
  ADC1->CR1 = 0x01;     //設定ADC不分頻、單次轉換
  ADC1->CR2 = 0x08;     //設定不外部觸發也不開啟中斷、資料右對齊、不開啟掃描
  ADC1->CSR = 0x06;     //清除轉換标志 設定通道5為AD口
}

void setADCChannel(uint8_t channel)
{
  ADC1->CSR = (channel & 0x0F); //寫入轉換通道
}

uint16_t getADCValue(void)
{
  uint16_t adc = 0x00;
  ADC1->CR1 |= 0x01;                                    //啟動ADC開始轉換
  while((adc & 0x80) == 0x00){adc = ADC1->CSR;}         //等待轉換完成
  adc = ADC1->DRL;
  adc |= (ADC1->DRH << 0x08);                           //擷取ADC值
  return adc;
}
           

調用的方法:

setADCChannel(VCC_AIN_CHANNEL);
 VccAdc = getADCValue();
           

測試下來,采樣還算是比較準确的,并且速度也挺快的。

算是STM8S003的使用經驗積累吧。