【STM32】STM32之串口

本篇博文最后修改时间:2016年12月28日,11:59。


一、简介

本文介绍如何使用STM32的串口,串口1和串口2的驱动都写好了,本文以串口2的驱动为例


二、实验平台

库版本:STM32F10x_StdPeriph_Lib_V3.5.0

编译软件:MDK4.53

硬件平台:STM32开发板(主芯片stm32f103c8t6)

仿真器:JLINK


版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、实验前提

在进行本文步骤前,请先阅读并实现以下博文:

1、《STM32之NVIC》:http://blog.csdn.net/feilusia/article/details/52819709


五、实验步骤

1、编写并添加串口驱动

1)编写驱动GUA_USART.c(存放在“……\HARDWARE”)

//******************************************************************************          
//name:             GUA_USART.c          
//introduce:        串口驱动   
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.12.28   
//******************************************************************************  
#include "stm32f10x.h"
#include "GUA_USART.h"

/*********************宏定义************************/ 
#define GUA_USART_TIMEOUT    ((GUA_U32)0xFFF)            //串口超时时间

/*********************全局变量************************/ 
//串口1缓冲区
GUA_U8 gGUA_USART1_rx_buf[GUA_USART1_RX_SIZE] = {0};                          
GUA_U8 gGUA_USART1_tx_buf[GUA_USART1_TX_SIZE] = {0};                         

//串口2缓冲区
GUA_U8 gGUA_USART2_rx_buf[GUA_USART2_RX_SIZE] = {0};                          
GUA_U8 gGUA_USART2_tx_buf[GUA_USART2_TX_SIZE] = {0};                         

/*********************内部函数声明************************/ 
static void GUA_USART1_Init(GUA_U32 nGUA_BaudRate, GUA_U32 nGUA_WordLength, GUA_U32 nGUA_StopBits,
														GUA_U32 nGUA_Parity, FunctionalState GUA_IT_Tx_NewState,
														FunctionalState GUA_IT_Rx_NewState, FunctionalState GUA_Cmd_NewState);
static void GUA_USART2_Init(GUA_U32 nGUA_BaudRate, GUA_U32 nGUA_WordLength, GUA_U32 nGUA_StopBits,
														GUA_U32 nGUA_Parity, FunctionalState GUA_IT_Tx_NewState,
														FunctionalState GUA_IT_Rx_NewState, FunctionalState GUA_Cmd_NewState);									
//******************************************************************************            
//name:             GUA_USART1_Init           
//introduce:        USART1初始化        
//parameter:        nGUA_BaudRate:波特率, nGUA_WordLength:数据长度, nGUA_StopBits:停止位
//                  nGUA_Parity:校验位, GUA_IT_Tx_NewState:发送中断使能位, GUA_IT_Rx_NewState:接收中断使能位, 	               
//                  GUA_Cmd_NewState:串口使能位
//return:           none         
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.12.28                      
//******************************************************************************
static void GUA_USART1_Init(GUA_U32 nGUA_BaudRate, GUA_U32 nGUA_WordLength, GUA_U32 nGUA_StopBits,
														GUA_U32 nGUA_Parity, FunctionalState GUA_IT_Tx_NewState,
														FunctionalState GUA_IT_Rx_NewState, FunctionalState GUA_Cmd_NewState)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	USART_ClockInitTypeDef USART_ClockInitStructure;

	//开GPIOA、AFIO、USART1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE);

	//复位
	USART_DeInit(USART1);										

	//IO配置		
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;																							 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;																						 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	 
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	//时序配置
	USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;  
	USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;  
	USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;  
	USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;   
	USART_ClockInit(USART1,&USART_ClockInitStructure);
	
	//串口配置
	USART_InitStructure.USART_BaudRate = nGUA_BaudRate;																		//设置串口通信时的波特率  
	USART_InitStructure.USART_WordLength = nGUA_WordLength;																//设置数据位的长度  
	USART_InitStructure.USART_StopBits = nGUA_StopBits;																		//设置停止位   
	USART_InitStructure.USART_Parity = nGUA_Parity ;																			//设置校验位   
	USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;    	//设置硬件控制流失能  
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;      									//设置发送使能,接收使能   
	USART_Init(USART1, &USART_InitStructure);																							//将以上赋完值的结构体带入库函数USART_Init进行初始化  

	USART_ITConfig(USART1, USART_IT_TXE, GUA_IT_Tx_NewState);															//串口1发送中断
	USART_ITConfig(USART1, USART_IT_RXNE, GUA_IT_Rx_NewState);														//串口1接收中断
	USART_Cmd(USART1, GUA_Cmd_NewState);																									//使能USART1
	
	USART_ClearFlag(USART1, USART_FLAG_TC);																								//清除发送标志
	USART_ClearFlag(USART1, USART_FLAG_RXNE);																						 	//清除接收标志	
}

//******************************************************************************            
//name:             GUA_USART2_Init           
//introduce:        USART2初始化        
//parameter:        nGUA_BaudRate:波特率, nGUA_WordLength:数据长度, nGUA_StopBits:停止位
//                  nGUA_Parity:校验位, GUA_IT_Tx_NewState:发送中断使能位, GUA_IT_Rx_NewState:接收中断使能位, 	               
//                  GUA_Cmd_NewState:串口使能位              
//return:           none         
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.12.28                     
//******************************************************************************
static void GUA_USART2_Init(GUA_U32 nGUA_BaudRate, GUA_U32 nGUA_WordLength, GUA_U32 nGUA_StopBits,
														GUA_U32 nGUA_Parity, FunctionalState GUA_IT_Tx_NewState,
														FunctionalState GUA_IT_Rx_NewState, FunctionalState GUA_Cmd_NewState)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	USART_ClockInitTypeDef USART_ClockInitStructure;

	//开GPIOA、AFIO、USART2时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);			
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	
	//复位
	USART_DeInit(USART2);																																		
	
	//IO配置
	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);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;																							
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	 
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	//时序配置
	USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;  
	USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;  
	USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;  
	USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;   
	USART_ClockInit(USART2,&USART_ClockInitStructure);
	
	//串口配置
	USART_InitStructure.USART_BaudRate = nGUA_BaudRate;																		//设置串口通信时的波特率  
	USART_InitStructure.USART_WordLength = nGUA_WordLength;																//设置数据位的长度  
	USART_InitStructure.USART_StopBits = nGUA_StopBits;																		//设置停止位   
	USART_InitStructure.USART_Parity = nGUA_Parity ;																			//设置校验位   
	USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;    	//设置硬件控制流失能  
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;      									//设置发送使能,接收使能   
	USART_Init(USART2, &USART_InitStructure);																							//将以上赋完值的结构体带入库函数USART_Init进行初始化  

	USART_ITConfig(USART2, USART_IT_TXE, GUA_IT_Tx_NewState);															//串口2发送中断
	USART_ITConfig(USART2, USART_IT_RXNE, GUA_IT_Rx_NewState);														//串口2接收中断	
	USART_Cmd(USART2, GUA_Cmd_NewState);																									//使能USART2	
	
	USART_ClearFlag(USART2, USART_FLAG_TC);																								//清除发送标志		
	USART_ClearFlag(USART2, USART_FLAG_RXNE);																						 	//清除接收标志		
}

//******************************************************************************            
//name:             GUA_USARTx_Send           
//introduce:        串口发送函数         
//parameter:        GUA_USARTx:USART1或USART2, pGUA_Data:数据发送缓冲区, nGUA_Len:数据长度         
//return:           none         
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.12.28                      
//******************************************************************************  
void GUA_USARTx_Send(USART_TypeDef* GUA_USARTx, GUA_U8 *pGUA_Data, GUA_U8 nGUA_Len)
{
	GUA_U8 i = 0;
	
	for(i = 0; i < nGUA_Len; i++)
	{
		while(USART_GetFlagStatus(GUA_USARTx, USART_FLAG_TC) != SET);	
		USART_SendData(GUA_USARTx, pGUA_Data[i]);													
	}
}

//******************************************************************************            
//name:             GUA_USARTx_Reveive           
//introduce:        串口接收函数         
//parameter:        GUA_USARTx:USART1或USART2, pGUA_Data:数据接收缓冲区      
//return:           none         
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.12.28                   
//******************************************************************************  
GUA_U8 GUA_USARTx_Reveive(USART_TypeDef* GUA_USARTx, GUA_U8 *pGUA_Data)
{
  GUA_U8 nGUA_Num = 0;
  GUA_U32 nGUA_Timeout = 0;
  GUA_U8 *pGUA_Data_Temp = pGUA_Data;            							
  
  while(1)
  {
		//等待接收缓冲区收到数据
    nGUA_Timeout= GUA_USART_TIMEOUT;                      		
    while(USART_GetITStatus(GUA_USARTx, USART_IT_RXNE) == RESET) 
    {
			//等待超时则退出函数
      if((nGUA_Timeout--) == 0)                       					
        return nGUA_Num;
    }

		//计算接收到的数据个数
    nGUA_Num++;              

		//保存数据到临时缓冲区  		
    *pGUA_Data_Temp++ = USART_ReceiveData(GUA_USARTx);		    
  }   
}

//******************************************************************************            
//name:             GUA_USART_Init           
//introduce:        串口初始化         
//parameter:        none                 
//return:           none         
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.12.28                    
//******************************************************************************
void GUA_USART_Init(void)
{	
	//GUA_USART1_Init(9600,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,DISABLE, DISABLE, ENABLE);
	GUA_USART2_Init(9600, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No, DISABLE, ENABLE, ENABLE);
}

2) 编写驱动头文件 GUA_USART.h(存放在“ …… \HARDWARE ”)
//******************************************************************************          
//name:             GUA_USART.h          
//introduce:        串口驱动的头文件   
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.12.28   
//******************************************************************************   
#ifndef _GUA_USART_H_
#define _GUA_USART_H_

/*********************头文件************************/
#include "stm32f10x.h"

/*********************宏定义************************/
#ifndef GUA_U8        
typedef unsigned char GUA_U8;        
#endif    

#ifndef GUA_8        
typedef signed char GUA_8;        
#endif      
      
#ifndef GUA_U16        
typedef unsigned short GUA_U16;        
#endif 

#ifndef GUA_16        
typedef signed short GUA_16;        
#endif         
      
#ifndef GUA_U32        
typedef unsigned long GUA_U32;        
#endif 

#ifndef GUA_32        
typedef signed long GUA_32;       
#endif

#ifndef GUA_U64    
typedef unsigned long long GUA_U64;  
#endif

#ifndef GUA_64    
typedef signed long long GUA_64;  
#endif

//串口1缓冲区大小
#define GUA_USART1_RX_SIZE			17
#define GUA_USART1_TX_SIZE			17

//串口2缓冲区大小
#define GUA_USART2_RX_SIZE			17
#define GUA_USART2_TX_SIZE			17

/*********************外部变量************************/
//串口1缓冲区
extern GUA_U8 gGUA_USART1_rx_buf[GUA_USART1_RX_SIZE];                          
extern GUA_U8 gGUA_USART1_tx_buf[GUA_USART1_TX_SIZE];                         

//串口2缓冲区
extern GUA_U8 gGUA_USART2_rx_buf[GUA_USART2_RX_SIZE];                          
extern GUA_U8 gGUA_USART2_tx_buf[GUA_USART2_TX_SIZE];  

/*********************外部函数************************/
extern void GUA_USARTx_Send(USART_TypeDef* GUA_USARTx, GUA_U8 *pGUA_Data, GUA_U8 nGUA_Len);
extern GUA_U8 GUA_USARTx_Reveive(USART_TypeDef* GUA_USARTx, GUA_U8 *pGUA_Data);
extern void GUA_USART_Init(void);                      


#endif

3) 工程中添加GUA_USART.c



4)在MDK设置中添加串口驱动源文件路径



2、添加库的驱动

1)添加库的驱动文件



2)添加库的驱动头文件(stm32f10x_conf.h 中)

#include "stm32f10x_usart.h"

3、设置NVIC中断优先级(GUA_NVIC.c的GUA_NVIC_Init中

	//串口中断
	GUA_NVIC_Config(NVIC_PriorityGroup_2, USART2_IRQn, 0, 1, ENABLE);	

4、写中断服务函数(stm32f10x_it.c中)

1)添加头文件

#include "GUA_USART.h"

2)写串口2中断服务函数
//******************************************************************************            
//name:             USART2_IRQHandler           
//introduce:        串口2中断服务函数         
//parameter:        none                 
//return:           none         
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.10.17                     
//******************************************************************************
void USART2_IRQHandler(void)
{
	//接收串口数据
	nNum = GUA_USARTx_Reveive(USART2, gGUA_USART2_rx_buf);                    
	
	//将接收到的数据发送出去
	GUA_USARTx_Send(USART2, &gGUA_USART2_rx_buf, nNum); 
}

5、在应用层中调用

1)添加驱动头文件(main.c中)

#include "GUA_USART.h"	

2) 添加驱动初始化代码(main.c的main函数中)

	//中断优先级配置
	GUA_NVIC_Init(); 

	//串口初始化
	GUA_USART_Init();	 






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值