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中: