STM8L051调试笔记之基础功能:
系统时钟、串口、定时器都是基础而且必须的功能,这里放在一起统一记录,之所以用TIM2定时器,是因为想实现STM32的滴答定时器功能
这些基础功能没什么好理解的,就直接贴代码了main.c:
main.c:
void main(void) { enableInterrupts(); Sysclk_Init(); LED_Init(); Uart1_Init(); printf("This is a STM8 code!!!\r\n"); while (1) { if(secondClock_flag) { secondClock_flag = 0; printf("This is a STM8 code!!!\r\n"); } if(calculate_flag) { calculate_flag = 0; printf("a minute\r\n"); } } }
内部时钟及定时器:
我使用的板子上是没有外部晶振的,所以这里使用的是内部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 != '\0') { 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 <stdio.h> #include <stdarg.h> /* 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中: