| RT,相关说明都是在工程内部。 /**
 ******************************************************************************
 * @file    USART.h
 * @author
 * @version 0.1
 * @date    1-Dec-2012
 * @brief
 ******************************************************************************
 * @attention
 *
 *
 *
 ******************************************************************************
 */
 
 /** @addtogroup User
 * @{
 */
 
 /**
 * @brief Define to prevent recursive inclusion
 */
 #ifndef __USART_H
 #define __USART_H
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include "stm32f10x.h"
 
 #define USEUSART2
 
 #define USART_BufferChannel 8
 #define USART_BufferChannelVal  0x1<<(USART_BufferChannel-1)
 
 #define USART_BufferLength 512
 
 
 /* 整个结构体对内核而言都是只读的,内核不能进行任何写操作 */
 typedef struct
 {
 /* 表示当前通道数据准备完成,可以被CPU读出 */
 /* EG. 0x1表示通道1数据可读,0x2表示通道2数据可读,0X4表示通道3数据可读 */
 
 uint32_t RecBufChaRdy;
 
 /* 表示当前通道是否被选中作为注入通道 */
 /* EG.0x4,表示被选中的是通道3 */
 
 uint32_t RecBufPingPang;
 
 /* 表示该通道由于硬件原因导致数据错误 */
 
 uint32_t RecBufChaErr;
 
 /* 数据溢出,标志为READY的通道未在规定的时间移出,而新的数据需要使用该通道。*/
 
 ErrorStatus RecBufOverFlow;
 
 /* 缓冲区 */
 uint8_t RecBuf[USART_BufferChannel][USART_BufferLength];
 
 uint16_t RecBufValLen[USART_BufferChannel];
 } USARTRecBufDef;
 
 #if defined USEUSART1
 extern USARTRecBufDef USART1Buf;
 #endif
 #if defined USEUSART2
 extern USARTRecBufDef USART2Buf;
 #endif
 #if defined USEUSART3
 extern USARTRecBufDef USART3Buf;
 #endif
 #if defined USEUART4
 extern USARTRecBufDef UART4Buf;
 #endif
 #if defined USEUART5
 extern USARTRecBufDef UART5Buf;
 #endif
 
 
 void StdPeriphUSART1Init(void);
 void StdPeriphUSART2Init(void);
 void StdPeriphUSART3Init(void);
 void StdPeriphUART4Init(void);
 void StdPeriphUART5Init(void);
 
 void USART1_IRQHandler(void);
 void USART2_IRQHandler(void);
 void USART3_IRQHandler(void);
 void UART4_IRQHandler(void);
 void UART5_IRQHandler(void);
 /* Private define ------------------------------------------------------------*/
 /* Private typedef -----------------------------------------------------------*/
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 #ifdef __cplusplus
 }
 #endif
 
 #endif /*__USART_H */
 
 /**
 * @}
 */
 
 /**
 * @}
 */
 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
 
 
 /**
 ******************************************************************************
 * @file    usart.c
 * @author  Author
 * @version V0.1
 * @date    01-DEC-2012
 * @brief   usart LIB body
 ******************************************************************************
 * @attention: 接受未知长度的数据,只有一个起点,即串口数据接受中断,在此函数中
 *             初始化DMA开始传输。终点无非两个,一,DMA没有接受完成,串口进入总
 *             线空闲中断,在空闲中断中获取收到的数据量,然后结束DMA传输,二,
 *             DMA接受完成,进入DMA接收完成中断,关闭DMA接收。
 *             在其中涉及到了各种中断的切换,一,触发串口接收中断后,关串口接收
 *             中断,打开串口总线空闲中断和DMA传输完成中断。二,进入DMA完成中断
 *             后,关闭总线空闲中断,打开串口接收中断,准备下一次接收,同时结束
 *             本次DMA传输。三,如果进入了总线空闲中断,打开串口接收中断,准备
 *             下一次接收,同时结束本次DMA传输。
 *             考虑到HEX数据流,缓冲结构体内引入了指示有效数据长度的变量。
 *             缓冲结构体内引入了乒乓操作,数据被依次注入到结构体中的缓冲数组内
 *             。同时为了指示通道的可读性,引入了标志位。结构体内的标志位对CPU
 *             来说都是“只读”的,修改将导致错误。
 ******************************************************************************
 */
 
 /* Includes ------------------------------------------------------------------*/
 #include "USART.h"
 #include "DMA.h"
 /** @addtogroup User
 * @{
 */
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 
 /******************************************************************************/
 /*         USART OR UART on board initialization and Exception Handler        */
 /******************************************************************************/
 
 USARTRecBufDef  USART2Buf = { 0,1,0,SUCCESS,{{0}} };
 
 /**
 * @brief  StdPeriphUSART2Init program.
 * @param  None
 * @retval None
 */
 void StdPeriphUSART2Init(void)
 {
 GPIO_InitTypeDef GPIO_InitStructure;
 USART_InitTypeDef USART_InitStructure;
 /* Enable CLK */
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
 
 /* Configurate GPIO */
 /* Configurate GPIOA_PIN9 as TX pin of USART2 */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
 GPIO_InitStructure.GPIO_Speed        = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_Init(GPIOA,&GPIO_InitStructure);
 /* Configurate GPIOA_PIN10 as RX pin of USART2 */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
 GPIO_InitStructure.GPIO_Speed        = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;;
 GPIO_Init(GPIOA,&GPIO_InitStructure);
 
 /* USART2 Initil        */
 USART_InitStructure.USART_BaudRate = 115200;
 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;
 USART_Init(USART2,&USART_InitStructure);
 
 USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
 USART_ClearFlag(USART2,USART_FLAG_RXNE);
 USART_ClearFlag(USART2,USART_FLAG_TC);
 
 USART_DMACmd(USART2,USART_DMAReq_Tx|USART_DMAReq_Rx,ENABLE);
 
 USART_Cmd(USART2,ENABLE);
 }
 /**
 * @brief  This function handles USART2 interrupt request.
 * @param  None
 * @retval None
 */
 void USART2_IRQHandler(void)
 {
 uint16_t index=0;
 uint16_t buffer=0;
 if(USART_GetITStatus(USART2,USART_IT_RXNE))
 {
 /* 清除中断挂起 */
 USART_ClearITPendingBit(USART2,USART_IT_RXNE);
 /* 屏蔽接收中断,开启IDLE中断 */
 USART_ITConfig(USART2,USART_IT_RXNE,DISABLE);
 USART_ITConfig(USART2,USART_IT_IDLE,ENABLE);
 /* 初始化DMA接受数据 */
 StdPeriphDMA1Channel6Init();
 }
 else if(USART_GetITStatus(USART2,USART_IT_IDLE))
 {
 /* 清除中断挂起 */
 USART_ClearITPendingBit(USART2,USART_IT_IDLE);
 /* 接收完成,恢复接收中断,准备下一次接受 */
 USART_ITConfig(USART2,USART_IT_IDLE,DISABLE);
 USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
 
 /* 获取当前通道号 */
 while(USART2Buf.RecBufPingPang>>index!=0)
 index++;
 /* 获取当前通道号的剩余空间 */
 buffer=DMA_GetCurrDataCounter(DMA1_Channel6);
 
 /* 设置新数据的长度 */
 USART2Buf.RecBufValLen[index-1] = USART_BufferLength-buffer;
 /* 将当前通道号设置可读 */
 USART2Buf.RecBufChaRdy |= USART2Buf.RecBufPingPang;
 /* 停止DMA传输 */
 DMA_DeInit(DMA1_Channel6);
 }
 }
 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
 /**
 ******************************************************************************
 * @file    dma.c
 * @author  Author
 * @version V0.1
 * @date    01-DEC-2012
 * @brief   usart LIB body
 ******************************************************************************
 * @attention:乒乓操作位总是指向被注入的通道,当该通道被选中注入后,通道可读被
 *             复位,直到在DMA接受中断和IDLE中断中结束本次传输后,会重新被设置
 *             可读。乒乓操作位,总是在DMA接收完成中断中被移位,指向下一个通道。
 *
 *
 ******************************************************************************
 */
 
 /* Includes ------------------------------------------------------------------*/
 #include "DMA.h"
 #include "USART.h"
 /** @addtogroup User
 * @{
 */
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 
 /******************************************************************************/
 /*         DMA Initialization and Exception Handler        */
 /******************************************************************************/
 /**
 * @brief  StdPeriphDMA1Channel6Init program.
 * @param  None
 * @retval None
 */
 void StdPeriphDMA1Channel6Init(void)
 {
 uint16_t index = 0;
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 DMA_InitTypeDef DMA_InitStructure;
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 /* 分配注入通道,确定通道内的剩余空间 */
 {
 /* 获取当前通道号 */
 while(USART2Buf.RecBufPingPang>>index!=0)
 index++;
 /* 将当前通道号置忙 */
 USART2Buf.RecBufChaRdy &= ~USART2Buf.RecBufPingPang;
 /* 如果当前通道是正在使用的通道,继续注入数据,如果是过期通道清空数据*/
 if(USART2Buf.RecBufValLen[index-1] == USART_BufferLength)
 USART2Buf.RecBufValLen[index-1]=0;
 else
 USART2Buf.RecBufValLen[index-1]=USART2Buf.RecBufValLen[index-1];
 }
 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2Buf.RecBuf[index-1]+ (uint32_t)USART2Buf.RecBufValLen[index-1];
 DMA_InitStructure.DMA_BufferSize = USART_BufferLength - (uint32_t)USART2Buf.RecBufValLen[index-1];
 
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
 DMA_InitStructure.DMA_PeripheralBaseAddr = USART2_BASE + 0X04;
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
 DMA_Init(DMA1_Channel6,&DMA_InitStructure);
 DMA_ITConfig(DMA1_Channel6,DMA_IT_TC,ENABLE);
 DMA_Cmd(DMA1_Channel6,ENABLE);
 }
 /**
 * @brief  DMA1_Channel6 Exception Handler.
 * @param  None
 * @retval None
 */
 void DMA1_Channel6_IRQHandler(void)
 {
 uint16_t index = 0;
 if(DMA_GetITStatus(DMA1_IT_TC6))
 {
 /* 清除中断挂起 */
 DMA_ClearITPendingBit(DMA1_IT_TC6);
 
 /* 获取当前通道号 */
 while(USART2Buf.RecBufPingPang>>index!=0)
 index++;
 /* 当前的通道号存储结束,设置有效数据大小 */
 USART2Buf.RecBufValLen[index-1] = USART_BufferLength;
 /* 将当前通道号设置可读 */
 USART2Buf.RecBufChaRdy |= USART2Buf.RecBufPingPang;
 /* 指向下一个通道号 */
 if(USART2Buf.RecBufPingPang==USART_BufferChannelVal)
 USART2Buf.RecBufPingPang=0x1;
 else
 USART2Buf.RecBufPingPang<<=0x1;
 DMA_DeInit(DMA1_Channel6);
 /* 关闭IDLE中断,打开接收中断,为下一次数据准备,如果产生DMA传输中断的同时*/
 /* 又触发了总线空闲中断,即,通道填满后数据流恰好结束 ,如果不禁止IDLE中断*/
 /* 就会发生两次接收结束,两个函数都处理了数据就会导致错误 */
 USART_ITConfig(USART2,USART_IT_IDLE,DISABLE);
 USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
 }
 }
 
 
 
 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
 
 /**
 ******************************************************************************
 * @file    NVIC.c
 * @author  Author
 * @version V0.1
 * @date    02-DEC-2012
 * @brief   usart LIB body
 ******************************************************************************
 * @attention
 *
 *
 *
 *
 ******************************************************************************
 */
 
 /* Includes ------------------------------------------------------------------*/
 #include "NVIC.h"
 
 /** @addtogroup User
 * @{
 */
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 
 /******************************************************************************/
 /*                              NVIC Initialization                           */
 /******************************************************************************/
 void StdPeriphNVICInit(void)
 {
 NVIC_InitTypeDef NVIC_InitStructure;
 
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
 
 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_Init(&NVIC_InitStructure);
 
 
 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn ;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 14;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_Init(&NVIC_InitStructure);
 }
 
 
 
 
 
 
 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
 
 /**
 ******************************************************************************
 * @file    main.c
 * @author  MCD Application Team
 * @version V3.5.0
 * @date    08-April-2011
 * @brief   Main program body
 ******************************************************************************
 * @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>© COPYRIGHT 2011 STMicroelectronics</center></h2>
 ******************************************************************************
 */
 
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f10x.h"
 #include <stdio.h>
 #include <string.h>
 
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
 #include "USART.h"
 #include "DMA.h"
 #include "NVIC.h"
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 
 /**
 * @brief  Main program.
 * @param  None
 * @retval None
 */
 int main(void)
 {
 SystemInit(); /* If the hse can not startup successful,you can add your code in the end of this function.*/
 /* Add your application code here */
 
 StdPeriphUSART2Init();
 StdPeriphNVICInit();
 
 
 /* Infinite loop */
 while (1)
 {
 }
 }
 /**
 * @brief
 * @param
 * @retval
 */
 
 #ifdef  USE_FULL_ASSERT
 
 /**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
 void assert_failed(uint8_t* file, uint32_t line)
 {
 /* User can add his own implementation to report the file name and line number,
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
 /* Infinite loop */
 while (1)
 {
 }
 }
 #endif
 
 /**
 * @}
 */
 
 
 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
 
 |