STM8单片机ADC、Timer、USART实用例程

这是一个我花了较长时间摸索出来的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[i] = (ADCvalue/factor10) % 10 + 48; //提取十进制每一位,并转换成ASCII码
 
           factor10 = factor10 / 10;
 
           while(!USART1_SR_TXE);
 
           USART1_DR = Buffer[i];  //发送每一位,先发高位
 
         }
 
        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; }  
 
}
永不止步步 发表于11-22 09:49 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67410个|学分:307967个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号