当前位置: 首页 > web >正文

单片机 串口发送和接收

usart.h

#ifndef UART_H
#define UART_H
#include "at32f403a_407_clock.h"#define	 	USART_QUEUE_SIZE 					10
#define	 	USART_BUF_SIZE 					  1024// 队列结构体
typedef struct {uint8_t buffer[USART_QUEUE_SIZE][USART_BUF_SIZE]; // 存储队列数据的缓冲区uint16_t len[USART_QUEUE_SIZE]; // 存储队列数据的缓冲区uint16_t front;                      // 队头uint16_t rear;                       // 队尾
} Usart_Queue;extern Usart_Queue usart1_queue;void usart1_init(void);
void usart2_init(void);
void usart_send_byte( usart_type * pUSARTx, uint8_t ch);
void usart_send_string( usart_type * pUSARTx, char *str);
void usart_send_bytes( usart_type * pUSARTx, uint8_t* ch,int len);void usart_queue_init(Usart_Queue* q);
int usart_queue_enqueue(Usart_Queue* q, uint8_t* data,uint16_t len);
int usart_queue_dequeue(Usart_Queue* q, uint8_t* data);
#endif

usart.c

#include "usart.h"
#include <string.h>#define	 	USART_HEADER 					  	0X15
#define	 	USART_TAIL 					  		0X16uint8_t  	usart1_receive_data[USART_BUF_SIZE]; 
uint16_t 	usart1_receive_index=0;
uint8_t   usart1_is_receive_header=0;Usart_Queue usart1_queue;//串口1初始化
void usart1_init()
{gpio_init_type gpio_init_struct;usart_queue_init(&usart1_queue);/* 使能对应端口的时钟 */crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);/* 默认填充配置 */gpio_default_para_init(&gpio_init_struct);/* 设置 GPIO 驱动能力较大电流推动/吸入能力 */gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;/* 设置 GPIO 输出类型为推挽输出模式 */gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;/* 设置 GPIO 模式为复用模式 */gpio_init_struct.gpio_mode = GPIO_MODE_MUX;/* 配置 GPIO 引脚 */gpio_init_struct.gpio_pins = GPIO_PINS_9|GPIO_PINS_10;/* 设置 GPIO 无上下拉模式 */gpio_init_struct.gpio_pull = GPIO_PULL_NONE;/* 初始化 GPIO 外设 */gpio_init(GPIOA, &gpio_init_struct);/* 波特率 数据位 停止位配置 */usart_init(USART1, 9600, USART_DATA_8BITS, USART_STOP_1_BIT);/* 中断优先级分组配置 */nvic_priority_group_config(NVIC_PRIORITY_GROUP_1);/* 中断使能及优先级配置 */nvic_irq_enable(USART1_IRQn, 0,1);/* 发送使能 */usart_transmitter_enable(USART1, TRUE);/* 接收使能 */usart_receiver_enable(USART1, TRUE);/* 中断使能 */	usart_interrupt_enable(USART1,USART_RDBF_INT, TRUE);/* 串口使能 */usart_enable(USART1, TRUE);
}//串口2初始化
void usart2_init()
{gpio_init_type gpio_init_struct;/* 使能对应端口的时钟 */crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);/* 默认填充配置 */gpio_default_para_init(&gpio_init_struct);/* 设置 GPIO 驱动能力较大电流推动/吸入能力 */gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;/* 设置 GPIO 输出类型为推挽输出模式 */gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;/* 设置 GPIO 模式为复用模式 */gpio_init_struct.gpio_mode = GPIO_MODE_MUX;/* 配置 GPIO 引脚 */gpio_init_struct.gpio_pins = GPIO_PINS_2;/* 设置 GPIO 无上下拉模式 */gpio_init_struct.gpio_pull = GPIO_PULL_NONE;/* 初始化 GPIO 外设 */gpio_init(GPIOA, &gpio_init_struct);gpio_init_struct.gpio_pins = GPIO_PINS_3;gpio_init(GPIOA, &gpio_init_struct);/* 波特率 数据位 停止位配置 */usart_init(USART2, 9600, USART_DATA_8BITS, USART_STOP_1_BIT);/* 中断优先级分组配置 */nvic_priority_group_config(NVIC_PRIORITY_GROUP_1);/* 中断使能及优先级配置 */nvic_irq_enable(USART2_IRQn, 0,1);/* 发送使能 */usart_transmitter_enable(USART2, TRUE);/* 接收使能 */usart_receiver_enable(USART2, TRUE);/* 中断使能 */	usart_interrupt_enable(USART2,USART_RDBF_INT, TRUE);/* 串口使能 */usart_enable(USART2, TRUE);
}/*****************  发送一个字符 **********************/
void usart_send_byte( usart_type * pUSARTx, uint8_t ch)
{/* 发送一个字节数据到USART */usart_data_transmit(pUSARTx,ch);/* 等待发送数据寄存器为空 */while (usart_flag_get(pUSARTx, USART_TDBE_FLAG) == RESET);	
}/*****************  发送多个字符 **********************/
void usart_send_bytes( usart_type * pUSARTx, uint8_t* ch,int len)
{int i;for(i=0;i<len;i++){usart_send_byte( pUSARTx, *(ch + i) );}
}/*****************  发送字符串 **********************/
void usart_send_string( usart_type * pUSARTx, char *str)
{unsigned int k=0;do {usart_send_byte( pUSARTx, *(str + k) );k++;} while(*(str + k)!='\0');/* 等待发送完成 */while(usart_flag_get(pUSARTx,USART_TDC_FLAG)==RESET){}
}//串口1中断 接收
void USART1_IRQHandler(void)
{uint8_t uc;if(usart_flag_get(USART1, USART_RDBF_FLAG) != RESET){uc = usart_data_receive(USART1);usart1_receive_data[usart1_receive_index]=uc;usart1_receive_index++;if(uc==USART_HEADER)usart1_is_receive_header=1;if((uc==USART_TAIL&&usart1_receive_index>=6&&usart1_is_receive_header)||usart1_receive_index>=USART_BUF_SIZE){usart_queue_enqueue(&usart1_queue,usart1_receive_data,usart1_receive_index);//usart_send_bytes(USART1,usart1_receive_data,usart1_receive_index);usart1_receive_index=0;usart1_is_receive_header=0;}}
}//串口2中断 接收
void USART2_IRQHandler(void)
{uint8_t uc;if(usart_flag_get(USART2, USART_RDBF_FLAG) != RESET){uc = usart_data_receive(USART2);usart_data_transmit(USART2, uc);}
}// 初始化队列
void usart_queue_init(Usart_Queue* q) {q->front = 0;q->rear = 0;
}// 判断队列是否为空
int usart_queue_is_empty(Usart_Queue* q) {return q->front == q->rear;
}// 判断队列是否为满
int usart_queue_is_full(Usart_Queue* q) {return ((q->rear + 1) % USART_QUEUE_SIZE) == q->front;
}// 入队操作
int usart_queue_enqueue(Usart_Queue* q, uint8_t* data,uint16_t len) {if (usart_queue_is_full(q)) {return -1;  // 队列已满,无法入队}q->len[q->rear]=len;memcpy(q->buffer[q->rear], data, USART_BUF_SIZE);  // 复制数据到队列q->rear = (q->rear + 1) % USART_QUEUE_SIZE;           // 更新队尾索引return 0;
}// 出队操作
int usart_queue_dequeue(Usart_Queue* q, uint8_t* data) {int len=0;if (usart_queue_is_empty(q)) {return 0;  // 队列为空,无法出队}len=q->len[q->front];memcpy(data, q->buffer[q->front], USART_BUF_SIZE);  // 复制队头数据q->front = (q->front + 1) % USART_QUEUE_SIZE;          // 更新队头索引return len;
}

main.c

	while(1){data_len = usart_queue_dequeue(&usart1_queue, item);// 从队列中出队一个项if (data_len != 0){usart_send_bytes(USART1,item,data_len);}delay_ms(10);}
http://www.xdnf.cn/news/9532.html

相关文章:

  • ⚡ Linux 系统安装与配置 Vim 编辑器(包括 Vim 插件管理器)
  • RTOS 完整概述与实战应用:从基础原理到产业实情
  • 论文略读:Deep reinforcement learning for community architectural layout generation
  • Dolphinscheduler-3.2.0分布式集群详细部署
  • 时间的基本概念与相关技术二
  • 如何将多张图组合到一张图里同时保留高的分辨率(用PPT+AdobeAcrobat)
  • 用 Appuploader,让 iOS 上架流程真正“可交接、可记录、可复用”:我们是这样实现的
  • 能按需拆分 PDF 为多个文档的工具
  • Linux C++ 开发基础命令指南
  • 亚远景-ISO 21434标准:汽车网络安全实践的落地指南
  • 基于深度学习的工业OCR实践:仪器仪表数字识别技术详解
  • qt之开发大恒usb3.0相机三
  • 基于python,html,flask,echart,ids/ips,VMware,mysql,在线sdn防御ddos系统
  • SCDN如何同时保障网站加速与DDoS防御?
  • 精益数据分析(92/126):指标基准化——如何判断你的数据表现是否足够优秀
  • Vue Router 钩子函数与组件生命周期执行顺序详解
  • Ubuntu 系统grub日志级别设置
  • C#与 Prism 框架:构建模块化的 WPF 应用程序
  • 毫秒级数据采集的极致优化:如何用C#实现高性能、无冗余的实时文件写入?
  • 文档整合自动化
  • ASP.NET MVC添加新控制器示例
  • Android 缓存应用冻结器(Cached Apps Freezer)
  • 交换机环路故障分析以及解决方案
  • 模型自学推理:自信驱动进化
  • 使用JavaSDK简单上传文件到阿里云OSS服务中
  • GitHub开源|AI顶会论文中文翻译PDF合集(gpt-translated-pdf-zh)
  • 【AGI】Qwen3模型高效微调
  • Python生成ppt(python-pptx)N问N答(如何绘制一个没有背景的矩形框;如何绘制一个没有背景的矩形框)
  • 小提琴图绘制-Graph prism
  • 打破网络次元壁:NAT 穿透与内网打洞的 “Matrix 式” 通信革命