GD32F103VE串口中断发送和接收

GD32F103VE串口中断发送和接收,本程序基于RS485完成测试,实现将收到的数据,再发送出去。

#include "USART1_Interrupt.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
#include "Timer0.h"
#include "delay.h"uint8_t USART1_TX_Buffer[USART1_TX_Buffer_Size]; //USART1发送缓冲区数组;
uint8_t USART1_TX_Buffer_Send_Index=0;          //USART1_TX_Buffer[]的发送索引值;
uint8_t USART1_TX_Buffer_Load_Index=0;          //USART1_TX_Buffer[]的装载索引值
uint8_t USART1_TX_Completed_Flag;
uint8_t USART1_TX_Overtime_Conter;//USART1发送超时计数器uint8_t USART1_RX_Buffer[USART1_RX_Buffer_Size]; //USART1接收缓冲区数组
uint8_t USART1_RX_Buffer_Load_Index;          //USART1_RX_Buffer[]的装载索引值
uint8_t USART1_RX_Time_Count;                 //USART1接收时间计数器
uint8_t USART1_RX_Completed_Flag;void GD32F103_USART1_Init(unsigned int bound);
void RS485_RX_END(void);
void USART1_Load_Send_Data(void);void RS485_Enable_Output_Init(void)
{rcu_periph_clock_enable(RCU_GPIOA);  //使能GPIOA时钟,enable GPIO clock gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);//将GPIOA1设置为输出上拉RS485_ENABLE_PIN_Output_High();
}//函数功能:初始化串口1,这个和STM32F103VET6的USART2兼容
void GD32F103_USART1_Init(unsigned int bound)
{//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"nvic_irq_enable(USART1_IRQn,0,0);//设置USART1_IRQn的中断优先级,抢占优先级为0,子优先级为0,USART interrupt configuration串口初始化开始/rcu_periph_clock_enable(RCU_GPIOA);  //使能GPIOA时钟,enable GPIO clock rcu_periph_clock_enable(RCU_USART1); //使能USART1时钟,enable USART clockgpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);//将GPIOA2设置为AFIO口(复用IO口),输出上拉gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);//将GPIOA3设置为浮空输入口RS485_Enable_Output_Init();usart_deinit(USART1);                        //复位USART1,USART configureusart_baudrate_set(USART1,bound);          //设置USART1的波特率usart_word_length_set(USART1,USART_WL_8BIT); //设置USART1数据传输格式为8位usart_stop_bit_set(USART1,USART_STB_1BIT);   //设置USART1停止位为1位usart_parity_config(USART1,USART_PM_NONE);   //设置USART1无需奇偶校验usart_hardware_flow_rts_config(USART1,USART_RTS_DISABLE);  //设置不使能USART1的RTS引脚功能usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE); //设置不使能USART1的CTS引脚功能usart_receive_config(USART1, USART_RECEIVE_ENABLE);//根据USART_RECEIVE_ENABLE,设置串口控制寄存器USART_CTL0的串口接收使能usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);//根据USART_TRANSMIT_ENABLE,设置串口控制寄存器USART_CTL0的串口发送使能usart_enable(USART1);//使能串口模块
串口初始化结束/usart_interrupt_enable(USART1, USART_INT_RBNE);//根据USART_INT_RBNE指定,使能串口接收寄存区为非空时产生中断//read data buffer not empty interrupt and overrun error interrupt//enable USART1 receive interrupt/在串口中断服务函数中发送数据配置开始//usart_interrupt_disable(USART1, USART_INT_TBE);//根据USART_INT_TBE指定,不使能串口发送缓冲区为空中断//Disnables Transmit Data Register empty interruptusart_interrupt_enable(USART1, USART_INT_TC);//根据USART_INT_TC指定,使能串口发送完成中断//transmission complete interrupt
/在串口中断服务函数中发送数据配置结束//Timer_Interrupt_Initializtion(TIMER0,1000,108);//当arr=500,psc=108时,则为1ms,误差为1us;
}void RS485_RX_END(void)
{if(USART1_RX_Time_Count>0){USART1_RX_Time_Count++;if(USART1_RX_Time_Count>3){if( USART1_RX_Buffer[0]=='1' )//地址正确{USART1_RX_Completed_Flag = 1; //变频器响应正确USART1_TX_Completed_Flag = 0; //允许再次发送数据USART1_RX_Buffer[USART1_RX_Buffer_Load_Index]='\r';USART1_RX_Buffer[USART1_RX_Buffer_Load_Index+1]='\n';USART1_RX_Buffer[USART1_RX_Buffer_Load_Index+2]='\0';strcpy((char*)USART1_TX_Buffer,(char*)USART1_RX_Buffer);//将收到的数据发送出去USART1_Load_Send_Data();}else{USART1_RX_Completed_Flag = 2; //变频器响应错误,需要重新发送命令USART1_TX_Completed_Flag = 0; //允许再次发送数据}USART1_RX_Buffer_Load_Index = 0;USART1_RX_Time_Count = 0;}}
}
#ifndef __USART1_Interrupt_H
#define __USART1_Interrupt_H#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t#define RS485_Enable_Output 		       PAout(1)
#define RS485_ENABLE_PIN_Output_High() GPIO_BOP(GPIOA)=GPIO_PIN_1  //定义RS485串口使能脚输出高电平
#define RS485_ENABLE_PIN_Output_Low()  GPIO_BC(GPIOA)=GPIO_PIN_1   //定义RS485串口使能脚输出低电平
#define RS485_ENABLE_PIN_Toggle() gpio_bit_write( GPIOA,GPIO_PIN_1,(bit_status)((1-gpio_input_bit_get(GPIOA,GPIO_PIN_1))) )
//GA1取反输出电平#define USART1_TX_Buffer_Size 		      15
extern uint8_t USART1_TX_Buffer[USART1_TX_Buffer_Size];
extern uint8_t USART1_TX_Buffer_Send_Index;//USART1_TX_Buffer[]的发送索引值;
extern uint8_t USART1_TX_Buffer_Load_Index;//USART1_TX_Buffer[]的装载索引值
extern uint8_t USART1_TX_Completed_Flag;
extern uint8_t USART1_TX_Overtime_Conter;//USART1发送超时计数器#define USART1_RX_Buffer_Size 		      125
extern  uint8_t USART1_RX_Buffer[USART1_RX_Buffer_Size]; //USART1接收缓冲区数组
extern uint8_t USART1_RX_Buffer_Load_Index;          //USART1_RX_Buffer[]的装载索引值
extern uint8_t USART1_RX_Time_Count;                 //USART1接收时间计数器
extern uint8_t USART1_RX_Completed_Flag;extern void GD32F103_USART1_Init(unsigned int bound);
extern void RS485_RX_END(void);
extern void USART1_Load_Send_Data(void);#endif
#include "Timer0.h"
#include "USART1_Interrupt.h"void Timer_Interrupt_Initializtion(uint32_t timer_periph,uint16_t arr,uint16_t psc);//函数功能:通用定时器0中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//Timer_Interrupt_Initializtion(TIMER0,50000,1080);//当arr=50000,psc=1080时,则为500ms,误差为10us;
//Timer_Interrupt_Initializtion(TIMER0,1000,108);//当arr=500,psc=108时,则为1ms,误差为1us;
//计算公式:arr*psc/108000000/1,当arr=250,psc=108时,则为0.25ms,误差为1us;
void Timer_Interrupt_Initializtion(uint32_t timer_periph,uint16_t arr,uint16_t psc)
{timer_parameter_struct TimerParameterStruct;switch(timer_periph){case TIMER0:rcu_periph_clock_enable(RCU_TIMER0);      //使能TIMER0的APB2外设时钟nvic_irq_enable(TIMER0_UP_IRQn, 2U, 0U);  //设置TIMER0_UP_IRQn的中断优先级,抢占优先级为2,子优先级为0break;case TIMER1:rcu_periph_clock_enable(RCU_TIMER1);nvic_irq_enable(TIMER1_IRQn, 2U, 0U);  //设置TIMER1_IRQn的中断优先级,抢占优先级为2,子优先级为0break;case TIMER2:rcu_periph_clock_enable(RCU_TIMER2);nvic_irq_enable(TIMER2_IRQn, 2U, 0U);  //设置TIMER2_IRQn的中断优先级,抢占优先级为2,子优先级为0break;case TIMER3:rcu_periph_clock_enable(RCU_TIMER3);nvic_irq_enable(TIMER3_IRQn, 2U, 0U);  //设置TIMER3_IRQn的中断优先级,抢占优先级为2,子优先级为0break;case TIMER4:rcu_periph_clock_enable(RCU_TIMER4);nvic_irq_enable(TIMER4_IRQn, 2U, 0U);  //设置TIMER4_IRQn的中断优先级,抢占优先级为2,子优先级为0break;case TIMER5:rcu_periph_clock_enable(RCU_TIMER5);nvic_irq_enable(TIMER5_IRQn, 2U, 0U);  //设置TIMER5_IRQn的中断优先级,抢占优先级为2,子优先级为0break;case TIMER6:rcu_periph_clock_enable(RCU_TIMER6);nvic_irq_enable(TIMER6_IRQn, 2U, 0U);  //设置TIMER6_IRQn的中断优先级,抢占优先级为2,子优先级为0break;default:break;}timer_deinit(timer_periph);                 //复位TIMERxTIMERx配置开始TimerParameterStruct.period            = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TimerParameterStruct.prescaler         = psc-1; //设置用来作为TIMx时钟频率除数的预分频值(APB2时钟分频值)TimerParameterStruct.clockdivision     = TIMER_CKDIV_DIV1;   //设置时钟分母值为1//计算公式:arr*psc/108000000/1,当arr=250,psc=108时,则为0.25ms,误差为1us;TimerParameterStruct.counterdirection  = TIMER_COUNTER_UP;   //设置计数方向为"向上计数"TimerParameterStruct.alignedmode       = TIMER_COUNTER_EDGE; //设置为无中央对齐计数模式(边沿对齐模式)TimerParameterStruct.repetitioncounter = 0;                  //设置"重复计数次数"为0timer_init(timer_periph,&TimerParameterStruct);//根据TimerParameterStruct所指向的参数初始化TIMERx的时间基数单位
TIMERx配置结束timer_counter_value_config(timer_periph,0);//设置TIMERx的计数器初始值为0//timer_counter_read(timer_periph);//读取TIMERx的计数器值timer_auto_reload_shadow_enable(timer_periph);//使能TIMERx自动重装载timer_flag_clear(timer_periph,TIMER_FLAG_UP);               //清除"TIMERx更新标志位"timer_interrupt_flag_clear(timer_periph,TIMER_INT_FLAG_UP); //清除"TIMERx更新中断标志位"timer_interrupt_enable(timer_periph,TIMER_INT_UP);          //使能"TIMERx更新"产生中断timer_internal_clock_config(timer_periph);//设置"内部时钟"作为定时器时钟//timer_slave_mode_select(timer_periph,TIMER_SLAVE_MODE_DISABLE);//设置"关闭从模式",如果TIMER计数器使能,则预分频器直接由内部时钟驱动timer_enable(timer_periph);//TIMERx计数器使能,开始工作
}//函数功能:TIMER0更新中断服务程序
void TIMER0_UP_IRQHandler(void)
{if( timer_interrupt_flag_get(TIMER0,TIMER_INT_FLAG_UP) )// 读取更新中断标志位{RS485_RX_END();//判断变频器接收是否完成timer_flag_clear(TIMER0,TIMER_FLAG_UP);               //清除"TIMER0更新标志位"timer_interrupt_flag_clear(TIMER0,TIMER_INT_FLAG_UP); //清除"更新中断标志位"}
}

main.c如下:

#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t,bool
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()#include "delay.h"
#include "USART1_Interrupt.h"const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
int main(void)
{//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"INTX_ENABLE();//开启所有中断delay_init();//初始化延迟函数GD32F103_USART1_Init(115200);strcpy((char*)USART1_TX_Buffer,CPU_Reset_REG);USART1_Load_Send_Data();while(1){}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/28832.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Zabbix监控华为交换机DHCP接口地址池

一、背景 最近工作中遇到一个因为DHCP地址池满载、导致用户无法获取到IP地址的故障,所以在想通过zabbix 监控DHCP地址池的状态、当DHCP 地址池数量小于某个值时触发zabbix告警。 网上找了一下没有相关的文档、和对应的OID值、于是用Python 脚本的方式实现 二、实现效…

电视盒子哪个牌子好?拆机达人揭晓电视盒子品牌排行榜

老赵每天会对各种类型的数码产品进行拆机,对硬件、品控这块非常熟悉,近期很多朋友问我电视盒子哪个牌子好,我整理了目前市面上硬件、软件都表现不错的电视盒子品牌排行榜,看看目前最值得入手的电视盒子都有哪些。 第一&#xff1a…

无涯教程-Perl - getnetent函数

描述 此函数从/etc/networks文件获取下一个条目,返回-($name,$aliases,$addrtype,$net) 如果/etc/networks文件为空,则它将不返回任何内容,并且调用将失败。 语法 以下是此函数的简单语法- getnetent返回值 此函数在错误时返回undef,否则在标量context中返回网络地址,在错…

第九次作业

1. SSL工作过程是什么? 当客户端向一个 https 网站发起请求时,服务器会将 SSL 证书发送给客户端进行校验,SSL 证书中包含一个公钥。校验成功后,客户端会生成一个随机串,并使用受访网站的 SSL 证书公钥进行加密&#xf…

手搓单链表

文章目录 前言一、链表和顺序表的区别二、什么是单链表单链表分类单链表的结构 三、带头不循环单链表1.单链表的结构体2.带头不循环单链表的初始化和销毁3.带头不循环单链表的头插,尾插和打印4.带头不循环单链表的头删和尾删5.带头不循环单链表的查找,指…

进程通信常见方式

目录 通信通信概述 通信的主要方式 进程同步机制--低级进程通信 高级通信工具 共享存储器系统(Shared-Memory System) 管道(pipe)通信系统 客户机-服务器系统(Client-Server system)---套接字(Socket) 客户机-服务器系统(Client-Serv…

国内什么牌子的ipad手写笔好用?适合绘画电容笔推荐

对于那些想要用ipad来学习的人来说,苹果Pencil是必不可少的。但是,Apple Pencil的价格真的太贵了,以至于很多人都买不起。所以,最好的办法就是选用一支平替的电容笔。本人从前几年就开始使用iPad,同时本身也是一位数码…

冠达管理:创新药概念强势拉升,康希诺大涨超15%

立异药概念9日盘中强势拉升,到发稿,昊帆生物“20cm”涨停,康希诺大涨超15%,翰宇药业涨近13%,德展健康涨停,泰格医药、药石科技涨超7%。 康希诺昨日晚间公告,8月7日,公司与 AstraZene…

【三维重建】【深度学习】windows10下instant-nsr-pl代码Pytorch实现

【三维重建】【深度学习】windows10下instant-nsr-pl代码Pytorch实现 提示:基于 Instant-NGP 和 Pytorch-Lightning 框架的神经表面重建 文章目录 【三维重建】【深度学习】windows10下instant-nsr-pl代码Pytorch实现前言instant-nsr-pl模型运行下载源码并安装环境训练instant-…

那些没人教你的Jmeter 循环断言,百度不到的,收藏一下吧

前言 对于使用jmeter工具完成接口测试的测试工程师而言。在工作中,或者在面试中,都会遇到一个问题。 CSV文档做了一大笔测试数据后,怎么去校验这个结果呢? 现在大部分测试工程师可能都是通过人工的方法去查看结果,十几…

java中javamail发送带附件的邮件实现方法

java中javamail发送带附件的邮件实现方法 本文实例讲述了java中javamail发送带附件的邮件实现方法。分享给大家供大家参考。具体分析如下: JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它…

网络安全 Day27-运维安全项目-堡垒机部署

运维安全项目-堡垒机部署 1. 运维安全项目-架构概述2. 运维安全项目之堡垒机2.1 堡垒机概述2.2 堡垒机选型2.3 环境准备2.4 部署Teleport堡垒机2.4.1 下载与部署2.4.2 启动2.4.3 浏览器访问teleport2.4.4 进行配置2.4.5 安装teleport客户端 2.5 teleport连接服务器 1. 运维安全…

Elasticsearch官方测试数据导入

一、数据准备 百度网盘链接 链接:https://pan.baidu.com/s/1rPZBvH-J0367yQDg9qHiwQ?pwd7n5n 提取码:7n5n文档格式 {"index":{"_id":"1"}} {"account_number":1,"balance":39225,"firstnam…

【音视频】vms布署说明

目录 外场布署场景(99%) 研发实验场景(1%) 高级玩法 证书安装方法 外场布署场景(99%) 下面两种场景,为本产品主要应用场景,2023-08-08日后(统一所有证书)…

C++ 函数模板与类模板

C最重要的特性之一就是代码重用,为了实现代码重用,代码必须具有通用性。通用代码应不受数据类型的影响,并且可以自动适应数据类型的变化。这种程序设计类型称为参数化程序设计。模板是C支持参数化程序设计的工具,通过它可以实现参…

前端进阶js02----null和undefined的区别

1.相同点 1)都是原始类型的值且保存在栈中。 2) 在布尔运算中都会被认为是false 2.不同点 1)null是js的关键字,表示空值;undefined不是关键字,是一个全局变量。 2)值相同,但类型不一样 值相同&#xff1a…

考研算法第40天:众数 【模拟,简单题】

题目 本题收获 又是一道比较简单的模拟题,就不说解题思路了,说一下中间遇到的问题吧,就是说cin输入它是碰到空格就停止输入的,详细的看下面这篇博客对于cin提取输入流遇到空格的问题_while(cin) 空格_就是那个党伟的博客-CSDN博…

为什么都劝年轻人不要频繁跳槽?

"为什么都劝年轻人不要频繁跳槽?"这句话绝对正确,没有任何漏洞,无论如何解释都是正确的,因为“频繁”这个词是非常主观的,有很大的弹性。 不同的人对于跳多少次才算频繁有不同的看法,有人认为一…

大数据培训课程-《机器学习从入门到精通》上新啦

《机器学习从入门到精通》课程是一门专业课程,面向人工智能技术服务,课程系统地介绍了Python编程库、分类、回归、无监督学习和模型使用技巧以及算法和案例充分融合。 《机器学习从入门到精通》课程亮点: 课程以任务为导向,逐步学…

Python自动化测试用例:如何优雅的完成Json格式数据断言

目录 前言 直接使用 优化 封装 小结 进阶 总结 资料获取方法 前言 记录Json断言在工作中的应用进阶。 直接使用 很早以前写过一篇博客,记录当时获取一个多级json中指定key的数据: #! /usr/bin/python # coding:utf-8 """ aut…