单片机学习小组
直播中

小峰

12年用户 903经验值
私信 关注

STM8S003F3如何使用ADC?

STM8S003F3如何使用ADC?

回帖(1)

李瑜刈

2022-2-11 14:01:21
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的使用经验积累吧。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分