这是一个我花了较长时间摸索出来的STM8L-051的例程,它控制LED灯,Timer2定时100us进入中断,软件启动ADC,采样10 次后取平均,将结果通过UASART发送至PC机,在超级终端上显示的实用程序,因其内存极小,不能用printf等函数,因此对于想用这款资源极少的MCU的开发者来说,读这篇文章会大大节约你的研发时间。有不会的问题请发邮件
#include
#include "stm8l15x.h"
#include "iostm8l051f3.h"
#define LED_GPIO_PORT GPIOA
#define LED_GPIO_PINS GPIO_Pin_2 | GPIO_Pin_3
#define ADC1_DR_ADDRESS ((uint16_t)0x5344)
#define BUFFER_SIZE ((uint8_t) 0x02)
#define BUFFER_ADDRESS ((uint16_t)(&Buffer))
#define ASCII_NUM_0 ((uint8_t) 48)
#define ADC_RATIO ((uint16_t) 806)
#define SampleADC ((uint8_t) 0x0A)
uint8_t Buffer[4] = {0, 0, 0, 0};
uint16_t ADCdata = 0;
uint16_t ADCvalue = 0;
unsigned char LED =1;
unsigned char c = 8;
uint16_t acode = 1234; //43 "+" 0x2B;
void Delay(__IO uint16_t nCount)
{
while (nCount != 0)
{
nCount--;
}
}
//int putchar(int c)
//{
// while ((USART1_SR&0x80)==0x00);
// UART2_sendchar((u8)c);
// return (c);
//}
static void CLK_Config(void)
{
CLK_SYSCLKSourceSwitchCmd(ENABLE);
CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI);
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSI)
{}
CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);
// CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_USART1, ENABLE);
}
static void GPIO_Config(void)
{
PC_DDR = 0X20;
PC_CR1 = 0X20;
PA_DDR = 0X0C;
PA_CR1 = 0X0C;
}
static void USART1_Config(void)
{
// ADCvalue = USART1_DR;
USART1_BRR2 = 0x03;
USART1_BRR1 = 0x68; //16M/9600=683
USART1_CR2 = 0x0C; //Transmitter & receiver enable
}
static void ADC_Config(void)
{
ADC1_CR2 = 0x27; //risign edge, trigger 3, sampling time 384
ADC1_CR3 = 0x10; //16channel
// ADC_ChannelCmd(ADC1, ADC_Channel_17, ENABLE);
}
void TIM2_Config(void)
{
TIM2_PSCR = 0x07; // 应是16,但只能置三位,所以是111 fCK_PSC / 2(PSC[2:0]).
// TIM2_PSCRL = 0x3F; // PSCR=0x1F3F,f=8M/(0x1F3F+1)=1000Hz,每个计数周期1ms
TIM2_ARRH = 0x00; // 自动重载寄存器ARR=0x01F4=500
TIM2_ARRL = 0x18; // 24X4us=96us 每记数500次产生一次中断,即500ms
TIM2_IER = 0x01; // 允许更新中断
TIM2_CR1 = 0x05; // 计数器使能,开始计数,只允许更新中断请求
}
void Delay (uint16_t nCount);
//#pragma vector = ADC1_EOC_vector
//__interrupt void ADC1_EOC(void)
//{
// ADCdata = ADC_GetConversionValue(ADC1);
// }
#pragma vector =TIM2_OVR_UIF_vector
__interrupt void TIM2_OVR_UIF(void)
{
asm("sim");
static uint8_t measurements = SampleADC;
static uint32_t accumulator = 0;
uint32_t average = 0;
uint16_t factor10 = 1000;
int8_t i ;
ADCdata = 0;
TIM2_SR1 = 0x00; //Clear UIF
ADC1_SR = 0x00; //Clear EOC
ADC1_CR1 = 0x03; // EOC interrupt unable, software set start, ADC enable
// while (!(ADC1_SR & 0x01));
Delay(0x000F);
ADCdata = (uint16_t)(ADC1_DRH);
ADCdata = (uint16_t)((uint16_t)((uint16_t)ADCdata << 8) | ADC1_DRL);
accumulator += ADCdata;
if(measurements == 0)
{
LED= !LED;
measurements = SampleADC;
average = accumulator/SampleADC;
ADCvalue = (uint16_t)((uint32_t)((uint32_t)average * (uint32_t)ADC_RATIO) / (uint32_t)1000);
accumulator = 0;
while(!USART1_SR_TXE);
for (i = 3; i >= 0; i--)
{
Buffer = (ADCvalue/factor10) % 10 + 48; //提取十进制每一位,并转换成ASCII码
factor10 = factor10 / 10;
while(!USART1_SR_TXE);
USART1_DR = Buffer; //发送每一位,先发高位
}
while(!USART1_SR_TXE);
USART1_DR = 32; //发送空格
}
measurements--;
asm("rim");
}
void main(void)
{
asm("sim");
GPIO_Config();
GPIO_Init(LED_GPIO_PORT, LED_GPIO_PINS, GPIO_Mode_Out_PP_Low_Fast);
CLK_Config();
ADC_Config();
TIM2_Config();
USART1_Config();
//DMA_Config();
asm("rim");
while (1) {
PA_ODR_ODR2 = LED;
PA_ODR_ODR3 = LED; }
}
|