STM32F0系列开发之串口的使用

写在前面

芯片型号:stm32f030c8t6
说明:便宜,用量大
要点说明:初始化、主函数调用串口接收callback、串口接收空闲中断,串口接收中断
这种API封装方式可以拓展到其他单片机,但需要注意单片机是否支持接收空闲中断
本文注意介绍空闲中断的应用,这样就不用在定时器中计时来检测接收超时中断了

一、应用

外部定义串口接收回调

当串口数据接收完成后,在该回调中处理串口数据即可

void Uart_recvCallBack(void *buf, int len)
{

}

外部初始化串口

myUart_initialize(115200,
					USART_WordLength_8b,
					USART_StopBits_1,
					USART_Parity_No,
					Uart_recvCallBack);

二、源码

myUart.h

#ifndef __myUart_H
#define	__myUart_H

#include "stm32f0xx.h"
#include "stm32f0xx_usart.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_misc.h"

#define USART_REC_LEN  			200  	//定义最大接收字节数

typedef void (*myUart_cb)(void *buf, int len);

void myUart_initialize(   uint32_t USART_BaudRate,
							uint32_t USART_WordLength,
							uint32_t USART_StopBits,
							uint32_t USART_Parity,
							myUart_cb cb);
void myUart_setBaudRate(uint32_t USART_BaudRate);
void myUart_sendByte(uint8_t byte);
void myUart_sendBytes(uint8_t *Buffer, uint32_t Length);
uint8_t myUart_recvByte(void);
int fputc(int ch, FILE *f);

#endif /* __UART_H */


myUart.c

#include "myUart.h"

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

uint8_t USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
uint16_t USART_RX_count = 0;       //接收状态标记		
myUart_cb myUart_callBack;
/* Private functions ---------------------------------------------------------*/

USART_InitTypeDef USART_InitStructure;

void myUart_initialize(   uint32_t USART_BaudRate,
							uint32_t USART_WordLength,
							uint32_t USART_StopBits,
							uint32_t USART_Parity,
							myUart_cb cb)
{  

	GPIO_InitTypeDef  GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );

	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);        
	/*
	*  USART1_TX -> PA9 , USART1_RX ->        PA10
	*/                                
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;                 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(GPIOA, &GPIO_InitStructure);        

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPriority=1 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

	USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength;//设置数据位
	USART_InitStructure.USART_StopBits = USART_StopBits;//设置停止位
	USART_InitStructure.USART_Parity = USART_Parity;//设置效验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式
	USART_Init(USART1, &USART_InitStructure); //配置入结构体

	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接受超时中断
	USART_Cmd(USART1, ENABLE);//使能串口1

	myUart_callBack = cb;
}			
void myUart_setBaudRate(uint32_t USART_BaudRate)
{
	USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
	USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
	USART_Cmd(USART1, DISABLE);

	USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率
	USART_Init(USART1, &USART_InitStructure); //配置入结构体

	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接收超时中断
	USART_Cmd(USART1, ENABLE);//使能串口1
}
void myUart_sendByte(uint8_t byte) //发送1字节数据
{
 while(!((USART1->ISR)&(1<<7)));
 USART1->TDR=byte;	
}		

void myUart_sendBytes(uint8_t *Buffer, uint32_t Length)
{
	while(Length != 0)
	{
		while(!((USART1->ISR)&(1<<7)));//等待发送完
		USART1->TDR= *Buffer;
		Buffer++;
		Length--;
	}
}

uint8_t myUart_recvByte(void)
{	
	while(!(USART1->ISR & (1<<5)));//等待接收到数据
	return(USART1->RDR);			 //读出数据
}


PUTCHAR_PROTOTYPE 
{
/* 将Printf内容发往串口 */
  USART_SendData(USART1,(uint8_t)  ch);
  while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
	{}
 
  return (ch);
}

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	uint8_t Res;

	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
	{
		USART_ClearITPendingBit(USART1, USART_IT_IDLE);//USART_IT_IDLE需要手动清除
		if (USART_RX_count)
		{
			if (myUart_callBack)
			{
				myUart_callBack(USART_RX_BUF, USART_RX_count);
			}
		}
		USART_RX_count = 0;
	}
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
	{
		USART_RX_BUF[USART_RX_count] = USART_ReceiveData(USART1);	//读取接收到的数据,自动清除USART_IT_RXNE中断标志
		USART_RX_count ++;
	} 
} 

你可能感兴趣的:(STM32)