下面的程序使用 CH32V103C8T6评估板测试没有问题,使用中断完成了串口的非阻塞式收发,编程思路参考了51单片机非阻塞串口中断收发数据

usart_buf.h

/** usart_buf.h**  Created on: 2022年6月19日*      Author: lin*/
#ifndef USER_DEV_USART_BUF_H_
#define USER_DEV_USART_BUF_H_#include "ch32v10x.h"#define USART_USE           1       // 使用那个串口 1 2 3
#define BAUDRATE            115200  // 波特率
#define SEND_BUF_SIZE       128     // 发送缓存大小
#define RECEIVE_BUF_SIZE    128     // 接收缓存大小
#define END_CHAR            '\n'      // 接收字符结束标志
#define USARTx_PP           1       //抢占优先级
#define USARTx_SUB          1       //执行优先级typedef enum
{USART_ReceiveReady,USART_ReceiveComplete,
}USART_ReceiveStateType;extern uint8_t USART_Receive_Buf[RECEIVE_BUF_SIZE];
extern USART_ReceiveStateType USART_ReceiveState;extern void Init_USART(void);
extern void USART_SendStr(const char* Data);
extern void USART_SendBuf(const uint8_t* Data, uint16_t size);
extern void USART_SendNum(int32_t num);
extern void USART_SendByte(uint8_t Data);
extern void USART_SendHex8(uint8_t Data);
extern void USART_SendBin(uint32_t Data);#endif /* USER_DEV_USART_BUF_H_ */

usart_buf.c

/** usart_buf.c**  Created on: 2022年6月19日*      Author: lin*/
#include "usart_buf.h"/*-------------接口-------------*/
#if (USART_USE == 1)#define USART_Periph  USART1#define USART_PORT        GPIOA#define USART_RCC      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE)#define USART_TX      GPIO_Pin_9#define USART_RX      GPIO_Pin_10#define USARTx_IRQN      USART1_IRQn
#elif (USART_USE == 2)#define USART_Periph    USART2#define USART_PORT        GPIOA#define USART_RCC      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE)#define USART_TX         GPIO_Pin_2#define USART_RX      GPIO_Pin_3#define USARTx_IRQN       USART2_IRQn
#elif (USART_USE == 3)#define USART_Periph    USART3#define USART_PORT        GPIOB#define USART_RCC      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE)#define USART_TX         GPIO_Pin_10#define USART_RX         GPIO_Pin_11#define USARTx_IRQN      USART3_IRQn
#endif//发送
typedef struct
{uint8_t buf[SEND_BUF_SIZE];    //存放待发送字节uint8_t* p_w;      //当前写入指针uint8_t* p_s;       //当前发送指针
} USART_SendBufTypeDef;
USART_SendBufTypeDef SendBufStruct = {.buf={0}, .p_s=(uint8_t*)(0), .p_w=(uint8_t*)(0)};//接收
uint8_t USART_Receive_Buf[RECEIVE_BUF_SIZE] = {0};
USART_ReceiveStateType USART_ReceiveState = USART_ReceiveReady;
static uint8_t dat = 0; //接收临时变量
static uint16_t byte_n = 0; //接收计数void Init_USART(void)
{GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;// 发送相关指针初始化SendBufStruct.p_s = SendBufStruct.buf;SendBufStruct.p_w = SendBufStruct.buf;USART_RCC; //开时钟GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin = USART_TX;GPIO_Init(USART_PORT, &GPIO_InitStruct);//GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin = USART_RX;GPIO_Init(USART_PORT, &GPIO_InitStruct);USART_InitStruct.USART_BaudRate = BAUDRATE;USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_Init(USART_Periph, &USART_InitStruct);USART_ClearFlag(USART_Periph, USART_FLAG_TC); //串口状态寄存器 复位值0x000000C0 TC和TXE是1 表示发送完成 上电会进中断一次 初始化应该清除此标志USART_ClearFlag(USART_Periph, USART_FLAG_TXE);USART_ITConfig(USART_Periph, USART_IT_TC, ENABLE);USART_ITConfig(USART_Periph, USART_IT_RXNE, ENABLE);NVIC_InitStruct.NVIC_IRQChannel = USARTx_IRQN;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = USARTx_PP;  //优先级配置NVIC_InitStruct.NVIC_IRQChannelSubPriority = USARTx_SUB;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);USART_Cmd(USART_Periph, ENABLE);
}#if (USART_USE == 1)
void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART1_IRQHandler(void)
#elif (USART_USE == 2)
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART2_IRQHandler(void)
#elif (USART_USE == 3)
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART3_IRQHandler(void)
#endif
{//发送if(USART_GetITStatus(USART_Periph, USART_IT_TC) == SET){if(SendBufStruct.p_s != SendBufStruct.p_w){//USART_Periph->DATAR = (*(SendBufStruct.p_s) & (uint16_t)0x01FF); //发送完成后  又触发中断发送后续字节USART_SendData(USART_Periph, *(SendBufStruct.p_s));++SendBufStruct.p_s; //增加发送指针}else{SendBufStruct.p_s = SendBufStruct.buf; //发送完全部字节后 各指针归位 清中断标志SendBufStruct.p_w = SendBufStruct.buf;//USART_ClearITPendingBit(USART_Periph, USART_IT_TC);}USART_ClearITPendingBit(USART_Periph, USART_IT_TC);}//接收if(USART_GetITStatus(USART_Periph, USART_IT_RXNE) == SET){/*处理接收中断*/dat = (uint8_t)USART_ReceiveData(USART_Periph);if(dat != END_CHAR && USART_ReceiveState == USART_ReceiveReady && byte_n < RECEIVE_BUF_SIZE-1){USART_Receive_Buf[byte_n] = dat;++byte_n;}else{USART_Receive_Buf[byte_n] = '\0';USART_ReceiveState = USART_ReceiveComplete; // 此时可以处理,处理完成之后设置为USART_ReceiveReady在接收后续字符byte_n = 0;}USART_ClearITPendingBit(USART_Periph, USART_IT_RXNE);}}void USART_SendByte(uint8_t Data)
{*(SendBufStruct.p_w) = Data;++SendBufStruct.p_w;if(SendBufStruct.p_s == SendBufStruct.buf){USART_SendData(USART_Periph, *(SendBufStruct.p_s));++SendBufStruct.p_s;}
}void USART_SendStr(const char* Data)
{while(*Data){*(SendBufStruct.p_w) = *Data;++SendBufStruct.p_w; //指向当前字符串最后一个字符++Data;}//判断是否需要重新发送第一个字节触发 "发送完成中断"if(SendBufStruct.p_s == SendBufStruct.buf){USART_SendData(USART_Periph, *(SendBufStruct.p_s)); //发送起始字节,发送完成后进入中断处理后续字节++SendBufStruct.p_s;}
}void USART_SendBuf(const uint8_t* Data, uint16_t size)
{const uint8_t* end = Data+size;while(Data < end){*(SendBufStruct.p_w) = *Data;++SendBufStruct.p_w; //指向当前字符串最后一个字符++Data;}//判断是否需要重新发送第一个字节触发 "发送完成中断"if(SendBufStruct.p_s == SendBufStruct.buf){USART_SendData(USART_Periph, *(SendBufStruct.p_s));++SendBufStruct.p_s;}
}static void Num_To_Str(int32_t num, char* strBuf)
{uint8_t NumLen = 0;uint32_t NumBak;uint8_t i,j;uint8_t NegativeActivateFlag = 0;if(num == 0){strBuf[0] = '0';strBuf[1] = '\0';return;}if(num < 0){NegativeActivateFlag = 1;num = -num;strBuf[0] = '-';}NumBak = num;//首先判断数字位数while(num != 0){++NumLen;num /= 10;}for(i = 0; i < NumLen; ++i){num = NumBak;for(j = i; j < NumLen-1; ++j){num /= 10;}if(NegativeActivateFlag){strBuf[i+1] = num%10 + '0';}else{strBuf[i] = num%10 + '0';}}if(NegativeActivateFlag){strBuf[i+1] = '\0';}else{strBuf[i] = '\0';}}void USART_SendNum(int32_t num)
{char strBuf[10+1] = {0};Num_To_Str(num, strBuf);USART_SendStr(strBuf);
}static uint8_t dec_to_hex_4(uint8_t Data)
{if((Data&0x0F) <= 9){return (Data&0x0F)+48;}else{return (Data&0x0F)+55;}}void USART_SendHex8(uint8_t Data)
{USART_SendByte( dec_to_hex_4(Data>>4) );USART_SendByte( dec_to_hex_4(Data) );USART_SendByte(' ');
}void USART_SendBin(uint32_t Data)
{uint32_t i;USART_SendByte('<');for (i = 0; i < 32; ++i){if(i!=0 && i%4 == 0){USART_SendByte('_');}if(Data&0x80000000){USART_SendByte('1');}else{USART_SendByte('0');}Data <<= 1;}USART_SendByte('>');USART_SendByte('\n');
}

main.c

#include "debug.h"
#include "ch32v10x.h"
#include "usart_buf.h"
#include "gpio_toggle.h"int main(void)
{uint16_t i = 0;Delay_Init();Delay_Ms(500);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);Init_GPIO_Toggle();Init_USART();while(1){if(USART_ReceiveState == USART_ReceiveComplete){USART_SendStr("Receive:");USART_SendStr(USART_Receive_Buf);USART_SendStr("\n");USART_ReceiveState = USART_ReceiveReady; //准备接收}if(i%50 == 0){//USART_SendStr("Hello World\n");GPIO_Toggle();}++i;//      USART_SendStr("World Hello\n");
//      USART_SendStr("Hello World\n");
//      USART_SendStr("123456\n");
//      USART_SendStr("654321\n");
//      USART_SendStr("aaaa5555\n");
//      USART_SendStr("8\n");
//      USART_SendBin(10);Delay_Ms(10);}
}

单片机非阻塞串口中断收发数据相关推荐

  1. tms320f28027 中断优先级_TMS320F28027 自带串口中断收发数据例子

    [实例简介] TMS320F28027自带有串口,利用串口中断与上位机(电脑)进行数据交换,软件设置成 上位机所发数据要以'*'结束. 仅供DSP板的学习所用,软件用的是CCS4.1,编译如果不能通过 ...

  2. 51单片机连接维特智能JY61串口6轴加速度陀螺仪(通过串口中断实现数据的现实)

    51单片机连接维特智能JY61串口6轴加速度陀螺仪(通过串口中断实现数据的现实) 1.JY61的初始化 利用USB转TTL模块连接只需要连接: 打开厂家赠送的上位机软件,模块出厂默认设置使用串口,波特 ...

  3. STM8S UART串口使用中断收发数据

    STM8S UART串口使用中断收发数据 原来调过STM8L的串口,逻辑简单,中断清晰,换成STM8S105K4后,虽然也是用STD库, 除去函数名.宏名等语言层面的差异以外,中断处理方面也有些不一样 ...

  4. Keil实例仿真AT89C51串口UART收发数据(附程序)

    目录 一.引言 二.所用软件 1.串口调试工具 2.虚拟串口软件 3.Keil μVision5 三.软件设置 1.串口调试助手软件设置 2.虚拟串口软件设置 3.Keil C51设置 A.调试(.i ...

  5. QT入门第十四天 串口通信协议+收发数据+波特率+数据位+停止位+奇偶校验+串口识别射频RFID的卡号

    QT入门第十四天 串口通信[QT入门第十四天 串口通信协议+收发数据+波特率+数据位+停止位+奇偶校验+串口识别射频RFID的卡号 第一章 常见的硬件通信接口协议 [1]硬件通信接口协议 [2]使用串 ...

  6. STM32F0系列串口DMA收发数据

    关于STM32F0系列串口DMA收发数据详解 这里用的库函数版本,芯片型号为stm32f030c8t6.在用到串口DMA时,要按以下几个步骤进行. 1.确定使用的串口号,这里,我用的是usart2,对 ...

  7. PHp批量推送数据太慢,PHP非阻塞批量推送数据-php教程

    明天看到论坛外面有人问如PHP何批量非梗阻向效劳器推送数据,这里大略总结下. 相干保举:<PHP教程> 一.最简略的方法: 一个剧本同时跑屡次,用参数来跑指定范畴.如果要推送10000用户 ...

  8. STM32G070RBT6基于STM32CubeMX创建串口中断接收数据

    STM32G070RBT6基于STM32CubeMX创建串口中断接收数据

  9. 单片机串口高效收发数据的实现方法

    想学习单片机的同学可以关注.私信我或者在评论区回复我要入门.这一期我们探讨传统数据收发不足之后,如何使用带FIFO的串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法:之后介绍一种特殊 ...

最新文章

  1. TFRecord tf.train.Feature
  2. php 文件管理系统_如何编写程序实现图书管理系统的个人图书借阅查询功能
  3. Activiti概述
  4. How does Spring @Transactional Really Work?--转
  5. 图像处理之log---log算子
  6. Java的IO:BIO | NIO | AIO
  7. 支付宝支付-手机浏览器H5支付
  8. Vue源码学习: 关于对Array的数据侦听
  9. 2022-2028年中国差旅管理行业市场全景调查及投资潜力研究报告
  10. 21世纪语言教程5c,21世纪核心素养5C模型
  11. ASIC和FPGA设计流程
  12. Ubuntu安装yum
  13. [轉]值得研究 邓亚萍代表的到底是哪个“国家”?
  14. Photoshop——更改图片比例
  15. 示波器界面的中英文切换
  16. 简单数据处理(相关系数,协方差,t检验)
  17. Unity3D 解决检测碰撞某类物体的一种方法
  18. 2022年中职网络空间安全国赛竞赛题解析仅代表自己的建议——2022年中职网络安全国赛竞赛试题9解析
  19. Java6、7章总结复习
  20. 针对等额本金还款模式的客户,写一个程序按顺序输入贷款总额(单位为万元)、月利率、贷款总月数,输出第一个月客户还款金额(单位为元,取整数)。

热门文章

  1. 一个实时显示系统时钟的android应用
  2. fedora安装vim可用
  3. CloudStack的创建
  4. 网秦发布2017年第一季度、第二季度及第三季度财报
  5. 农村包围城市的『快手』
  6. 全国计算机等级三级Linux应用与开发技术考试-第3章-Linux系统使用基础-练习题
  7. 视频识别之PC版车牌识别sdk
  8. 中国乳化机市场现状研究分析与发展前景预测报告
  9. C#文件拒绝访问。上传文件报错System.UnauthorizedAccessException: 对路径XXX的访问被拒绝。
  10. CSS选择器,盒子模型及浮动