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的使用经验积累吧。
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的使用经验积累吧。
举报