STM32F103VET6-keil工程配置-USART串口中斷
1、新建一個標準空白工程
2、設置時鐘源為外部HSE時鐘
1 #ifndef __SYSCLK_CONFIG_H 2 #define __SYSCLK_CONFIG_H 3 #include "main.h" 4 5 #define SystemCoreClock 72000000 6 void SYSCLK_Config(void); 7 void Delay_us(uint32_t nus); 8 void Delay_ms(uint32_t nms); 9 void Delay_s(uint32_t ns); 10 #endif
#include "SysCLK_Config.h" /********************************************** 1、配置HSE外部時鐘 2、開啟HSE/HSI時鐘,並等待HSE/HSI穩定 3、設置AHB,APB2,APB1 的分頻因子 4、設置PLL時鐘來源,和PLL倍頻因子,設置各種頻率主要就是在這裡設置 5、開啟PLL等待PLL穩定 6、把PLLCK切換為系統時鐘SYSCLK 7、讀取時鐘切換狀態,確保PLLCLK被選擇為系統時鐘 **********************************************/ void SYSCLK_Config(void) { __IO uint32_t HSEStartUpStatus = 0; /* 複位RCC時鐘為初始化狀態 */ RCC_DeInit(); /* 使能RCC時鐘源為HSE時鐘 */ RCC_HSEConfig(RCC_HSE_ON); /* 等待HSE時鐘啟動穩定 */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* 只有HSE穩定之後才會往下執行 */ if(HSEStartUpStatus == SUCCESS) { /* 使能FALSH 預存儲緩衝區 */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_2); /* 設置AHB匯流排時鐘分頻因子 */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* 設置APB1匯流排時鐘分頻因子 */ RCC_PCLK1Config(RCC_HCLK_Div2);//APB1匯流排最高時鐘為36MHz /* 設置APB2匯流排時鐘分頻因子 */ RCC_PCLK2Config(RCC_HCLK_Div1); /* 設置PLL倍頻因子 */ RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); /* 設置PLL倍頻因子 */ RCC_PLLCmd(ENABLE); /* 等待PLL穩定 */ while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); /* PLL穩定後,把PLL時鐘切換為系統時鐘 SYSCLK */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* 讀取時鐘切換狀態位,確保PLLCLK被選中為系統時鐘 */ while(RCC_GetSYSCLKSource() != 0x08); } else { while(1); } } void Delay_us(uint32_t nus) { uint32_t temp; SysTick_Config(SystemCoreClock/1000000); //開啟SYSTick定時器 for(temp = 0;temp<nus;temp++) { while(!((SysTick->CTRL)&(1<<16))); } SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk; //關閉系統定時器 } void Delay_ms(uint32_t nms) { uint32_t temp; SysTick_Config(SystemCoreClock/1000); //開啟SYSTick定時器 for(temp = 0;temp<nms;temp++) { while(!((SysTick->CTRL)&(1<<16))); } SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk; //關閉系統定時器 } void Delay_s(uint32_t ns) { uint32_t temp; SysTick_Config(SystemCoreClock); //開啟SYSTick定時器 for(temp = 0;temp<ns;temp++) { while(!((SysTick->CTRL)&(1<<16))); } SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk; //關閉系統定時器 }
4、串口通過中斷接收數據並回傳
1 #ifndef __BSP_USART_H 2 #define __BSP_USART_H 3 #include "main.h" 4 5 /* 時鐘線宏定義 */ 6 #define Debug_Usart_APBxCLKCmd RCC_APB2PeriphClockCmd 7 #define Debug_Usart_GPIO_APBxCLKCmd RCC_APB2PeriphClockCmd 8 9 /* GPIO埠宏定義 */ 10 #define Debug_Usart_Rx_GPIO_PORT GPIOA 11 #define Debug_Usart_Rx_GPIO_PIN GPIO_Pin_10 12 #define Debug_Usart_Rx_GPIO_CLK RCC_APB2Periph_GPIOA 13 14 #define Debug_Usart_Tx_GPIO_PORT GPIOA 15 #define Debug_Usart_Tx_GPIO_PIN GPIO_Pin_9 16 #define Debug_Usart_Tx_GPIO_CLK RCC_APB2Periph_GPIOA 17 18 /* USART外設宏定義 */ 19 #define Debug_Usart USART1 20 #define Debug_Usart_Baudrate 115200 21 #define Debug_Usart_Clk RCC_APB2Periph_USART1 22 23 /* 串口中斷宏定義*/ 24 #define Debug_Usart_IRQ USART1_IRQn 25 #define Debug_Usart_IRQHandle USART1_IRQHandler 26 27 28 /* 函數聲明 */ 29 void Bsp_Usart_Init(void); 30 31 #endif
1 #include "bsp_usart.h" 2 3 void Bsp_Usart_Init(void) 4 { 5 /* 結構體定義 */ 6 GPIO_InitTypeDef GPIO_Initstructure; 7 NVIC_InitTypeDef NVIC_Initstructure; 8 USART_InitTypeDef USART_Initstructure; 9 10 /* 使能時鐘 */ 11 Debug_Usart_GPIO_APBxCLKCmd(Debug_Usart_Rx_GPIO_CLK|Debug_Usart_Tx_GPIO_CLK,ENABLE); 12 Debug_Usart_APBxCLKCmd(RCC_APB2Periph_USART1,ENABLE); 13 14 /* 配置 GPIO 結構體 */ 15 GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz; 16 GPIO_Initstructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出 17 GPIO_Initstructure.GPIO_Pin = Debug_Usart_Tx_GPIO_PIN; 18 GPIO_Init(Debug_Usart_Tx_GPIO_PORT,&GPIO_Initstructure); 19 20 GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入 21 GPIO_Initstructure.GPIO_Pin = Debug_Usart_Rx_GPIO_PIN; 22 GPIO_Init(Debug_Usart_Rx_GPIO_PORT,&GPIO_Initstructure); 23 24 /* 配置 USART 結構體 */ 25 USART_Initstructure.USART_BaudRate = Debug_Usart_Baudrate; //波特率 26 USART_Initstructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬體流控制 27 USART_Initstructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //收發模式 28 USART_Initstructure.USART_Parity = USART_Parity_No; //校驗位 29 USART_Initstructure.USART_StopBits = USART_StopBits_1; //停止位 30 USART_Initstructure.USART_WordLength = USART_WordLength_8b; //數據長度 31 USART_Init(Debug_Usart,&USART_Initstructure); 32 33 /* 配置 NVIC 結構體 */ 34 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷向量組 35 36 NVIC_Initstructure.NVIC_IRQChannel = Debug_Usart_IRQ; 37 NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE; 38 NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 1; //搶佔優先順序 39 NVIC_Initstructure.NVIC_IRQChannelSubPriority = 1; //子優先順序 40 NVIC_Init(&NVIC_Initstructure); 41 42 /* 使能串口接收中斷 */ 43 USART_ITConfig(Debug_Usart,USART_IT_RXNE,ENABLE); 44 45 /* 使能串口 */ 46 USART_Cmd(Debug_Usart,ENABLE); 47 } 48 void Debug_Usart_IRQHandle(void) /* 串口中斷服務函數 */ 49 { 50 uint8_t ch; 51 52 /* 檢測接收緩衝區滿 開始接收數據 */ 53 if(USART_GetFlagStatus(Debug_Usart,USART_FLAG_RXNE) != RESET) 54 { 55 ch = USART_ReceiveData(Debug_Usart); 56 USART_SendData(Debug_Usart,ch); 57 /* 等待發送緩衝區為空 */ 58 while(USART_GetFlagStatus(Debug_Usart,USART_FLAG_TXE) == RESET); 59 } 60 }