【STM32F103ZET6——库函数】4.串口通讯

news/2025/3/5 0:32:28/

目录

配置串口引脚

引脚图

中断优先级分组

使能时钟

配置中断优先级

配置串口

重写中断服务函数

清空中断标志位

获取中断标志位

接收函数

打印数据

例程

例程说明

main.h

main.c

usart.h

usart.c

配置串口引脚

引脚图

  1. 配置引脚号

  2. 配置引脚速度

  3. 配置引脚的模式

  4. 引脚初始化  

GPIO_InitTypeDef GPIO;//USART1_TX   GPIOA.9
GPIO.GPIO_Pin = GPIO_Pin_9; //PA9
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
GPIO_Init(GPIOA, &GPIO);//初始化GPIOA9//USART1_RX	  GPIOA.10初始化
GPIO.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO);//初始化GPIOA.10

中断优先级分组

/*
zu_bie:NVIC_PriorityGroup_0NVIC_PriorityGroup_1NVIC_PriorityGroup_2NVIC_PriorityGroup_3NVIC_PriorityGroup_4
*/
void NVIC_PriorityGroupConfig(zu_bie);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组

使能时钟

void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟

配置中断优先级

  1. 配置中断的串口

  2. 配置抢占优先级

  3. 配置子优先级

  4. 通道使能

  5. 接收中断使能

void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);//接收中断使能NVIC_InitTypeDef ZhongDuan;
//Usart1 NVIC 配置
ZhongDuan.NVIC_IRQChannel = USART1_IRQn;
ZhongDuan.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1
ZhongDuan.NVIC_IRQChannelSubPriority = 1;		//子优先级1
ZhongDuan.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
NVIC_Init(&ZhongDuan);	//根据指定的参数初始化VIC寄存器
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//接收中断使能

配置串口

  1. 配置波特率

  2. 配置数据模式

  3. 配置停止位

  4. 配置奇偶校验位

  5. 配置硬件流传输

  6. 配置收发模式

  7. 串口初始化

  8. 串口使能

void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);//串口使能USART_InitTypeDef ChuanKou;
//USART 初始化设置
ChuanKou.USART_BaudRate = bound;//串口波特率
ChuanKou.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
ChuanKou.USART_StopBits = USART_StopBits_1;//一个停止位
ChuanKou.USART_Parity = USART_Parity_No;//无奇偶校验位
ChuanKou.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
ChuanKou.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
USART_Init(USART1,&ChuanKou);//串口初始化
USART_Cmd(USART1,ENABLE);//串口使能

重写中断服务函数

        注意:中断服务函数的函数已经固定,重新定义相同名字的函数即可,在定义好的函数里写中断的操作,哪个串口发生中断就得重定义哪个串口中断的函数

void USART1_IRQHandler();void USART1_IRQHandler(void)                	//串口1中断服务程序
{u8 JiaoYan_Wei=0;u8 j;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res =USART_ReceiveData(USART1);	//读取接收到的数据data[flag_1]=Res;flag_1++;if(flag_1==6) {flag_1=0;flag=1;}USART_ClearITPendingBit(USART1,USART_IT_RXNE);}
}

清空中断标志位

在中断服务函数里进行操作。

void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);USART_ClearITPendingBit(USART1,USART_IT_RXNE);

获取中断标志位

/*
不仅会判断标志位是否置1,同时还会判断是否使能了相应的中断
*/
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);USART_GetITStatus(USART1, USART_IT_RXNE);

接收函数

uint16_t USART_ReceiveData(USART_TypeDef* USARTx);Res =USART_ReceiveData(USART1);	//读取接收到的数据

打印数据

注意:得加上下面函数,才能像C语言那样打印到终端,在这里是打印到串口调试助手上

int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return (ch);
}

例程

例程说明

1.编写主程序,初始化串口1,设置波特率为9600,无校验,数据位8位,停止位1位。

2.编写中断服务程序代码实现将接收到的数据保存下来。

3、数据格式为0xaa,0x55,0xxx(有效控制字节), 校验字节(前数相加-1),0x0d,0x0a 。(前两个是头码,后两个是结束码)

4.分析保存的数据,如果数据正确,则将控制单片机进行对应的动作,并把收到的数据发回。

5、.控制动作包括led1、led2和蜂鸣器,控制协议自定,比如:

0x01Led1亮
0x02Led1灭
0x08Led2亮
0x09Led2灭
0x15蜂鸣器响
0x16蜂鸣器不响

main.h

#ifndef _MAIN_H_
#define _MAIN_H_#include "stm32f10x.h"                  // Device header
#include "stm32f10x_gpio.h"             // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_tim.h"              // Keil::Device:StdPeriph Drivers:TIM
#include <stm32f10x_rcc.h>
#include <stm32f10x_usart.h>
#include <stm32f10x_sdio.h>
#include <misc.h>
#include <stdio.h>
#include <delay.h>
#include "timch.h"
#include "bsp_SysTick.h"#include "led.h"
#include "Key.h"
#include "usart.h"
#include "FengMingQi.h"#endif

main.c

#include "main.h"extern u8 data[6];
extern u8 flag_1;
extern u8 flag;int main() {u8 key_num;u8 FMQ=0;u8 j;u8 JiaoYan_Wei=0;uart_init(9600);LED_Init();Key_Init();FengMingQi_Init();while(1) {if(flag==1){flag=0;	printf("\rok\n%x %x %x %x %x %x",data[0],data[1],data[2],data[3],data[4],data[5]);JiaoYan_Wei=data[0]+data[1]+data[2]-1;if((data[0]==0xaa)&&(data[1]==0x55)&&(JiaoYan_Wei==data[3])&&(data[4]==0x0d)&&(data[5]==0x0a)){switch(data[2]) {case 0x01: {//aa 55 01 ff 0d 0aLED_R_NO();break;}case 0x02: {//aa 55 02 00 0d 0aLED_R_OFF();break;}case 0x08: {//aa 55 08 06 0d 0aLED_G_NO();break;}case 0x09: {//aa 55 09 07 0d 0aLED_G_OFF();break;}case 0x15: {//aa 55 15 13 0d 0aFengMingQi_NO();break;}case 0x16: {//aa 55 16 14 0d 0aFengMingQi_OFF();break;}}}}}
}

usart.h

#ifndef __USART_H
#define __USART_H#include "stdio.h"
#include "sys.h"
#include "led.h"
#include "FengMingQi.h"
#include "delay.h"extern u8 Res;void uart_init(u32 bound);
void USART1_IRQHandler();#endif

usart.c

#include "usart.h"void uart_init(u32 bound) {//GPIO端口设置GPIO_InitTypeDef GPIO;USART_InitTypeDef ChuanKou;NVIC_InitTypeDef ZhongDuan;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟//USART1_TX   GPIOA.9GPIO.GPIO_Pin = GPIO_Pin_9; //PA9GPIO.GPIO_Speed = GPIO_Speed_50MHz;GPIO.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出GPIO_Init(GPIOA, &GPIO);//初始化GPIOA9//USART1_RX	  GPIOA.10初始化GPIO.GPIO_Pin = GPIO_Pin_10;//PA10GPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO);//初始化GPIOA.10//Usart1 NVIC 配置ZhongDuan.NVIC_IRQChannel = USART1_IRQn;ZhongDuan.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1ZhongDuan.NVIC_IRQChannelSubPriority = 1;		//子优先级1ZhongDuan.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能NVIC_Init(&ZhongDuan);	//根据指定的参数初始化VIC寄存器USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//接收中断使能//USART 初始化设置ChuanKou.USART_BaudRate = bound;//串口波特率ChuanKou.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式ChuanKou.USART_StopBits = USART_StopBits_1;//一个停止位ChuanKou.USART_Parity = USART_Parity_No;//无奇偶校验位ChuanKou.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制ChuanKou.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式USART_Init(USART1,&ChuanKou);//串口初始化USART_Cmd(USART1,ENABLE);//串口使能
}u8 data[6];
u8 Res;
u8 flag_1=0;
u8 flag;void USART1_IRQHandler(void)                	//串口1中断服务程序
{u8 JiaoYan_Wei=0;u8 j;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res =USART_ReceiveData(USART1);	//读取接收到的数据data[flag_1]=Res;flag_1++;if(flag_1==6) {flag_1=0;flag=1;}USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除中断标志位}
}int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return (ch);
}

http://www.ppmy.cn/news/1576684.html

相关文章

【面经】CPP经典面试手撕{LRUCache、字典树、布隆过滤器}

文章目录 LRUCache字典树布隆过滤器 LRUCache class LRUCache {using ListIt list<pair<int, int>>::iterator;list<pair<int, int>> _LRUlist;int _capacity;unordered_map<int, ListIt> _hashmap;public:LRUCache(int capacity) : _capacity(…

物联网水位计集成GPS

在物联网&#xff08;IoT&#xff09;应用中&#xff0c;将水位计与 GPS&#xff08;全球定位系统&#xff09; 集成&#xff0c;可以为水位监测系统增加地理位置信息&#xff0c;从而提升数据的空间维度和应用价值。以下是集成GPS的水位计的详细功能、优势和应用场景&#xff…

LeetCode 148:排序链表 (Sort Linked List)

题目描述&#xff1a; 给定一个单链表 head&#xff0c;将其按升序排序并返回排序后的链表。 输入条件&#xff1a; 链表长度不固定&#xff08;可为空&#xff09;。需要在O(n log n)时间复杂度和O(1)空间复杂度下完成 原地排序&#xff08;特别限制&#xff09;。 题解与思路…

【动态规划学习】区间dp

区间dp概述 区间dp&#xff0c;就是在一段区间上进行动态规划&#xff0c;求解一段区间的最优解。最后合并小区间上的最优解从而得到全局最优解的算法。 【问题引入】 石子合并问题 N堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的两堆石子合并成新的…

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_cycle 函数 - 详解(4)

详解&#xff08;4&#xff09; 初始化配置转储结构&#xff08;config_dump&#xff09; if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t))! NGX_OK){ngx_destroy_pool(pool);return NULL;}ngx_rbtree_init(&cycle->config_dump_rb…

第十三届蓝桥杯大赛软件赛决赛C/C++ 大学 B 组

A 【2022——暴力DP / 优雅背包】-CSDN博客 B 【钟表——类日期问题】-CSDN博客 C 【卡牌——二分】-CSDN博客 D 【最大数字——DFS】-CSDN博客 E 【出差——Dijkstra】-CSDN博客 F 【费用报销——01背包】-CSDN博客 G 【故障——条件概率】-CSDN博客 H 【机房—…

Oracle 数据库基础入门(四):分组与联表查询的深度探索(下)

在 Oracle 数据库的操作中&#xff0c;联合查询与子查询是获取复杂数据的关键手段。当单表数据无法满足业务需求时&#xff0c;联合查询允许我们从多张表中提取关联信息&#xff0c;而子查询则能以嵌套的方式实现更灵活的数据筛选。对于 Java 全栈开发者而言&#xff0c;掌握这…

服务异步通讯与RabbitMQ

服务异步通讯 文章目录 服务异步通讯MQRabbitMQ1、安装&#xff08;部署&#xff09;2、结构3、消息模型4、SpringAMQP4.1、基本消息队列4.2、工作消息队列4.3、发布订阅模型4.3.1、FanoutExchange&#xff08;广播类型的交换机&#xff09;4.3.2、DirectExchange&#xff08;路…