×
嵌入式 > 技术百科 > 详情

STM8L051F3基础功能:内部时钟;TIM2定时器;串口及printf

发布时间:2020-06-17 发布时间:
|

STM8L051调试笔记之基础功能:

系统时钟、串口、定时器都是基础而且必须的功能,这里放在一起统一记录,之所以用TIM2定时器,是因为想实现STM32的滴答定时器功能

这些基础功能没什么好理解的,就直接贴代码了main.c:

main.c:

  void main(void)

  {

    enableInterrupts();

    Sysclk_Init();

    LED_Init();

    Uart1_Init();

  

    

    printf("This is a STM8 code!!!rn");

   

   

   while (1)

   {

     

     if(secondClock_flag)

     {

       secondClock_flag = 0;

       printf("This is a STM8 code!!!rn");

     }

     

     if(calculate_flag)

     {

       calculate_flag = 0;

       printf("a minutern");

     }

   }

}


内部时钟及定时器:

我使用的板子上是没有外部晶振的,所以这里使用的是内部16Mhz的晶振,可以按个人需求对其进行分频。需要说明的是,STM8的程序中,即使没有配置系统时钟,板子依然可以工作,因为默认会有一个2Mhz的内部时钟,这一点在手册中可以查到:

接下来贴代码,由于本人比较懒,只保留的内部时钟的代码,对时钟要求不高的可以参考参考,要求时钟准确的还是用外部晶振吧,代码中附送延时函数,在我的上一篇笔记中有记录

sysclk.c:

#include "sysclk.h"


volatile u8 fac_us=0;


u8 secondClock_flag = 0;

u8 calculate_flag = 0;


void delay_us(u16 nus)

{

  __asm(

"PUSH A          n"

"DELAY_XUS:      n"

"LD A,fac_us     n"

"DELAY_US_1:     n"

"NOP             n"

"DEC A           n"

"JRNE DELAY_US_1 n"

"NOP             n"

"DECW X          n"

"JRNE DELAY_XUS  n"

"POP A           n"

); 

}


void delay_ms(u32 nms)

{

  u8 t;

  if(nms>65)

  {

    t=nms/65;

    while(t--)delay_us(65000);

    nms=nms%65;

  }

  delay_us(nms*1000);

}


void delay_init(u8 clk)

{

  if(clk>16)fac_us=(16-4)/4;

  else if(clk>4)fac_us=(clk-4)/4; 

  else fac_us=1;

}


void TIM2_Init(void)

{

  CLK_PeripheralClockConfig(CLK_Peripheral_TIM2,ENABLE);

  TIM2_TimeBaseInit(TIM2_Prescaler_16,TIM2_CounterMode_Up,1000);  //将系统时钟16分频得到1Mhz,计数1000(或999,未细究)则得到一个每ms进一次的中断,

  TIM2_ARRPreloadConfig(ENABLE);

  TIM2_ITConfig(TIM2_IT_Update,ENABLE);

  

  TIM2_Cmd(ENABLE);

}


void Sysclk_Init(void)

{

  CLK_HSICmd(ENABLE);

  CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI);  //选择HIS内部晶振,

  CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);  //STM8,HSI为16Mhz,这里1分频即不分频

  

  TIM2_Init();

  delay_init(16);  //参数是系统时钟,这里是16Mhz所以参数为16

}



sysclk.h中内容:

中断stm8l15x_it.c中内容(找到TIM2定时器对应的INTERRUPT_HANDLER):

串口功能:

这里使用的是PA2,PA3两个脚的串口,由于STM8只有8kb的flash,使用printf函数时一不小心就内存不足了,也在网上尝试了很多解决方案,这里我尝试的比较有用的方法是在设置里将printf formatter的值改为Tiny,我这里改为small也是可以的,至于这样会产生什么影响需要再进行分析了,听说改为Tiny是不使用对浮点数的操作,会使对printf相关库函数编译的代码小很多,具体是否如此没有验证,如有错误误导他人请及时批评指正。

贴代码:

uart.c

#include "uart.h"


/**

  * @brief  Configure USART peripheral  

  * @param  None

  * @retval None

  */

void Uart1_Init(void)

{

  /* USART1 configured as follow:

        - BaudRate = 115200 baud  

        - Word Length = 8 Bits

        - One Stop Bit

        - Odd parity

        - Receive and transmit enabled

        - USART Clock disabled

  */

  /* Enable USART clock */

  CLK_PeripheralClockConfig(CLK_Peripheral_USART1, ENABLE);

  

  /* USART1 Tx- Rx remapping to PA2- PA3 */

  SYSCFG_REMAPDeInit();

  SYSCFG_REMAPPinConfig(REMAP_Pin_USART1TxRxPortA, ENABLE);

  

  /* Configure USART Tx pin output*/

  GPIO_Init(GPIOA, GPIO_Pin_2, GPIO_Mode_Out_PP_High_Fast);

  

  /* Configure USART Rx pin input*/

  GPIO_Init(GPIOA, GPIO_Pin_3, GPIO_Mode_In_PU_No_IT);

  

  /* RESET USART1 */

  USART_DeInit(USART1);

  

  /* USART configuration */

  USART_Init(USART1, (u32)115200, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No, USART_Mode_Tx|USART_Mode_Rx);


  /* Enable the USART Receive interrupt: this interrupt is generated when the USART

    receive data register is not empty */

  USART_ClearITPendingBit(USART1, USART_IT_RXNE);

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

  /* Enable the USART Transmit complete interrupt: this interrupt is generated when the USART

    transmit Shift Register is empty */

  //USART_ITConfig(EVAL_COM1, USART_IT_TC, ENABLE);


  /* Enable USART */

  USART_Cmd(USART1, ENABLE);

}


/* 发送一个字节 */

void UART1_SendByte(u8 data)

{

  USART_SendData8(USART1, data);

  

  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

}


/* 发送len个字符 */

void UART1_SendStr(u8 *str)

{

  while(*str != '')    

  {    

    UART1_SendByte(*str++);

  }    

}


/* 接收一个字符 */

u8 UART1_ReceiveByte(void)

{

  u8 UART1_RX_BUF; 

      

  while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

  

  UART1_RX_BUF = USART_ReceiveData8(USART1);

  

  return  UART1_RX_BUF;

}


#ifdef _IAR_

int fputc(int ch, FILE *f)

{

  UART1_SendByte(ch);

  return (ch);

}

#else

PUTCHAR_PROTOTYPE

{

  UART1_SendByte(c);

  return (c);

}

#endif


GETCHAR_PROTOTYPE

{

#ifdef _COSMIC_

   char c = 0;

#else

   int c = 0;

#endif

   /* Loop until the Read data register flag is SET */

   while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

   c = USART_ReceiveData8(USART1);

   return (c);

}

uart.h:


#ifndef __UART_H

#define __UART_H


/* 包含系统头文件 */

#include "stm8l15x_conf.h"

#include

#include


/* Private define ------------------------------------------------------------*/

#ifdef _RAISONANCE_

#define PUTCHAR_PROTOTYPE int putchar (char c)

#define GETCHAR_PROTOTYPE int getchar (void)

#elif defined (_COSMIC_)

#define PUTCHAR_PROTOTYPE char putchar (char c)

#define GETCHAR_PROTOTYPE char getchar (void)

#else /* _IAR_ */

#define PUTCHAR_PROTOTYPE int putchar (int c)

#define GETCHAR_PROTOTYPE int getchar (void)

#endif /* _RAISONANCE_ */


void Uart1_Init(void);

void UART1_SendByte(u8 data);

void UART1_SendStr(u8 *str);


#ifdef _IAR_

int fputc(int ch, FILE *f);

#endif


#endif


stm8l15x_it.c中:




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
NS推出采用第二代PowerWise技术的能源管理单元及先进电源控制器