数据的收发
//===========发送单个数据==========
//1、等待TDR的清空
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){};
//2、写入数据-》TDR
USART_SendData(USART1, 0x5a);
//3、等待数据发送完成
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){};
//===========接收单个数据==========
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET){};
uint16_t flag = USART_ReceiveData(USART1);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){};
//===========发送字节数组===========
uint8_t a[] = {0,1,2,3,4,5,6};
for(int i=0; i< sizeof(a)/sizeof(uint8_t); i++){
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET){};
USART_SendData(USART1, a[i]+32);
};
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){};
//===========接收字符串=============
const char* str = "hello world!!!\n";
for(int i = 0; i < strlen(str); i++){
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET){};
USART_SendData(USART1, str[i]);
}
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){};
中断 + 队列 实现串口通信
#include "stm32f10x.h"
#include "stm32f10x_pal.h"
#include "string.h"
#include "queue.h"
static Queue_HandleTypeDef RxQueue;
static Queue_HandleTypeDef TxQueue;
static uint8_t tmparr[255];
static uint16_t cursor = 0;
void USART1_Echo_RxPrc(void);
void USART1_Echo_TxPrc(void);
void USART1_IRQHandler(void);
static void USART_Recv_Init(void);
int main(void)
{
USART_Recv_Init();
Queue_Init(&RxQueue);
Queue_Init(&TxQueue);
while(1){
USART1_Echo_RxPrc();
USART1_Echo_TxPrc();
}
}
void USART1_IRQHandler(void){
//接收消息队列
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET){
ErrorStatus error = Queue_Enqueue(&RxQueue, USART_ReceiveData(USART1));
if(error != SUCCESS){
//对消息队列满处理
}
}
//当TxE为1,且发送队列不为空时,出队,输出数据
if(USART_GetITStatus(USART1, USART_IT_TXE) == SET){
uint8_t tmp;
ErrorStatus error = Queue_Dequeue(&TxQueue, &tmp);
//有出队数据,发送
if(error == SUCCESS){
USART_SendData(USART1, tmp);
}
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);//关中断
}
}
void USART1_Echo_RxPrc(void){
uint8_t tmp;
//需要屏蔽中断,防止中断对队列的影响
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//关中断
ErrorStatus error = Queue_Dequeue(&RxQueue, &tmp);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开中断
//出队记录数据
if(error == SUCCESS){
tmparr[cursor++] = tmp;
}
}
void USART1_Echo_TxPrc(void){
//===================放入数据====================
//满足要求,将数据加入输出队列
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);//关中断
if(cursor > 2 && tmparr[cursor-1]=='\n' && tmparr[cursor-2] == '\r'){
//加入队列
uint32_t i;
for(i=0 ; i < strlen((char*)tmparr) ;i++){
Queue_Enqueue(&TxQueue, tmparr[i]);
}
//数组清零
cursor=0;
}
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//开中断
}
static void USART_Recv_Init(void){
//初始化PAL库
PAL_Init();
//初始化引脚Pb6
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIOInitStruct;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIOInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIOInitStruct);
//Pb7
GPIOInitStruct.GPIO_Pin = GPIO_Pin_7;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIOInitStruct);
//LED——Pc13
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &GPIOInitStruct);
GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);//初始状态:灭
//引脚重映射
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
//使能USART1外设
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_InitTypeDef USARTInitStruct;
USARTInitStruct.USART_WordLength = USART_WordLength_8b;//数据位长度
USARTInitStruct.USART_Parity = USART_Parity_No;//奇偶校验关闭
USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控关闭
USARTInitStruct.USART_BaudRate = 9600;//波特率
USARTInitStruct.USART_StopBits = USART_StopBits_1;//停止位长度
USARTInitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//双向模式
USART_Init(USART1, &USARTInitStruct);//初始化
USART_Cmd(USART1, ENABLE);//闭合USART1开关
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//USART中断设置
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
//NVIC配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
key: 在队列的对外输出使用中断函数