DMA+Usart1的stm32f103收发实验-接收不定长数据

这个实验的时间比上一篇笔记早,非常粗糙,但是能用。

板子是淘宝上买的那种40米左右的f103rct6的板子,根据http://t.csdnimg.cn/P7JiC 上的内容写的,原作者应该是这位佬http://t.csdnimg.cn/ZxPzx

有些用不上的代码,没有删除,运行出错仅需删除无用代码即可运行

fifo.c/h

#include "fifo.h"
#include "usart.h"
/*********************************            变量声明部分             *********************************/

/*********************************            主要函数部分             *********************************/
static void fifo_lock(void)
{
    __disable_irq();             //cpu不响应中断
}


static void fifo_unlock(void)
{
    __enable_irq();
}



uint16_t fifo_receive(Fifo_InitTypeDef* rxfifo, Buff_InitTypeDef* rxbuff, uint16_t size)
{
	uint16_t countsize= 0,free_size = 0;
	if (size==0)
	{
		return 0;     //有效写入rxfifo的数据为0
	}

    free_size = rxfifo->fifo_size-rxfifo->fifo_occupy_size;
    if(free_size == 0)
    {
        return 0;   //剩余空间为0,有效写入rxfifo的数据为0
    }

    if(free_size < size)
    {
        size = free_size;   //若剩余空间不足写入size大小的数据,则实际写入数据量为free_size
    }
	countsize = size;    
        fifo_lock();       //锁住fifo
	while(countsize-- > 0)
	{
		{
		   		*rxfifo->fifo_tailptr = *rxbuff->buff_headptr;  	  	
                rxfifo->fifo_tailptr++;rxbuff->buff_headptr++;
		        rxfifo->fifo_occupy_size++;
			    rxbuff->buff_handle_size--;
		}//将DMArxbuff的值挨个写入rxfifo中
		if (rxfifo->fifo_tailptr ==&rxfifo->fifo[rxfifo->fifo_size]) 
		{
			rxfifo->fifo_tailptr = rxfifo->fifo;
		}
		if (rxbuff->buff_headptr ==&rxbuff->buff[rxbuff->buff_size]) 
		{
			rxbuff->buff_headptr = rxbuff->buff;
		}
	}
        fifo_unlock();
	return size;
}


uint16_t fifo_send(Fifo_InitTypeDef* txfifo, Buff_InitTypeDef* txbuff, uint16_t size)
{
	uint16_t countsize = 0;
	
	if (size==0)
	{
		return 0;     //有效写入DMAtxbuff的数据为0
	}
    if(txfifo->fifo_occupy_size == 0)
    {
        return 0;   //有效数据为0,有效写入DMAtxbuff的数据为0
    }
    if(txfifo->fifo_occupy_size < size)
    {
        size = txfifo->fifo_occupy_size;   //若有效数据少于写入size,则实际写入数据量为txfifo_occupy_datasize
    }
	countsize = size;    
        fifo_lock();       //锁住fifo
	while(countsize-- > 0)
	{
		{
		   		*txbuff->buff_tailptr = *txfifo->fifo_headptr;

				txbuff->buff_tailptr++; txfifo->fifo_headptr++;
				txfifo->fifo_occupy_size--;
			    txbuff->buff_handle_size++;
		}//将txfifo的值挨个写入DMATXbuff中
		if (txfifo->fifo_headptr ==&txfifo->fifo[txfifo->fifo_size]) 
		{
			txfifo->fifo_headptr = txfifo->fifo;
		}
		if (txbuff->buff_tailptr == &txbuff->buff[txbuff->buff_size])
		{
			txbuff->buff_tailptr = txbuff->buff;
		}
	}
        fifo_unlock();
	return size;
}



uint16_t get_fifo_occupy_size(Fifo_InitTypeDef* fifo)
{
    return fifo->fifo_occupy_size;
}

uint16_t get_buff_handle_size(Buff_InitTypeDef* buff,uint8_t DMA_RX_TX_STATUS)
{
	if(DMA_RX_TX_STATUS==TX)
	{
        buff->buff_handle_size=0;
		return 0;
	}
	else
    {
		return buff->buff_handle_size;
    }
}




#ifndef _FIFO_H
#define _FIFO_H

#include "stm32f10x.h"


#ifdef __cplusplus
extern "C"
{
#endif

	
	     
#define  FIFOSIZE                              (uint16_t)4096
#define  RXBUFFSIZE                            (uint16_t)4096
#define  TXBUFFSIZE                            (uint16_t)2048
	
#define  RX                                    (uint8_t)1	
#define  TX                                    (uint8_t)0
	
typedef struct
{
	uint8_t *fifo;      	    /* 缓冲区 */
	uint16_t fifo_size;    	    /* 缓冲区大小 */
    uint16_t fifo_occupy_size;       /* 有效数据大小 */
	uint8_t *fifo_headptr;      	    /* 读指针 */
	uint8_t *fifo_tailptr;       	/* 写指针 */
}Fifo_InitTypeDef;

typedef struct
{
	uint8_t *buff;      	    /* 缓冲区 */
	uint16_t buff_size;    	    /* 缓冲区大小 */
    uint16_t buff_handle_size;       /* 待处理的数据大小 */
	uint8_t *buff_headptr;      	    /* 读指针 */
	uint8_t *buff_tailptr;       	/* 写指针 */
}Buff_InitTypeDef;	
	
	
	

uint16_t fifo_receive(Fifo_InitTypeDef* rxfifo, Buff_InitTypeDef* rxbuff, uint16_t size);	
uint16_t fifo_send(Fifo_InitTypeDef* txfifo, Buff_InitTypeDef* txbuff, uint16_t size);
uint16_t get_fifo_occupy_size(Fifo_InitTypeDef* fifo);
uint16_t get_buff_handle_size(Buff_InitTypeDef* buff,uint8_t DMA_RX_TX_STATUS);


#ifdef __cplusplus
}
#endif

#endif /*_FIFO_H*/



usart1_TxRx_dma.c/h

#include "usart1_TxRx_dma.h"
#include "fifo.h"



/*********************************            变量声明部分             *********************************/  
   	static uint8_t	tx_flag=0;
    static uint8_t  IT_FLAG=0;
	static uint8_t  fifoarray[FIFOSIZE] ;
	static uint8_t  DMARXbuff[RXBUFFSIZE];
	static uint8_t  DMATXbuff[TXBUFFSIZE];
	static Fifo_InitTypeDef  fifo;
	static Buff_InitTypeDef  rxbuff;
	static Buff_InitTypeDef  txbuff;
/*********************************            中断函数配置部分             *********************************/
static void DMARX_NVIC_Configuration(void)
{
    NVIC_InitTypeDef  NVIC_InitStructure1;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure1.NVIC_IRQChannel = DMA1_Channel5_IRQn;				//NVIC通道设置
	NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 3 ;				//抢占优先级
	NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 0;						//子优先级
	NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;							//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure1);		
}

static void DMATX_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure2;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure2.NVIC_IRQChannel = DMA1_Channel4_IRQn;				//NVIC通道设置
	NVIC_InitStructure2.NVIC_IRQChannelPreemptionPriority = 3 ;				//抢占优先级
	NVIC_InitStructure2.NVIC_IRQChannelSubPriority = 0;						//子优先级
	NVIC_InitStructure2.NVIC_IRQChannelCmd = ENABLE;							//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure2);		
}
/*********************************            配置函数部分             *********************************/

static void Fifo_Init(Fifo_InitTypeDef* fifo,uint8_t* fifoaddr,uint16_t fifosize)
{
	fifo->fifo             = fifoaddr;
	fifo->fifo_size        = fifosize;
	fifo->fifo_occupy_size = 0;
	fifo->fifo_headptr     = fifoaddr;
	fifo->fifo_tailptr     = fifoaddr;
}

static void DMABuff_Init(Buff_InitTypeDef* buff,uint8_t* buffaddr,uint16_t buffsize)
{
	buff->buff             = buffaddr;
	buff->buff_size        = buffsize;
	buff->buff_handle_size = 0;
	buff->buff_headptr     = buffaddr;
	buff->buff_tailptr     = buffaddr;
}

void Device_Init(void)
{
	Fifo_Init(&fifo,fifoarray,FIFOSIZE);
	DMABuff_Init(&rxbuff,DMARXbuff,RXBUFFSIZE);
	DMABuff_Init(&txbuff,DMATXbuff,TXBUFFSIZE);
}
void USART1_DMA_Rx_Config(void)
{
    
    DMA_InitTypeDef  DMA_InitStruct;

 	DMA_DeInit(DMA_U1_Rx_CHANNEL);
 	DMA_Cmd(DMA_U1_Rx_CHANNEL, DISABLE);
    RCC_AHBPeriphClockCmd(DMA_CLOCK,ENABLE);

//传输的路径相当于是
//从DMA(自定义的一个变量)传输数据到DMA外设(USART)  这也就是所谓的M2p   所以这个地址就是上面声明的数组的首地址
//由于通过DMA传输数据时会有一个寄存器[15:0]来表示剩余待传输的字节数  所以一次性最多只能传输65535个字节数据
    DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)USART1_DR_ADDRESS;
    DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)DMARXbuff;    
    DMA_InitStruct.DMA_DIR= DMA_DIR_PeripheralSRC;
	
    DMA_InitStruct.DMA_BufferSize=RXBUFFSIZE;    //总共数据量
	
    DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;  //外设地址不递增   
    DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable ;         //存储器地址递增  数组[0]  [1]  [2]  ...
    DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte ;  //一个字节为单位的数据
    DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte ;
    
//	DMA_InitStruct.DMA_Mode=DMA_Mode_Normal; 
    DMA_InitStruct.DMA_Mode=DMA_Mode_Circular;            
    DMA_InitStruct.DMA_Priority= DMA_Priority_VeryHigh;
    DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;     
	//DMA不同通道之间如果有请求冲突  需配置相应的优先级  这里是软件优先级  硬件优先级:通道数字越小优先级越高
	//DMA传输数据:外设向DMA控制器发出传输数据请求信号 DMA控制器收到请求后会发出应答 外设应答后再次做出应答
	//DMA收到最后应答后开始传输数据  
	
	//同一通道的不同外设的请求只能有一个
    DMA_Init(DMA_U1_Rx_CHANNEL, &DMA_InitStruct);
	
	DMARX_NVIC_Configuration();
	DMA_ITConfig(DMA_U1_Rx_CHANNEL,DMA_IT_TC|DMA_IT_HT,ENABLE);   //USART1半满溢满中断

    DMA_ClearITPendingBit(DMA1_IT_TC5);
	DMA_ClearITPendingBit(DMA1_IT_HT5);   //DMA配置完成后,中断标志位会自动置1 需执行中断标志位清除操作
	
	Debug_USART1_Config();              //串口1配置使能
    DMA_Cmd(DMA_U1_Rx_CHANNEL, ENABLE);
	//跟其他的配置顺序类似,只能在使能之前进行配置
	USART_DMACmd(DEBUG_USART1, USART_DMAReq_Rx, ENABLE);
} 


void USART1_DMA_Tx_Config(uint8_t *SendAddr, uint16_t Size)
{

	DMA_InitTypeDef  DMA_InitStruct;

	DMA_DeInit(DMA_U1_Tx_CHANNEL);
	DMA_Cmd(DMA_U1_Tx_CHANNEL, DISABLE);
	RCC_AHBPeriphClockCmd(DMA_CLOCK, ENABLE);

	
	DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)USART1_DR_ADDRESS;
	DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)SendAddr;
	DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;

	DMA_InitStruct.DMA_BufferSize = Size;    //总共数据量

	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址不递增   
	DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;         //存储器地址递增  数组[0]  [1]  [2]  ...
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //一个字节为单位的数据
	DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

	DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStruct.DMA_Priority = DMA_Priority_High;
	DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
	//DMA不同通道之间如果有请求冲突  需配置相应的优先级  这里是软件优先级  硬件优先级:通道数字越小优先级越高
	//DMA传输数据:外设向DMA控制器发出传输数据请求信号 DMA控制器收到请求后会发出应答 外设应答后再次做出应答
	//DMA收到最后应答后开始传输数据  

	//同一通道的不同外设的请求只能有一个
	DMA_Init(DMA_U1_Tx_CHANNEL, &DMA_InitStruct);
	DMATX_NVIC_Configuration();
	DMA_ITConfig(DMA_U1_Tx_CHANNEL, DMA_IT_TC, ENABLE);   
	DMA_ClearITPendingBit(DMA1_IT_TC5);

	Debug_USART1_Config();              //串口1配置使能
	DMA_Cmd(DMA_U1_Tx_CHANNEL, ENABLE);
	//跟其他的配置顺序类似,只能在使能之前进行配置
	USART_DMACmd(DEBUG_USART1, USART_DMAReq_Tx, ENABLE);
}
/*********************************            辅助函数部分             *********************************/
uint16_t get_DMA_rx_data(Buff_InitTypeDef* rxbuff,uint8_t IT_FLAG)
{
    if(IT_FLAG==DMA_CHANNEL5_HT_IT)
	{
	    rxbuff->buff_handle_size = (uint16_t)(&rxbuff->buff[rxbuff->buff_size/2]- rxbuff->buff_headptr);
		rxbuff->buff_tailptr = &rxbuff->buff[rxbuff->buff_size / 2];
		return rxbuff->buff_handle_size;
	}
	if(IT_FLAG==DMA_CHANNEL5_TC_IT)
	{
		rxbuff->buff_handle_size = (uint16_t)(&rxbuff->buff[rxbuff->buff_size]- rxbuff->buff_headptr);
		rxbuff->buff_tailptr = rxbuff->buff;
		return rxbuff->buff_handle_size;
	}
	if(IT_FLAG==DMA_CHANNEL5_ILDE_IT)
	{
		rxbuff->buff_handle_size = (uint16_t)(rxbuff->buff_size -((uint16_t)(rxbuff->buff_tailptr - rxbuff->buff)+DMA_GetCurrDataCounter(DMA_U1_Rx_CHANNEL)));
		rxbuff->buff_tailptr = &rxbuff->buff_headptr[rxbuff->buff_handle_size];
		return rxbuff->buff_handle_size;
	}	
}


/*********************************            串口1发送函数部分             *********************************/
void Usart1_DMA_TX(Buff_InitTypeDef* txbuff)
{
	if(get_buff_handle_size(txbuff,RX)!=0)
	{
		   USART1_DMA_Tx_Config(txbuff->buff_headptr, get_buff_handle_size(txbuff,RX));
		
		   txbuff->buff_headptr=&txbuff->buff_headptr[get_buff_handle_size(txbuff,RX)];
		if (txbuff->buff_headptr == &txbuff->buff[txbuff->buff_size])
		{
			txbuff->buff_headptr = txbuff->buff;
		}
    }
}

void DMA_TX_Init(void)
{
        Usart1_DMA_TX(&txbuff);
}

/*********************************            串口1发送中断函数部分             *********************************/
void DMA1_Channel4_IRQHandler(void)
{
	if(DMA_GetITStatus(DMA1_IT_TC4)!= RESET)	//DMA接收完成标志
	{
		while(USART_GetFlagStatus(DEBUG_USART1, USART_FLAG_TXE)==RESET);  
        while(USART_GetFlagStatus(DEBUG_USART1,USART_FLAG_TC)==RESET);    //DMA发送完毕但是也需要等待串口发送完毕,否则数据会在串口中被覆盖
		DMA_Cmd(DMA_U1_Tx_CHANNEL, DISABLE );   	//关闭USART1 TX DMA1 所指示的通道
	    DMA_ClearITPendingBit(DMA1_IT_TC4); 	//清除中断标志 
	}
}
/*********************************            串口1半满中断函数部分             *********************************/

void DMA1_Channel5_IRQHandler(void)
{
	uint16_t size;
	if(DMA_GetITStatus(DMA1_IT_HT5)!= RESET)    //***********半满中断部分************//
	{
		USART_ClearFlag(DEBUG_USART1,USART_FLAG_TC);		//清除USART1标志位
		USART1_ClearIdle();                          //清除IDLE标志位  以免数据传输完成后再次开启空闲中断                        		
        IT_FLAG=DMA_CHANNEL5_HT_IT;
        size=fifo_receive(&fifo, &rxbuff, get_DMA_rx_data(&rxbuff, IT_FLAG));
		fifo_send(&fifo, &txbuff, size);
		DMA_TX_Init();
//		delaytime(1); 
		get_buff_handle_size(&txbuff,TX);
        DMA_ClearITPendingBit(DMA1_IT_HT5); 		//清除中断标志 
	}

	if(DMA_GetITStatus(DMA1_IT_TC5)!= RESET)		//***********溢满中断部分************//
	{   
		USART_ClearFlag(DEBUG_USART1,USART_FLAG_TC);		//清除USART1标志位
		USART1_ClearIdle();                          //清除IDLE标志位  以免数据传输完成后再次开启空闲中断                        		
        IT_FLAG=DMA_CHANNEL5_TC_IT;
		size=fifo_receive(&fifo, &rxbuff, get_DMA_rx_data(&rxbuff, IT_FLAG));
		fifo_send(&fifo, &txbuff, size);
		DMA_TX_Init();
//		delaytime(1);
		get_buff_handle_size(&txbuff,TX);
        DMA_ClearITPendingBit(DMA1_IT_TC5); 		//清除中断标志 
	}
}

/*********************************            串口1闲置中断函数部分             *********************************/
void USART1_IRQHandler(void)                	
{
	uint16_t size;
	if(USART_GetITStatus(DEBUG_USART1, USART_IT_IDLE) != RESET)			//串口2空闲中断
	{
		USART_ClearFlag(DEBUG_USART1,USART_FLAG_TC);		//清除USART1标志位		
		IT_FLAG=DMA_CHANNEL5_ILDE_IT;
		size=fifo_receive(&fifo, &rxbuff, get_DMA_rx_data(&rxbuff, IT_FLAG));	
		fifo_send(&fifo, &txbuff, size);
        DMA_TX_Init();
//		delaytime(1);
		get_buff_handle_size(&txbuff,TX);
		USART1_ClearIdle();                          //清除IDLE标志位  以免数据传输完成后再次开启空闲中断                        		
	}
}


#ifndef  _USART1_TXRX_DMA_H
#define  _USART1_TXRX_DMA_H

#include "stm32f10x.h"
#include "usart.h"
#include "fifo.h"

#ifdef __cplusplus
extern "C" {
#endif

	
//DMA
#define  DMA_U1_Tx_CHANNEL                    DMA1_Channel4   
#define  DMA_U1_Rx_CHANNEL                    DMA1_Channel5
#define  DMA_CLOCK                            RCC_AHBPeriph_DMA1


//USART
#define  USART1_DR_ADDRESS                    (USART1_BASE +0x04)



#define  DMA_CHANNEL5_HT_IT                    (uint8_t)1
#define  DMA_CHANNEL5_TC_IT                    (uint8_t)2
#define  DMA_CHANNEL5_ILDE_IT                  (uint8_t)3



void USART1_DMA_Rx_Config(void);
void USART1_DMA_Tx_Config(uint8_t *SendAddr, uint16_t Size);
void Usart1_DMA_TX(Buff_InitTypeDef* txbuff);
uint16_t get_DMA_rx_data(Buff_InitTypeDef* rxbuff, uint8_t IT_FLAG);
void Device_Init(void);
void DMA_TX_Init(void);

#ifdef __cplusplus
}
#endif

#endif  /*_USART1_TXRX_DMA_H*/

usart.c/h

#include "usart.h"



/*********************************            变量声明部分             *********************************/
uint8_t USART1_RX_FLAG;
uint8_t USART1_RX_DATA;


/*********************************            延迟函数部分             *********************************/
void delaytime(uint32_t num)
{
   for(;num!=0;num--);
}
/*********************************            串口配置函数部分             *********************************/
//USART1  接收中断配置

#if(Usart1_normal_with_Interrupt)
static void USART1_NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure1;

  
  ///* 嵌套向量中断控制器组选择 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  ///* 配置USART为中断源 
  NVIC_InitStructure1.NVIC_IRQChannel = DEBUG_USART1_IRQ;
  ///* 抢断优先级为1 
  NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 3;
  ///* 子优先级为1 
  NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 0;
  ///* 使能中断 
  NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
  ///* 初始化配置NVIC 
  NVIC_Init(&NVIC_InitStructure1);
}
#endif



void Debug_USART1_GPIO_Config(void)
{
     GPIO_InitTypeDef    GPIO_InitStructure1;

/*                                       配置USART1相关参数                              */
	  //打开GPIO时钟
     DEBUG_USART1_GPIO_APB2ClkCmd(DEBUG_USART1_GPIO_CLK, ENABLE);
       /* 配置Tx引脚为推挽复用模式  */
     GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_InitStructure1.GPIO_Pin = DEBUG_USART1_TX_PIN;  
     GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(DEBUG_USART1_TX_GPIO_PORT, &GPIO_InitStructure1);

	 /* 配置Rx引脚为浮空输入模式 */
     GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IN_FLOATING;
     GPIO_InitStructure1.GPIO_Pin = DEBUG_USART1_RX_PIN;
     GPIO_Init(DEBUG_USART1_RX_GPIO_PORT, &GPIO_InitStructure1);
}



	

void Debug_USART1_Config(void)    
{

  USART_InitTypeDef   USART1_InitStructure;
  
	
  //打开串口外设时钟
  DEBUG_USART1_APB2ClkCmd(DEBUG_USART1_CLK, ENABLE);	
  /* 使能 USART 时钟 */  //串口时钟不意味着同步数据接收
   
  /* 配置串DEBUG_USART 模式 */
  /* 波特率设置:DEBUG_USART_BAUDRATE */
  USART1_InitStructure.USART_BaudRate = DEBUG_USART1_BAUDRATE;
  /* 字长(数据位+校验位):8 */
  USART1_InitStructure.USART_WordLength = USART_WordLength_8b;
  /* 停止位:1个停止位 */
  USART1_InitStructure.USART_StopBits = USART_StopBits_1;
  /* 校验位选择:不使用校验 */
  USART1_InitStructure.USART_Parity = USART_Parity_No;
  /* 硬件流控制:不使用硬件流 */
  USART1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  /* USART模式控制:同时使能接收和发送 */
  USART1_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  /* 完成USART初始化配置 */
  USART_Init(DEBUG_USART1, &USART1_InitStructure); 
  
  //USART的GPIO口初始化
  Debug_USART1_GPIO_Config();
  
#if(Usart1_normal_with_Interrupt)
	
  /* 嵌套向量中断控制器NVIC配置 */     
  USART1_NVIC_Configuration();
  
	/* 使能串口接收中断 */
  USART_ITConfig(DEBUG_USART1, USART_IT_IDLE, ENABLE);
  USART1_ClearIdle();

#endif
/* 使能串口 */     //打开UE引脚
  USART_Cmd(DEBUG_USART1, ENABLE);


}



/*********************************            辅助函数部分             *********************************/
void USART1_ClearIdle(void)
{
    uint8_t temp;
	USART_GetFlagStatus(DEBUG_USART1,USART_FLAG_IDLE);
	temp=DEBUG_USART1->DR;
}


/*********************************            串口发送函数部分             *********************************/

void Usart_SendByte(USART_TypeDef* pUSARTx,uint8_t data)
{
  USART_SendData(pUSARTx, data);
  while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE)==RESET);  //数据写入TDR  不断读取SR-Reg并且等待数据进入移位Reg
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);  //不断读取SR-Reg并且等待数据传至外部
  delaytime(1000);  //等待数据从IO口传至上位机  
}


void Usart_SendString( USART_TypeDef * pUSARTx, uint8_t *str)
{
    uint8_t k=0;
    do {
		Usart_SendByte( pUSARTx, str[k] );  
		k++;
		} while (*(str + k)!='\0');
}



void Usart_Sendnumber(USART_TypeDef * pUSARTx,uint16_t number)
{
    uint8_t ge=0,shi=0,bai=0,qian=0;
	uint8_t FLAG=0;
	ge   = (number % 10);
    shi  = (((number-ge)/10)%10);
	bai  = (((number-ge-shi*10)/100)%10);
	qian = ((number - ge-shi*10-bai*100) / 1000);
	
	if(qian!=0)
	{
			    Usart_SendByte(pUSARTx,qian+48);
		        Usart_SendByte(pUSARTx,bai+48);
		        Usart_SendByte(pUSARTx,shi+48);
		        Usart_SendByte(pUSARTx,ge+48);
	}
	else if(bai!=0&&qian==0)
	{
		        Usart_SendByte(pUSARTx,bai+48);
		        Usart_SendByte(pUSARTx,shi+48);
		        Usart_SendByte(pUSARTx,ge+48);
	}
	else if(shi!=0&&bai==0&&qian==0)
	{
		        Usart_SendByte(pUSARTx,shi+48);
		        Usart_SendByte(pUSARTx,ge+48);
	}
    else
	{
		        Usart_SendByte(pUSARTx,ge+48);
	}

}

void Usart_SendnumberArray(USART_TypeDef * pUSARTx,uint8_t arr[],uint16_t ArrayLength)
{
	uint16_t i=0;
	for(i=0;i<ArrayLength;i++)
	{
	   Usart_Sendnumber(pUSARTx,arr[i]);
    }
}

void Usart_SendArray(USART_TypeDef * pUSARTx,uint8_t arr[],uint16_t ArrayLength)
{
	uint16_t i=0;
	for(i=0;i<ArrayLength;i++)
	{
	   Usart_SendByte(pUSARTx,arr[i]);
    }
}

uint8_t USART1_Get_RX_Flag(void)
{
   if(USART1_RX_FLAG==1)
   {
       USART1_RX_FLAG=0;
	   return 1;
   }
   return 0;
}

uint8_t USART1_Get_RX_Data(void)
{
   return USART1_RX_DATA;
}





/*********************************            中断函数部分             *********************************/
#if(Usart1_IT_RXNE)
void DEBUG_USART1_IRQHandler(void)
{

    if (USART_GetITStatus(DEBUG_USART1,USART_IT_RXNE)==SET)
		//当接收完成,数据从接收移位寄存器传入RDR中时表示接收完成  RXNE位为1  1!=0为真  执行下边的语句
   {
      USART1_RX_DATA = USART_ReceiveData( DEBUG_USART1 );  //返回最新从USARTx寄存器中读取到的数据,并且清除标志位
	  USART1_RX_FLAG = 1;
	  USART_ClearITPendingBit(DEBUG_USART1,USART_IT_RXNE);
   }

}
#endif

#ifndef _USART_H
#define _USART_H

#include "stm32f10x.h"

#ifdef __cplusplus
extern "C" {
#endif 


//引脚定义
/*******************************************************/
//串口1-USART
#define DEBUG_USART1                             USART1
#define DEBUG_USART1_CLK                         RCC_APB2Periph_USART1
#define DEBUG_USART1_APB2ClkCmd                  RCC_APB2PeriphClockCmd
#define DEBUG_USART1_BAUDRATE                    115200  //串口波特率

//USART GPIO 引脚定义

#define DEBUG_USART1_GPIO_APB2ClkCmd             RCC_APB2PeriphClockCmd
#define DEBUG_USART1_GPIO_CLK                    RCC_APB2Periph_GPIOA

#define DEBUG_USART1_RX_GPIO_PORT                GPIOA
#define DEBUG_USART1_RX_PIN                      GPIO_Pin_10
#define DEBUG_USART1_TX_PIN                      GPIO_Pin_9
#define DEBUG_USART1_TX_GPIO_PORT                GPIOA

#define DEBUG_USART1_IRQHandler                  USART1_IRQHandler
#define DEBUG_USART1_IRQ                 	     USART1_IRQn
/************************************************************/


//函数开关
#define Usart1_normal_with_Interrupt              1
/************************************************************/

//中断函数开关
#define Usart1_IT_RXNE      0

/************************************************************/
void delaytime(uint32_t num);
void Debug_USART1_Config(void);
void Usart_SendByte(USART_TypeDef* pUSARTx,uint8_t data);
void Usart_SendString( USART_TypeDef * pUSARTx, uint8_t *str);
void Usart_Sendnumber(USART_TypeDef * pUSARTx,uint16_t number);
void Usart_SendnumberArray(USART_TypeDef * pUSARTx,uint8_t arr[],uint16_t ArrayLength);
uint8_t USART1_Get_RX_Flag(void);
uint8_t USART1_Get_RX_Data(void);
void Usart_SendArray(USART_TypeDef * pUSARTx,uint8_t arr[],uint16_t ArrayLength);
void USART1_ClearIdle(void);


#ifdef __cplusplus
}
#endif

#endif /*_USART_H*/

main.c

#include "stm32f10x.h"
#include "usart.h"
#include "ledinitiate.h"
#include "usart1_TxRx_dma.h"
#include "bsp_key.h"
#include "bsp_systick.h"
#include "fifo.h"
    
extern uint8_t  fifoarray[FIFOSIZE] ;
extern uint8_t	tx_flag=0;

	int main(void)
	{

		led1initiate();
//		led2initiate();
		LED1(OFF);
//		LED2(OFF);
		Device_Init();   //必不可少的一环,不可随便删除
        USART1_DMA_Rx_Config();
		
        while(1)
	  	{
			    LED1(ON);
        }




   }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值