串口通信非中断方式
main.c代码:
#include “main.h”
#include “usart.h”
#include “gpio.h”=
#include “stdio.h”
#include “string.h”
//重定向printf函数实现串口打印
int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}
int main(void)
{
unsigned char ch[20] = {0};
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
HAL_UART_Transmit(&huart1, (uint8_t *)"xfj handsome", strlen("xfj handsome"), 100);
while (1)
{
HAL_UART_Receive(&huart1, ch, 19, 100);//ch留一个空间给'\0'
//HAL_UART_Transmit(&huart1, ch, strlen(ch), 100);
//printf(ch);
printf("%s",ch);
if(!strcmp((const char *)ch,"open\r\n")){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_RESET){
printf("风扇已经打开\r\n");
}
}else if(!strcmp((const char *)ch,"close\r\n")){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_SET){
printf("风扇已经关闭\r\n");
}
}else{
if(!(ch[0] == '\0')){
printf("%s","指令错误!");
}
}
memset(ch, 0, strlen((const char *)ch));
}
}
中断方式:
串口中断回调函数:
HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //发送中断回调函数
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //接收中断回调函数
状态标记变量:
USART_RX_STA
从0开始,串口中断接收到一个数据(一个字节)就自增1。当数据读取全部OK时候(回车和换行符号来的时候),那么 USART_RX_STA的最高位置1,表示串口数据接收全部完毕了,然后main函数里面可以处理数据了。
stm32CubeMX串口配置图:
main.c代码:
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
#include "string.h"
//串口接收缓存(1字节)
uint8_t buf=0;
// 接收状态
// bit15, 接收完成标志
// bit14, 接收到0x0d
// bit13-0, 接收到的有效字节数目
uint16_t UART1_RX_STA=0;
//定义最大接收字节数 200,可根据需求调整
#define UART1_REC_LEN 200
// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
uint8_t UART1_RX_Buffer[UART1_REC_LEN];
void SystemClock_Config(void);
//重写接收完成回调函数,收到一个数据后,在这里做处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//判断中断是由那个串口触发的
if(huart->Instance == USART1){
//判断是否接收完成(UART1_RX_STA bit15位是否为1)
if((UART1_RX_STA &0x8000) == 0){
//如果已经收到回车0x0d
if(UART1_RX_STA & 0x4000){
//接着判断是否收到换行(0x0a)
if(buf == 0x0a){
//如果0x0d和0x0a都收到,则将bit15的位置置为1
UART1_RX_STA |= 0x8000;
}else{
//否则认为接收错误,重新开始
UART1_RX_STA = 0;
}
}else{
//如果没有收到回车,则先判断接收的这个字符是否为0x0d(回车)
if(buf == 0x0d){
//是回车的话,将bit14位置为1
UART1_RX_STA |= 0x4000;
}else{
//否则将接收到的数据保存在缓存数组里面
UART1_RX_Buffer[UART1_RX_STA & 0x3fff] = buf;
UART1_RX_STA++;
//如果接收的数据大于UART1_REC_LEN(200个字节),则重新开始接收
if((UART1_RX_STA & 0x3fff) > UART1_REC_LEN-1){
UART1_RX_STA = 0;
}
}
}
}
//重新开启中断
HAL_UART_Receive_IT(&huart1,&buf,1);
}
}
**//重定向prinf函数实现串口打印**
int fputc(int ch,FILE *f)
{
unsigned char temp[1] = {ch};
HAL_UART_Transmit(&huart1,temp,1,0xFFFF);
return ch;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
//开启接收中断
HAL_UART_Receive_IT(&huart1,&buf,1);
while (1)
{
//判断接收是否完成
if(UART1_RX_STA & 0x8000){
printf("收到数据: ");
if(!strcmp((const char *)UART1_RX_Buffer,"open")){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_RESET){
printf("风扇已经打开\r\n");
}
}else if(!strcmp((const char *)UART1_RX_Buffer,"close")){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_SET){
printf("风扇已经关闭\r\n");
}
}else{
if(UART1_RX_Buffer[0] != '\0'){
printf("%s","指令错误!");
}
}
memset(UART1_RX_Buffer, 0, strlen((const char *)UART1_RX_Buffer));//清理掉当前缓存数组里面的内容,防止误判
printf("\r\n");
//重新开始下一次接收
UART1_RX_STA = 0;
}
printf("xfj hansome\r\n");
HAL_Delay(1000);
}
}