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****/
|