写在前面
芯片型号:
stm32f030c8t6
说明:便宜,用量大
要点说明:初始化、主函数调用串口接收callback、串口接收空闲中断,串口接收中断
这种API封装方式可以拓展到其他单片机,但需要注意单片机是否支持接收空闲中断
本文注意介绍空闲中断的应用,这样就不用在定时器中计时来检测接收超时中断了
当串口数据接收完成后,在该回调中处理串口数据即可
void Uart_recvCallBack(void *buf, int len)
{
}
myUart_initialize(115200,
USART_WordLength_8b,
USART_StopBits_1,
USART_Parity_No,
Uart_recvCallBack);
#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 */
#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 ++;
}
}