文章目录

  • 一、开发环境
  • 二、串口中断发送原理
  • 三、实验现象
  • 四、完整源码
  • 五、后记

一、开发环境

/***************************************************************
文章名:基于STM32F103RCT6这款MCU实现串口中断发送,使用环形队列
时间:2022年5月27日21:12:58
科室:N/A
员工:N/A
版本:V0
修改记录:N/A
目的:基于STM32F103RCT6这款MCU实现打印。这里的打印使用的非阻塞方式发送,也就是使用中断发送串口数据。并且,发送数据时使用了环形队列这样一种高级数据结构,用于做串口发送的缓冲区。这篇文章会总结实现的硬件平台、软件平台、调试工具、调试手段、心得体会,详细的代码文件也会在文章里展示出来。
硬件平台:基于STM32F103RCT6的开发板,STM32F103RCT6是基于ARM
Cortex M3系列的单片机,外部晶振使用8MHZ,3.3V供电。
软件平台:keil uvision5
下载工具:串口线、stc-isp-15xx-v6.87E
调试工具:XCOM V2.0
***************************************************************/
硬件平台图片:

软件平台图片:

下载工具图片:

调试工具图片:

二、串口中断发送原理

在正点原子系列教学里,printf的实现是通过如下方式实现的:

int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   USART1->DR = (u8) ch;      return ch;
}

这种方式打印数据有个特点,就是打印函数里用了while,也就是说每次发送前判断条件“USART1->SR&0X40)==0”,也就是判断一个字节的数据是否发送完毕。以波特率115200,1个起始位,1个停止位,8个数据位,无校验为例,发送这样一个字节的数据耗时10/115200(s)=8.68e(-5) s,也就是0.086ms。如果一次打印50个数据,就是4.3ms,这段时间里,mcu在等待数据发送完毕,没办法执行其他任务。可见这种方式非常耗费资源。
本文介绍另外一种中断方式发送串口数据的方法,每次检测到发送数据寄存器空,就在中断里向数据寄存器写数据,数据发送完毕,发送寄存器又空,又产生中断,循环往复,直到所有数据发送完毕。这种方式的优点在于,串口发送数据的时候是硬件行为,并不需要cpu等待所有数据发送完毕,利用了串口发送数据寄存器空产生中断这个特性。

三、实验现象

四、完整源码

stm32f10x_it.c

在这里插入代码片/********************************************************************************* @file    GPIO/IOToggle/stm32f10x_it.c * @author  MCD Application Team* @version V3.5.0* @date    08-April-2011* @brief   Main Interrupt Service Routines.*          This file provides template for all exceptions handler and peripherals*          interrupt service routine.******************************************************************************* @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"void NMI_Handler(void)
{
}void HardFault_Handler(void)
{/* Go to infinite loop when Hard Fault exception occurs */while (1){}
}void MemManage_Handler(void)
{/* Go to infinite loop when Memory Manage exception occurs */while (1){}
}void BusFault_Handler(void)
{/* Go to infinite loop when Bus Fault exception occurs */while (1){}
}void UsageFault_Handler(void)
{/* Go to infinite loop when Usage Fault exception occurs */while (1){}
}void SVC_Handler(void)
{
}void DebugMon_Handler(void)
{
}void PendSV_Handler(void)
{
}void SysTick_Handler(void)
{
}/******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************/
system_stm32f10x.c```c
/********************************************************************************* @file    GPIO/IOToggle/system_stm32f10x.c* @author  MCD Application Team* @version V3.5.0* @date    08-April-2011* @brief   CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.* * 1.  This file provides two functions and one global variable to be called from *     user application:*      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier*                      factors, AHB/APBx prescalers and Flash settings). *                      This function is called at startup just after reset and *                      before branch to main program. This call is made inside*                      the "startup_stm32f10x_xx.s" file.**      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used*                                  by the user application to setup the SysTick *                                  timer or configure other parameters.*                                     *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must*                                 be called whenever the core clock is changed*                                 during program execution.** 2. After each device reset the HSI (8 MHz) is used as system clock source.*    Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, to*    configure the system clock before to branch to main program.** 3. If the system clock source selected by user fails to startup, the SystemInit()*    function will do nothing and HSI still used as system clock source. User can *    add some code to deal with this issue inside the SetSysClock() function.** 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depedning on*    the product used), refer to "HSE_VALUE" define in "stm32f10x.h" file. *    When HSE is used as system clock source, directly or through PLL, and you*    are using different crystal you have to adapt the HSE value to your own*    configuration.*        ******************************************************************************* @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>*******************************************************************************//** @addtogroup CMSIS* @{*//** @addtogroup stm32f10x_system* @{*/  /** @addtogroup STM32F10x_System_Private_Includes* @{*/#include "stm32f10x.h"/*** @}*//** @addtogroup STM32F10x_System_Private_TypesDefinitions* @{*//*** @}*//** @addtogroup STM32F10x_System_Private_Defines* @{*//*!< Uncomment the line corresponding to the desired System clock (SYSCLK)frequency (after reset the HSI is used as SYSCLK source)IMPORTANT NOTE:============== 1. After each device reset the HSI is used as System clock source.2. Please make sure that the selected System clock doesn't exceed your device'smaximum frequency.3. If none of the define below is enabled, the HSI is used as System clocksource.4. The System clock configuration functions provided within this file assume that:- For Low, Medium and High density Value line devices an external 8MHz crystal is used to drive the System clock.- For Low, Medium and High density devices an external 8MHz crystal isused to drive the System clock.- For Connectivity line devices an external 25MHz crystal is used to drivethe System clock.If you are using different crystal you have to adapt those functions accordingly.*/#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */#define SYSCLK_FREQ_24MHz  24000000
#else
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz  24000000 */
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
#define SYSCLK_FREQ_72MHz  72000000
#endif/*!< Uncomment the following line if you need to use external SRAM mountedon STM3210E-EVAL board (STM32 High density and XL-density devices) or on STM32100E-EVAL board (STM32 High-density value line devices) as data memory */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
/* #define DATA_IN_ExtSRAM */
#endif/*!< Uncomment the following line if you need to relocate your vector Table inInternal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x0/*!< Vector Table base offset field. This value must be a multiple of 0x200. *//*** @}*//** @addtogroup STM32F10x_System_Private_Macros* @{*//*** @}*//** @addtogroup STM32F10x_System_Private_Variables* @{*//*******************************************************************************
*  Clock Definitions
*******************************************************************************/
#ifdef SYSCLK_FREQ_HSEuint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_24MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_36MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;        /*!< System Clock Frequency (Core Clock) */
#else /*!< HSI Selected as System Clock source */uint32_t SystemCoreClock         = HSI_VALUE;        /*!< System Clock Frequency (Core Clock) */
#endif__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
/*** @}*//** @addtogroup STM32F10x_System_Private_FunctionPrototypes* @{*/static void SetSysClock(void);#ifdef SYSCLK_FREQ_HSEstatic void SetSysClockToHSE(void);
#elif defined SYSCLK_FREQ_24MHzstatic void SetSysClockTo24(void);
#elif defined SYSCLK_FREQ_36MHzstatic void SetSysClockTo36(void);
#elif defined SYSCLK_FREQ_48MHzstatic void SetSysClockTo48(void);
#elif defined SYSCLK_FREQ_56MHzstatic void SetSysClockTo56(void);
#elif defined SYSCLK_FREQ_72MHzstatic void SetSysClockTo72(void);
#endif#ifdef DATA_IN_ExtSRAMstatic void SystemInit_ExtMemCtl(void);
#endif /* DATA_IN_ExtSRAM *//*** @}*//** @addtogroup STM32F10x_System_Private_Functions* @{*//*** @brief  Setup the microcontroller system*         Initialize the Embedded Flash Interface, the PLL and update the *         SystemCoreClock variable.* @note   This function should be used only after reset.* @param  None* @retval None*/
void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CLRCC->CFGR &= (uint32_t)0xF8FF0000;
#elseRCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL *//* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= (uint32_t)0xFF80FFFF;#ifdef STM32F10X_CL/* Reset PLL2ON and PLL3ON bits */RCC->CR &= (uint32_t)0xEBFFFFFF;/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x00FF0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#else/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
#endif/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers *//* Configure the Flash Latency cycles and enable prefetch buffer */SetSysClock();#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}/*** @brief  Update SystemCoreClock variable according to Clock Register Values.*         The SystemCoreClock variable contains the core clock (HCLK), it can*         be used by the user application to setup the SysTick timer or configure*         other parameters.*           * @note   Each time the core clock (HCLK) changes, this function must be called*         to update SystemCoreClock variable value. Otherwise, any configuration*         based on this variable will be incorrect.         *     * @note   - The system frequency computed by this function is not the real *           frequency in the chip. It is calculated based on the predefined *           constant and the selected clock source:*             *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)*                                              *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)*                          *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) *             or HSI_VALUE(*) multiplied by the PLL factors.*         *         (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value*             8 MHz) but the real value may vary depending on the variations*             in voltage and temperature.   *    *         (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value*              8 MHz or 25 MHz, depedning on the product used), user has to ensure*              that HSE_VALUE is same as the real frequency of the crystal used.*              Otherwise, this function may have wrong result.*                *         - The result of this function could be not correct when using fractional*           value for HSE crystal.* @param  None* @retval None*/
void SystemCoreClockUpdate (void)
{uint32_t tmp = 0, pllmull = 0, pllsource = 0;#ifdef  STM32F10X_CLuint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif /* STM32F10X_CL */#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)uint32_t prediv1factor = 0;
#endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL *//* Get SYSCLK source -------------------------------------------------------*/tmp = RCC->CFGR & RCC_CFGR_SWS;switch (tmp){case 0x00:  /* HSI used as system clock */SystemCoreClock = HSI_VALUE;break;case 0x04:  /* HSE used as system clock */SystemCoreClock = HSE_VALUE;break;case 0x08:  /* PLL used as system clock *//* Get PLL clock source and multiplication factor ----------------------*/pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;#ifndef STM32F10X_CLpllmull = ( pllmull >> 18) + 2;if (pllsource == 0x00){/* HSI oscillator clock divided by 2 selected as PLL clock entry */SystemCoreClock = (HSI_VALUE >> 1) * pllmull;}else{#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;/* HSE oscillator clock selected as PREDIV1 clock entry */SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; #else/* HSE selected as PLL clock entry */if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET){/* HSE oscillator clock divided by 2 */SystemCoreClock = (HSE_VALUE >> 1) * pllmull;}else{SystemCoreClock = HSE_VALUE * pllmull;}#endif}
#elsepllmull = pllmull >> 18;if (pllmull != 0x0D){pllmull += 2;}else{ /* PLL multiplication factor = PLL input clock * 6.5 */pllmull = 13 / 2; }if (pllsource == 0x00){/* HSI oscillator clock divided by 2 selected as PLL clock entry */SystemCoreClock = (HSI_VALUE >> 1) * pllmull;}else{/* PREDIV1 selected as PLL clock entry *//* Get PREDIV1 clock source and division factor */prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;if (prediv1source == 0){ /* HSE oscillator clock selected as PREDIV1 clock entry */SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;          }else{/* PLL2 clock selected as PREDIV1 clock entry *//* Get PREDIV2 division factor and PLL2 multiplication factor */prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                         }}
#endif /* STM32F10X_CL */break;default:SystemCoreClock = HSI_VALUE;break;}/* Compute HCLK clock frequency ----------------*//* Get HCLK prescaler */tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];/* HCLK clock frequency */SystemCoreClock >>= tmp;
}/*** @brief  Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.* @param  None* @retval None*/
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSESetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHzSetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHzSetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHzSetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHzSetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHzSetSysClockTo72();
#endif/* If none of the define above is enabled, the HSI is used as System clocksource (default after reset) */
}/*** @brief  Setup the external memory controller. Called in startup_stm32f10x.s *          before jump to __main* @param  None* @retval None*/
#ifdef DATA_IN_ExtSRAM
/*** @brief  Setup the external memory controller. *         Called in startup_stm32f10x_xx.s/.c before jump to main.*        This function configures the external SRAM mounted on STM3210E-EVAL*         board (STM32 High density devices). This SRAM will be used as program*         data memory (including heap and stack).* @param  None* @retval None*/
void SystemInit_ExtMemCtl(void)
{
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is required, then adjust the Register Addresses *//* Enable FSMC clock */RCC->AHBENR = 0x00000114;/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */  RCC->APB2ENR = 0x000001E0;/* ---------------  SRAM Data lines, NOE and NWE configuration ---------------*/
/*----------------  SRAM Address lines configuration -------------------------*/
/*----------------  NOE and NWE configuration --------------------------------*/
/*----------------  NE3 configuration ----------------------------------------*/
/*----------------  NBL0, NBL1 configuration ---------------------------------*/GPIOD->CRL = 0x44BB44BB;  GPIOD->CRH = 0xBBBBBBBB;GPIOE->CRL = 0xB44444BB;  GPIOE->CRH = 0xBBBBBBBB;GPIOF->CRL = 0x44BBBBBB;  GPIOF->CRH = 0xBBBB4444;GPIOG->CRL = 0x44BBBBBB;  GPIOG->CRH = 0x44444B44;/*----------------  FSMC Configuration ---------------------------------------*/
/*----------------  Enable FSMC Bank1_SRAM Bank ------------------------------*/FSMC_Bank1->BTCR[4] = 0x00001011;FSMC_Bank1->BTCR[5] = 0x00000200;
}
#endif /* DATA_IN_ExtSRAM */#ifdef SYSCLK_FREQ_HSE
/*** @brief  Selects HSE as System clock source and configure HCLK, PCLK2*          and PCLK1 prescalers.* @note   This function should be used only after reset.* @param  None* @retval None*/
static void SetSysClockToHSE(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 0 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);#ifndef STM32F10X_CLFLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
#elseif (HSE_VALUE <= 24000000){FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;}else{FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;}
#endif /* STM32F10X_CL */
#endif/* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;/* Select HSE as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE;    /* Wait till HSE is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}
#elif defined SYSCLK_FREQ_24MHz
/*** @brief  Sets System clock frequency to 24MHz and configure HCLK, PCLK2 *          and PCLK1 prescalers.* @note   This function should be used only after reset.* @param  None* @retval None*/
static void SetSysClockTo24(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){
#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 0 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
#endif/* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL6); /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */       RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);/* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)/*  PLL configuration:  = (HSE / 2) * 6 = 24 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6);
#else/*  PLL configuration:  = (HSE / 2) * 6 = 24 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}
#elif defined SYSCLK_FREQ_36MHz
/*** @brief  Sets System clock frequency to 36MHz and configure HCLK, PCLK2 *          and PCLK1 prescalers. * @note   This function should be used only after reset.* @param  None* @retval None*/
static void SetSysClockTo36(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 1 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;    /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9); /*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);/* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}#else/*  PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}
#elif defined SYSCLK_FREQ_48MHz
/*** @brief  Sets System clock frequency to 48MHz and configure HCLK, PCLK2 *          and PCLK1 prescalers. * @note   This function should be used only after reset.* @param  None* @retval None*/
static void SetSysClockTo48(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 1 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;    /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);/* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}/* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL6);
#else/*  PLL configuration: PLLCLK = HSE * 6 = 48 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}#elif defined SYSCLK_FREQ_56MHz
/*** @brief  Sets System clock frequency to 56MHz and configure HCLK, PCLK2 *          and PCLK1 prescalers. * @note   This function should be used only after reset.* @param  None* @retval None*/
static void SetSysClockTo56(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);/* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}/* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL7);
#else/* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7);#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}#elif defined SYSCLK_FREQ_72MHz
/*** @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2 *          and PCLK1 prescalers. * @note   This function should be used only after reset.* @param  None* @retval None*/
static void SetSysClockTo72(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);/* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9);
#else/*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}
#endif/*** @}*//*** @}*//*** @}*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
uartsend_use_int.c```c
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "stm32f10x_usart.h"
#include "misc.h"
#include "string.h"
#include "timer.h"
#include "test.h"#define TxBufferSize1   (countof(TxBuffer1) - 1)
#define RxBufferSize1   (countof(TxBuffer1) - 1)
#define countof(a)   (sizeof(a) / sizeof(*(a)))      //表示数组a中元素的个数 #ifndef true
#define true 1
#endif#ifndef false
#define false 0
#endif  typedef unsigned char uint8_t ;
uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO,SUCCESS\n";
uint8_t RxBuffer1[RxBufferSize1],rec_f;
uint8_t TxCounter1 = 0x00;
uint8_t RxCounter1 = 0x00;
uint8_t NbrOfDataToTransfer1 = TxBufferSize1;
uint8_t NbrOfDataToRead1 = RxBufferSize1;#define DEBUG_STRING "HELLO_WORLD\n"#ifndef TRUE
#define TRUE 1U
#endif
#ifndef FALSE
#define FALSE 0U
#endif//#define USE_NONBLOCK_USART
#ifndef USE_NONBLOCK_USART
//#define USE_BLOCK_USART
#endif#define BAUDRATE_115200 115200Utypedef struct
{u8 UartSendData_Indixcation;u8 local_uart_transmit_buf[50];}G_UART_Context_Var_t;G_UART_Context_Var_t  G_UART_Context_Var = {0};void Set_UartSendData_Indixcation(u8 status);
u8 Get_UartSendData_Indixcation(void);void Set_UartSendData_Indixcation(u8 status)
{G_UART_Context_Var.UartSendData_Indixcation = status;
}u8 Get_UartSendData_Indixcation(void)
{return G_UART_Context_Var.UartSendData_Indixcation;
}void bsp_init(u32 uart_baudrate)
{USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;//1 gpio init/* Enable USART1, GPIOA, GPIOD and AFIO clocks */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA , ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //USART1 TXGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);            //A端口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;            //USART1 RXGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用开漏输入GPIO_Init(GPIOA, &GPIO_InitStructure);               //A端口//2 open clockNVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//ÇÀÕ¼ÓÅÏȼ¶3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //×ÓÓÅÏȼ¶3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          //IRQͨµÀʹÄÜNVIC_Init(&NVIC_InitStructure);    //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷//3 init usart1/* Enable USART1, GPIOA, GPIOD and AFIO clocks */if((uart_baudrate) == 115200)USART_InitStructure.USART_BaudRate = uart_baudrate;elseUSART_InitStructure.USART_BaudRate =         USART_InitStructure.USART_BaudRate = uart_baudrate;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;      //设置奇校验时,通信出现错误USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;/* Configure the USART1 */USART_Init(USART1, &USART_InitStructure);/* Enable the USART Transmoit interrupt: this interrupt is generated when theUSART1 transmit data register is empty */ //USART_ITConfig(USART1, USART_IT_TXE, ENABLE);/* Enable the USART Receive interrupt: this interrupt is generated when theUSART1 receive data register is not empty *///USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//Usart1 NVIC ÅäÖÃ/* Enable USART1 */USART_Cmd(USART1, ENABLE);}void SoftTimer_Init(void)
{}/*串口中断服务程序*/
//void USART1_IRQHandler(void)
//{
//  //unsigned int i;
//  /*接收中断*/
//#if 0
//  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
//  {
//    /* Read one byte from the receive data register */
//    RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);
//    if(RxCounter1 == NbrOfDataToRead1)  //接收数据达到需要长度,则将数据复制到发送数组中,并置标志
//    {
//      /* Disable the USART1 Receive interrupt */
//      //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
//        for(i=0; i< RxCounter1; i++) TxBuffer1[i]  = RxBuffer1[i];
//        rec_f=1;
//        RxCounter1=0;
//        TxCounter1=0;
//        USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  //打开发送中断,这句是关键
//    }
//  }
//#endif
//
//  /*发送中断*/
//  if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
//  {
//#if 1
//    USART_SendData(USART1, TxBuffer1[TxCounter1++]);
//  Set_UartSendData_Indixcation(true);
//
//
//    if(TxCounter1 == NbrOfDataToTransfer1)//发送数据完成
//    {
//          TxCounter1 = 0;
//          Set_UartSendData_Indixcation(false);
//          //memset(TxBuffer1,0x0,sizeof(TxBuffer1));
//      USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //关闭发送中断
//    }
//#endif
//  }
//} #ifdef USE_BLOCK_USART
void Send_DebugData(char *p)
{   while((*p != '\0')){while (!(USART1->SR & USART_FLAG_TXE))          // wait for TX buffer to emptycontinue;                                  // also either WDOG() or swap()USART_SendData(USART1,*p);while((USART1->SR&0X40)==0);p++;}
}
#endifvoid Send_DebugData_UseNoBlock(char *p,u8 length)
{if((NULL == p) && (length > 50)){return;}if((TxCounter1 == 0) && (false == Get_UartSendData_Indixcation())){USART_ITConfig(USART1, USART_IT_TXE, ENABLE);}else{return;}
}int main(void)
{unsigned char cnt = 0;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//bsp_init(BAUDRATE_115200);delay_init();//Set_UartSendData_Indixcation(FALSE);LED_Init();TIM3_Int_Init(5000,7199);//test_uart_init();test_init();test_printf(1,"UART SEND use interrupt and ringbuffer V0\r\n");while (1){#ifdef USE_NONBLOCK_USARTSend_DebugData_UseNoBlock(TxBuffer1,sizeof(TxBuffer1));delay_ms(1000); #endif#ifdef USE_BLOCK_USARTdelay_ms(5000);if(FALSE == Get_UartSendData_Indixcation()){Send_DebugData(DEBUG_STRING);delay_ms(10000);USART_ITConfig(USART1, USART_IT_TXE, ENABLE);Set_UartSendData_Indixcation(TRUE);       }
#endifdelay_ms(500);LED0 = !LED0;if(cnt++ >= 65535){cnt = 0;}test_printf(1,"DEBUG INFO:cnt = %d\r\n",cnt); __asm("nop");}
}

ringbuf.c

//*****************************************************************************
// file     : ringbuf.c
//
// Copyright (c) 2011-2014 HUAWEI co. Ltd. All rights reserved
//
// Change Logs:
// Date             Author      Note
// 2015/04/02       chc
//
//*****************************************************************************//*****************************************************************************
//
//! \addtogroup
//! @{
//
//*****************************************************************************
#include "ringbuf.h"/*** \brief ** \param None*   * \return None*/
void ringbuf_init(tRingBuf *pRingBuf, unsigned char *pBuf, unsigned char size)
{pRingBuf->head = pRingBuf->tail = 0;pRingBuf->pBuf = pBuf;pRingBuf->size = size;
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_empty(tRingBuf *pRingBuf)
{return (pRingBuf->head == pRingBuf->tail);
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_full(tRingBuf *pRingBuf)
{return (((pRingBuf->tail + 1) % pRingBuf->size) == pRingBuf->head);
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_avail(tRingBuf *pRingBuf)
{return pRingBuf->size - pRingBuf->head + pRingBuf->tail;
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_size(tRingBuf *pRingBuf)
{return pRingBuf->size;
}/*** \brief Returns number of bytes stored in ring buffer.** \param None*   * \return None*/
unsigned char ringbuf_used(tRingBuf *pRingBuf)
{unsigned char tail, head;tail = pRingBuf->tail;head = pRingBuf->head;return((head >= tail) ? (head - tail) :(pRingBuf->size - (tail - head)));
}/*** \brief Returns number of bytes available in a ring buffer.** \param None*   * \return None*/
unsigned char ringbuf_free(tRingBuf *pRingBuf)
{return((pRingBuf->size - 1) - ringbuf_used(pRingBuf));
}/*** \brief ** \param None*   * \return None*/
void ringbuf_write_one(tRingBuf *pRingBuf, unsigned char data)
{if (ringbuf_avail(pRingBuf) != 0){pRingBuf->pBuf[pRingBuf->head] = data;pRingBuf->head++;if (pRingBuf->head >= pRingBuf->size){pRingBuf->head = 0;}}
}/*** \brief ** \param None*   * \return None*/
void ringbuf_write(tRingBuf *pRingBuf, unsigned char *pData, unsigned char len)
{unsigned char i;for (i = 0; i < len; i++){ringbuf_write_one(pRingBuf, pData[i]);}
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_read_one(tRingBuf *pRingBuf)
{unsigned char data;data = pRingBuf->pBuf[pRingBuf->tail++];if (pRingBuf->tail >= pRingBuf->size){pRingBuf->tail = 0;}return data;
}/*** \brief ** \param None*   * \return None*/
void ringbuf_read(tRingBuf *pRingBuf, unsigned char *pData, unsigned char len)
{unsigned char i;for (i = 0; i < len; i++){pData[i] = ringbuf_read_one(pRingBuf);}
}//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************//*****************************************************************************
// file     : ringbuf.c
//
// Copyright (c) 2011-2014 HUAWEI co. Ltd. All rights reserved
//
// Change Logs:
// Date             Author      Note
// 2015/04/02       chc
//
//*****************************************************************************//*****************************************************************************
//
//! \addtogroup
//! @{
//
//*****************************************************************************
#include "ringbuf.h"/*** \brief ** \param None*   * \return None*/
void ringbuf_init(tRingBuf *pRingBuf, unsigned char *pBuf, unsigned char size)
{pRingBuf->head = pRingBuf->tail = 0;pRingBuf->pBuf = pBuf;pRingBuf->size = size;
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_empty(tRingBuf *pRingBuf)
{return (pRingBuf->head == pRingBuf->tail);
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_full(tRingBuf *pRingBuf)
{return (((pRingBuf->tail + 1) % pRingBuf->size) == pRingBuf->head);
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_avail(tRingBuf *pRingBuf)
{return pRingBuf->size - pRingBuf->head + pRingBuf->tail;
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_size(tRingBuf *pRingBuf)
{return pRingBuf->size;
}/*** \brief Returns number of bytes stored in ring buffer.** \param None*   * \return None*/
unsigned char ringbuf_used(tRingBuf *pRingBuf)
{unsigned char tail, head;tail = pRingBuf->tail;head = pRingBuf->head;return((head >= tail) ? (head - tail) :(pRingBuf->size - (tail - head)));
}/*** \brief Returns number of bytes available in a ring buffer.** \param None*   * \return None*/
unsigned char ringbuf_free(tRingBuf *pRingBuf)
{return((pRingBuf->size - 1) - ringbuf_used(pRingBuf));
}/*** \brief ** \param None*   * \return None*/
void ringbuf_write_one(tRingBuf *pRingBuf, unsigned char data)
{if (ringbuf_avail(pRingBuf) != 0){pRingBuf->pBuf[pRingBuf->head] = data;pRingBuf->head++;if (pRingBuf->head >= pRingBuf->size){pRingBuf->head = 0;}}
}/*** \brief ** \param None*   * \return None*/
void ringbuf_write(tRingBuf *pRingBuf, unsigned char *pData, unsigned char len)
{unsigned char i;for (i = 0; i < len; i++){ringbuf_write_one(pRingBuf, pData[i]);}
}/*** \brief ** \param None*   * \return None*/
unsigned char ringbuf_read_one(tRingBuf *pRingBuf)
{unsigned char data;data = pRingBuf->pBuf[pRingBuf->tail++];if (pRingBuf->tail >= pRingBuf->size){pRingBuf->tail = 0;}return data;
}/*** \brief ** \param None*   * \return None*/
void ringbuf_read(tRingBuf *pRingBuf, unsigned char *pData, unsigned char len)
{unsigned char i;for (i = 0; i < len; i++){pData[i] = ringbuf_read_one(pRingBuf);}
}//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

test.c

//*****************************************************************************
// file     : test.c
// test module
// Copyright (c) 2011-2014 HUAWEI co. Ltd. All rights reserved
//
// Change Logs:
// Date             Author      Note
// 2014/01/21       chc
//
//*****************************************************************************//*****************************************************************************
//
//! \addtogroup
//! @{
//
//*****************************************************************************
#include "test.h"
#include "test_uart.h"
//#include "test_msgproc.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
//#include "UnitCheck\BattCheck.h"
//#include "SystemManage\SystemStateManage\SystemStateManage.h"
//#include "SoftTimer\Manage_SoftTimer.h"
//#include "CarSignalManage\CarSignalManage.h"
//#include "Debug_Uart.h"
//#include "MX51\MX51MsgProcess.h"//#define cmdMAX_INPUT_SIZE        128
//
//unsigned char cInputIndex = 0;
//static char cInputString[ cmdMAX_INPUT_SIZE ], cLastInputString[ cmdMAX_INPUT_SIZE ];
//
//
//unsigned char DEBUG_CanInfo = 0;      //CAN print
//unsigned char DEBUG_UartRec = 0;      //uart print
//unsigned char DEBUG_UartSend = 0;
//unsigned char DEBUG_ResendInfo = 0;   //Resend Print
//unsigned char DEBUG_KeyInfo = 0;
//
//unsigned char DEBUG_KernelInfo = 0;
//
//
//extern unsigned char gHeartEnableFlag;
//extern unsigned char Mx51_CurrentState;
//extern Type_SystemState G_SystemState;
//extern unsigned char AMP_MuteState;
//extern unsigned char AutoTestRecved;
//
//tPrintLevel s_printlevel;
static unsigned char AutoTestRecved = 0;/*** \brief ** \param None*   * \return None*/
void test_init(void)
{test_uart_init();
//  test_set_printlevel(TEST_PRINT_LEVEL_DEFAULT);
//  Debug_uart_init();
}/*** \brief ** \param None*   * \return None*/
//void test_set_printlevel(tPrintLevel level)
//{
//  s_printlevel = level;
//}/*** \brief ** \param None*   * \return None*/
//void test_process_per10ms(void)
//{
//  test_msgproc_rcvmsg();
//  test_rcv_timeout_process();
//}/*** \brief ** \param None*   * \return None*/
//void test_print_array(unsigned char *pByte, unsigned char len, tPrintLevel level)
//{
//  if (level >= s_printlevel)
//  {
//      test_uart_send(pByte, len);
//  }
//}/*** \brief ** \param None*   * \return None*/
void test_printf(unsigned char printFlags, const char *fmt, ...)
{if((printFlags == 1) && (AutoTestRecved == 0)) /*Ìí¼Ó×Ô¶¯²âÊÔ¼ìÑé*/{va_list args;unsigned char length;char buf[100];va_start(args, fmt);length = vsprintf(buf, fmt, args);// auto testÒѾ­ÓÃÁË´®¿Ú£¬¹Ê֮ǰ´òÓ¡ÆÁ±Î modify by kuan 2017Äê11ÔÂ20ÈÕ15:54:04test_uart_send((unsigned char *)buf, strlen(buf));va_end(args);}
}/******************************************************************************
** Function    : getConsoleData
** Description : debug uart
** Input       : None
** Output      : None
** Author      : xuany
** Date        : 20180202
*******************************************************************************/
//unsigned char getConsoleData(char* pBuf, char* returnbuf,unsigned char bufSize)
//{
//    unsigned char i = 0;
//    unsigned char iPos = 0;
//
//    for ( ; i < bufSize; i++)
//    {
//        if((*(pBuf + i) == ' ')||(*(pBuf + i) == '-')||(*(pBuf + i) == ':'))
//        {
//            break;
//        }
//        else
//        {
//            returnbuf[iPos ++] = *(pBuf + i);
//        }
//    }
//    returnbuf[iPos ++] = '\0'; /*end*/
//    return iPos;
//}//void  ConsoleDataInfo(char* pSourceBuf, char* pDestBuf)
//{
//  unsigned char  index =0,iPos = 0;
//  unsigned char  ConsoleStatus = 0;  /*open : 1   close : 0*/
//  unsigned char  ConfigVehicleBuf[5]= {0x00};
//  unsigned long  EEpromAddr = 0;
//  unsigned char  ReadEEpromBuf[9]= {0x00};
//  unsigned char  i = 0;
//
//  iPos = getConsoleData((char *)(pSourceBuf+index), (char *)pDestBuf, strlen(pSourceBuf)-index);/*open or close*/
//
//  if(strcmp(pDestBuf,"init") == 0)
//  {
//      test_printf(0,"error\r\n");
//  }
//
//  else if(strcmp(pDestBuf,"Open")==0)
//  {
//      ConsoleStatus = 1;
//  }
//  else if(strcmp(pDestBuf,"Close")==0)
//  {
//      ConsoleStatus = 0;
//  }
//  else if (strcmp(pDestBuf, "Reset") == 0)
//  {
//      SystemGotoRestart(5);
//  }
//
//  index += iPos;
//  iPos = getConsoleData((char *)(pSourceBuf+index), (char *)pDestBuf, strlen(pSourceBuf)-index);
//
//  if(strcmp(pDestBuf,"Can")==0)
//  {
//          if(ConsoleStatus)  DEBUG_CanInfo=1;
//          else               DEBUG_CanInfo=0;
//  }
//  else if(strcmp(pDestBuf,"UartRec")==0)
//  {
//      if(ConsoleStatus)  DEBUG_UartRec=1;
//      else               DEBUG_UartRec=0;
//  }
//  else if(strcmp(pDestBuf,"UartSend")==0)
//  {
//      if(ConsoleStatus)  DEBUG_UartSend=1;
//      else               DEBUG_UartSend=0;
//  }
//  else if(strcmp(pDestBuf,"Resend")==0)
//  {
//          if(ConsoleStatus)  DEBUG_ResendInfo=1;
//          else               DEBUG_ResendInfo=0;
//  }
//  else if(strcmp(pDestBuf,"Key")==0)
//  {
//          if(ConsoleStatus)  DEBUG_KeyInfo=1;
//          else               DEBUG_KeyInfo=0;
//  }
//  else if(strcmp(pDestBuf,"Heart")==0)/*Heart*/
//  {
//      if(ConsoleStatus)  gHeartEnableFlag = 1;
//      else               gHeartEnableFlag = 0;
//  }
//  else if(strcmp(pDestBuf,"Vat")==0)/*Battery*/
//  {
//      test_printf(1,"Vat:%d\r\n",sBattManage.ad_val);
//  }
//  else if(strcmp(pDestBuf,"ShakeHand")==0)/*ShakeHand*/
//  {
//      test_printf(1,"ShakeHand:%x,%x,%x,%x\r\n",Mx51_CurrentState,G_SystemState.CurrentState,AMP_MuteState,CarSignal_ACCState_Inquire());
//  }
//  else if(strcmp(pDestBuf,"Bsp")==0)
//  {
//      test_printf(1,"BspHeartCount:%d\r\n",ReceiveBspCount);
//  }
//  else if(strcmp(pDestBuf,"Kernel")==0)
//  {
//      DEBUG_KernelInfo = 1;
//  }
//}//void GetShellDada(unsigned char RcvedChar)
//{
//
///* Was it the end of the line? */
//  if( RcvedChar == '\n' || RcvedChar == '\r' )
//  {
//      /* Just to space the output from the input. */
//      test_printf(1,"\r\n");
//      test_printf(1,">");
//
//      /*analyze uart data*/
//      ConsoleDataInfo( ( char * ) cInputString, ( char * ) cLastInputString );
//
//      /* All the strings generated by the input command have been sent.
//      Clear the input string ready to receive the next command.  Remember
//      the command that was just processed first in case it is to be
//      processed again. */
//      cInputIndex = 0;
//      memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
//      memset( cLastInputString, 0x00, cmdMAX_INPUT_SIZE );
DebugUart_PutString(">");
//      /* xPrintf( pcEndOfOutputMessage ); */
//  }
//  else
//  {
//      if( RcvedChar == '\r' )
//      {
//          /* Ignore the character. */
//      }
//      else if( (RcvedChar == '\b') || ((RcvedChar == (char)127)) )
//      {   /* Key BackSpace Value is 127 from minicom */
//          /* Backspace was pressed.  Erase the last character in the
//          string - if any. */
//          if( cInputIndex > 0 )
//          {
//              cInputIndex--;
//              cInputString[ cInputIndex ] = '\0';
//              /* ease one char on the uart console */
//
//              test_printf(1,"\b");
//              test_printf(1," ");
//              test_printf(1,"\b");
//          }
//      }
//      else
//      {
//          /* A character was entered.  Add it to the string
//          entered so far.  When a \n is entered the complete
//          string will be passed to the command interpreter. */
//          if( ( RcvedChar >= ' ' ) && ( RcvedChar <= '~' ) )
//          {
//              /* Echo the character back. */
//              test_printf(1,"%c",RcvedChar);
//
//              if( cInputIndex < cmdMAX_INPUT_SIZE )
//              {
//                  cInputString[ cInputIndex ] = RcvedChar;
//                  cInputIndex++;
//              }
//          }
//      }
//  }
//}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

test_uart.c

//*****************************************************************************
// file     : test_uart.c
// process data communication with test
// Copyright (c) 2006-2012 HUAWEI co. Ltd. All rights reserved
//
// Change Logs:
// Date             Author      Note
// 2013/08/27       chc
//
//*****************************************************************************//*****************************************************************************
//
//! \addtogroup test
//! @{
//
//*****************************************************************************
#include "test_uart.h"
//#include "MX51\MX51Uart.h"
//#include "McuConfig_PinAssign.h"
//#include "driverlib\clock.h"
//#include "driverlib\uart.h"
//#include "platform\vectors.h"
#include "ringbuf.h"
#include "stm32f10x_usart.h"
#include "stm32f10x.h"#define TEST_TXD_BUF_LEN                   100//
//! receive buffer struct
//
typedef struct
{unsigned char buf[TEST_RCV_BUF_LEN]; /**< store the received data */unsigned char cnt;                        /**< receive data count */unsigned char len;                     /**< packet length */unsigned char state;                    /**< receive state */unsigned char timeout;                  /**< check if has timeout */
}
tTestRxBuf;//
//! send buffer struct
//
typedef struct
{unsigned char buf[TEST_TXD_BUF_LEN]; /**< store the transmitted data */unsigned char num;                     /**< number of byte to send */unsigned char cnt;                     /**< number of byte has sent */
}
tTestTxBuf;//
//! define receive buffer
//
static tTestRxBuf sTestRcvBuf;//
//! define tx buffer
//
static tTestTxBuf sTestTxdBuf;//
//! store the data to upper layer
//
tTestComBuf TestRcvBuf[TEST_RCV_NUM];//
//! tx ringbuf
//
tRingBuf s_tx_ringbuf;unsigned char AutoTestFlag = 0;//
//! tx buffer space
//
unsigned char tx_buf[TX_RINGBUF_SIZE];/*** \brief** \param None** \return None*/
void test_uart_init(void)
{
//    vector_SetIrq(ICR_LINT1, ILM_Level_5);
//    vector_SetIrq(ICR_LINR1, ILM_Level_5);bsp_init(115200);//    UART_Open(1,
//              BR_115200,
//              DATA_LEN_8BIT,
//              STOP_BIT_1,
//              PARITY_NONE);
//
//    UART_SetRxInterrupt(1, 1);ringbuf_init(&s_tx_ringbuf, tx_buf, TX_RINGBUF_SIZE);
}/*** \brief** \param None** \return None*/
unsigned char test_uart_send(unsigned char *pData, unsigned char len)
{if (ringbuf_free(&s_tx_ringbuf) < len){return 0;}//UART_SetTxInterrupt(1, 0);USART_ITConfig(USART1, USART_IT_TXE, DISABLE);ringbuf_write(&s_tx_ringbuf, pData, len);//UART_SetTxInterrupt(1, 1);USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}/*** \brief** \param None** \return None*/
int test_uart_checkbuf(unsigned char state)
{int i;for (i = 0; i < TEST_RCV_NUM; i++){if (TestRcvBuf[i].newflag == state){return i;}}return -1;
}/*** \brief** \param None** \return None*/
void test_uart_bufset(unsigned char idx, unsigned char state)
{TestRcvBuf[idx].newflag = state;
}/*** \brief** \param None** \return None*/
void test_uart_fillbuf(unsigned char *pSrc, unsigned char len, unsigned char idx)
{unsigned char i;for (i = 0; i < len; i++){TestRcvBuf[idx].buf[i] = pSrc[i];}TestRcvBuf[idx].newflag = 1;
}/*** \brief** \param None** \return None*/
unsigned char * test_uart_getbuf(unsigned char idx)
{unsigned char *pBuf;pBuf = TestRcvBuf[idx].buf;return pBuf;
}/*** \brief** \param None** \return None*/
//__interrupt void test_rcv_isr(void)
//{
//    unsigned char rb;
//
//    sTestRcvBuf.timeout   = 5;
//
//    if(UART1_SSR1_ORE == 1 || UART1_SSR1_FRE == 1 || UART1_SSR1_PE == 1)
//    {
//        UART1_SCR1_CRE = 1;
//    }
//    else
//    {
//        rb = UART1_RDR1;
//
//        switch(sTestRcvBuf.state)
//        {
//        case 0: // head flag check
//            if(rb == 0xAA)
//            {
//                AutoTestFlag = 1; // auto test command
//                sTestRcvBuf.state = 1;
//                sTestRcvBuf.cnt = 0;
//                sTestRcvBuf.buf[sTestRcvBuf.cnt++] = rb;
//            }
//       else
//           {
//               AutoTestFlag = 0;
//           }
//            break;
//
//        case 1:       // Frame Counter
//            //airRcvPnt       =   0;
//            sTestRcvBuf.buf[sTestRcvBuf.cnt++] = rb;
//            sTestRcvBuf.state = 2;
//            break;
//
//        case 2:       //package length
//            if(sTestRcvBuf.cnt < TEST_RCV_BUF_LEN)
//            {
//                sTestRcvBuf.buf[sTestRcvBuf.cnt++] = rb;
//            }
//            else      // package's length is too long
//            {
//                sTestRcvBuf.state = 0;
//            }
//
//            if(rb <= (TEST_RCV_BUF_LEN - 3))
//            {
//                sTestRcvBuf.state = 3;
//            }
//            else
//            {
//                sTestRcvBuf.state = 0;
//            }
//            break;
//
//        case 3:       // data field
//
//            sTestRcvBuf.buf[sTestRcvBuf.cnt++] = rb;
//            if(sTestRcvBuf.cnt >= (sTestRcvBuf.buf[2] + 3))    //check sum
//            {
//                int bufIdx =test_uart_checkbuf(0);
//
//                if(bufIdx >= 0)
//                {
//                    test_uart_fillbuf(sTestRcvBuf.buf, sTestRcvBuf.buf[2]+3, bufIdx);
//                }
//                sTestRcvBuf.timeout = 0;//Õý³£½ÓÊÕÕýÈ·
//                sTestRcvBuf.state =   0;
//                sTestRcvBuf.cnt   =   0;
//            }
//            break;
//
//        default:
//            sTestRcvBuf.state = 0;
//            break;
//        }
//  if(AutoTestFlag != 1) // filter 0x0A and 0x0D
//  {
//      GetShellDada(rb);
//  }
//    }
//}/*** \brief** \param None** \return None*/
//__interrupt void test_snd_isr(void)
//{
//    if (ringbuf_empty(&s_tx_ringbuf))
//    {
//        UART_SetTxInterrupt(1, 0);
//    }
//    else
//    {
//        UART1_TDR1 = ringbuf_read_one(&s_tx_ringbuf);
//    }
//}void USART1_IRQHandler(void)
{if (ringbuf_empty(&s_tx_ringbuf)){//UART_SetTxInterrupt(1, 0);USART_ITConfig(USART1, USART_IT_TXE, DISABLE);}else{//UART1_TDR1 = ringbuf_read_one(&s_tx_ringbuf);if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET){USART_SendData(USART1, ringbuf_read_one(&s_tx_ringbuf));}}
}/*** \brief** \param None** \return None*/
void test_rcv_timeout_process(void)
{if(sTestRcvBuf.timeout > 0){sTestRcvBuf.timeout--;if(sTestRcvBuf.timeout == 1){sTestRcvBuf.state = 0;sTestRcvBuf.cnt = 0;sTestRcvBuf.timeout  =   0;}}
}//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

led.c

#include "led.h"//
//±¾³ÌÐòÖ»¹©Ñ§Ï°Ê¹Óã¬Î´¾­×÷ÕßÐí¿É£¬²»µÃÓÃÓÚÆäËüÈκÎÓÃ;
//ALIENTEK mini¢SSTM32¿ª·¢°å
//LEDÇý¶¯´úÂë
//ÕýµãÔ­×Ó@ALIENTEK
//¼¼ÊõÂÛ̳:www.openedv.com
//ÐÞ¸ÄÈÕÆÚ:2012/9/2
//°æ±¾£ºV1.0
//°æȨËùÓУ¬µÁ°æ±Ø¾¿¡£
//Copyright(C) ¹ãÖÝÊÐÐÇÒíµç×ӿƼ¼ÓÐÏÞ¹«Ë¾ 2009-2019
//All rights reserved
////³õʼ»¯PB5ºÍPE5ΪÊä³ö¿Ú.²¢Ê¹ÄÜÕâÁ½¸ö¿ÚµÄʱÖÓ
//LED IO³õʼ»¯

注意:主函数位于uartsend_use_int.c。先bsp_init,然后就可以调用test_printf了,岂不妙哉,不占用宝贵的cpu资源。

五、后记

本文章简要记录基于stm32单片机实现串口非阻塞打印的的全过程,并附带图片以及代码片。因为时间和篇幅有限,秉着开源的精神,特此把代码工程的压缩包一并上传。防止有同学移植困难,解压缩直接编译。在csdn搜索“使用非阻塞方式实现串口打印,stm32f103rct6”,这个资源下载设置的0积分。如果找不到,发函qp_linux_mcu@163.com.有感兴趣的欢迎留言、转发、评论收藏。QQ:1066312378欢迎技术交流合作,you know。

————————————————
版权声明:本文为CSDN博主「qp_12」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qp_12/article/details/117264618

基于STM32F103RCT6实现串口中断发送,使用环形队列相关推荐

  1. 【HAL库】STM32F407ZGT6实现串口中断发送和接收

    ** [HAL库]STM32F407ZGT6实现串口中断发送和接收 (保姆级教写代码1) ** 前言 根据近期所做的项目,想给大家分享一些有关STM32的各类通信方式的代码教程,都是基于STM32HA ...

  2. STM32G070RBT6基于STM32CubeMX创建串口中断接收数据

    STM32G070RBT6基于STM32CubeMX创建串口中断接收数据

  3. ucos-iii串口用信号量及环形队列中断发送,用内建消息队列中断接收

    串口发送部分代码: //通过信号量的方法发送数据 void usart1SendData(CPU_INT08U ch) {OS_ERR err;CPU_INT08U isTheFirstCh;OSSe ...

  4. DSP在SYS/BIOS下串口(UART)接收之环形队列

    众所周知串口收/发数据是以字节为单位的位传输通信协议. 当串口接收数据按固定数据长度接收:则可能会由于传输过程中出现丢数据,发送端少发数据或多发数据导致接收错位无法正确获取数据. 为了解决数据接收错位 ...

  5. 1-关于单片机通信数据传输(中断发送,大小端,IEEE754浮点型格式,共用体,空闲中断,环形队列)

    补充: 程序优化 为避免普通发送和中断发送造成冲突(造成死机,复位重启),printf修改为中断发送 写这篇文章的目的呢,如题目所言,我承认自己是一个程序猿.....应该说很多很多学单片机的对于... ...

  6. 8051单片机的中断发送

    最近使用c8051做开发,串口程序移入工程时,整个程序竟然不跑了,加断点,调试,发现在串口查询发送出了问题,程序在查询发送完毕的时候,竟然死在这,就是while(TI0==0)这地方,用其它型号单片机 ...

  7. GD32F303RET6 串口空闲中断+DMA数据发送接收+环形缓冲区方式保存数据

    GD32F303RET6 DMA 通道映射关系 串口 源文件 #include "uart.h" #include "stdio.h" #include &qu ...

  8. FPGA 串口中断_一个严谨的STM32串口DMA发送amp;接收(1.5Mbps波特率)机制

    昨天分享的<嵌入式大杂烩读者福利:第一期>大家有去抽奖吗,没抽的可参与抽奖,碰碰运气.我最喜欢抽奖了,还记得前几个月疫情严重时期连抽中了3包口罩,真刺激,哈哈.之后多多安排抽奖,敬请期待. ...

  9. 单片机实现环形队列_单片机模块化程序: 难道有环形队列串口发送数据就万事大吉了吗...

    1.问个问题,下面程序有没有BUG数组 2.环形队列虽然解决了一开始的中断发送数据覆盖问题,可是呢却引入了新的问题函数 3.而后看看中断发送测试 4.想没想明白是什么问题spa 5.发送数据1 和发送 ...

最新文章

  1. R语言ggplot2可视化在可视化图形的X轴标签中添加温度摄氏度符号(add temperature degree symbol on axis label)
  2. 《统一沟通-微软-技巧》-20-Lync 2010如何在我的联系人列表中添加非联盟联系人...
  3. 为何Java中子类重写方法的访问权限不能低于父类中权限
  4. 【汇总篇】如何利用Excel高效地处理数据
  5. <scope>test</scope>的作用
  6. whatpulse.exe 启动时报错
  7. 如何在 Asp.Net Core 实现 Excel 导出功能
  8. dao.php,DAO.php · Dodd/Training Lab - Gitee.com
  9. 什么是我想要守护的东西?
  10. pcs7服务器一直显示在同步,西门子PCS7OS系统时钟同步出现跳变的解决方法
  11. java pdf 页面 拼接_如何使用Java平铺PDF文档中的页面内容?
  12. 初中毕业学修车还是学计算机,儿子初中毕业了,成绩不好,想学门手艺谋生,去技校,还是去店里做学徒好?学修车吗?...
  13. 领导人怎样带领好团队
  14. 红米note3全网通(kenzo)非官方解锁
  15. html级联选择器,jquery实现 级联选择器
  16. Marvell 88E1111 百兆工程 (FPGA)
  17. 数学之美—细数 傅里叶变换 原理
  18. word骨灰级水平,赶紧留一份.
  19. 期货市场的投资者适当性原则
  20. 德鲁克:CEO必须秉持的六项原则

热门文章

  1. 插件GsonFormat快速实现JavaBean
  2. KS检验样本测试集和训练集分布问题
  3. 机器学习——线性模型之Softmax回归
  4. 连自律都做不到 还谈什么梦想
  5. 【opencv】二维面找角点/关键点 实现
  6. 基于FPGA的嵌入式图像处理笔记——图像增强的特例(图像反转)
  7. 如何在线翻译整篇PDF论文?
  8. r语言抓取维基百科表格数据
  9. The last update operation tried to add the file 'xxx.java',but the file already exists universioned
  10. python期末大作业_上海交通大学python期末大作业题目(姚天昉)