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

目录

配置串口引脚

引脚图

中断优先级分组

使能时钟

配置中断优先级

配置串口

重写中断服务函数

清空中断标志位

获取中断标志位

接收函数

打印数据

例程

例程说明

main.h

main.c

usart.h

usart.c

配置串口引脚

引脚图

  1. 配置引脚号

  2. 配置引脚速度

  3. 配置引脚的模式

  4. 引脚初始化

cpp 复制代码
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

中断优先级分组

cpp 复制代码
/*
zu_bie:
	NVIC_PriorityGroup_0
	NVIC_PriorityGroup_1
	NVIC_PriorityGroup_2
	NVIC_PriorityGroup_3
	NVIC_PriorityGroup_4
*/
void NVIC_PriorityGroupConfig(zu_bie);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组

使能时钟

cpp 复制代码
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. 接收中断使能

cpp 复制代码
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. 串口使能

cpp 复制代码
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);//串口使能

重写中断服务函数

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

cpp 复制代码
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);
    }
}

清空中断标志位

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

cpp 复制代码
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);

USART_ClearITPendingBit(USART1,USART_IT_RXNE);

获取中断标志位

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

USART_GetITStatus(USART1, USART_IT_RXNE);

接收函数

cpp 复制代码
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

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

打印数据

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

cpp 复制代码
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和蜂鸣器,控制协议自定,比如:

0x01 Led1亮
0x02 Led1灭
0x08 Led2亮
0x09 Led2灭
0x15 蜂鸣器响
0x16 蜂鸣器不响

main.h

cpp 复制代码
#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

cpp 复制代码
#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 0a
						LED_R_NO();
						break;
					}
					case 0x02: {//aa 55 02 00 0d 0a
						LED_R_OFF();
						break;
					}
					case 0x08: {//aa 55 08 06 0d 0a
						LED_G_NO();
						break;
					}
					case 0x09: {//aa 55 09 07 0d 0a
						LED_G_OFF();
						break;
					}
					case 0x15: {//aa 55 15 13 0d 0a
						FengMingQi_NO();
						break;
					}
					case 0x16: {//aa 55 16 14 0d 0a
						FengMingQi_OFF();
						break;
					}
				}
			}
        }
    }
}

usart.h

cpp 复制代码
#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

cpp 复制代码
#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.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

    //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);//接收中断使能

    //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);
}
相关推荐
Chester_19994 分钟前
CSP202312C.树上搜索
开发语言·数据结构·c++·蓝桥杯·stl
艾芯微科技1 小时前
SKY13370‑374LF|0.5‑6GHz SPDT 射频开关,WLAN/LTE 射频前端实用器件
网络·单片机·嵌入式硬件·集成测试·51单片机
见叶之秋1 小时前
【C++】String类的使用(含模拟实现)
java·开发语言·c++
wuminyu2 小时前
Linux内核线程调度与虚拟线程调度机制系统级深度剖析
java·linux·c语言·jvm·c++
jianqiang.xue2 小时前
收官:从v0.1到“研发新常态“,一套嵌入式智能体的落地与边界
stm32·单片机·物联网·架构·esp32
HUI-4743 小时前
EG1131|SOT23‑6 30V/1.5A 电流模式同步降压 DC‑DC,小体积消费类电源优选
嵌入式硬件·硬件工程
天空'之城3 小时前
单片机基础核心知识点汇总(三十)
单片机·嵌入式硬件
笨笨饿3 小时前
#137_死机恢复现场_Armino平台AP系统swd调试
git·python·stm32·单片机·嵌入式硬件·物联网·vim
linnux领域3 小时前
面包板供电“插哪都不亮“?一个暗断点引发的排查——硬件新手三板斧
单片机·嵌入式硬件·esp32·arduino·面包板·硬件入门
Jaixln_HRF3 小时前
芯维尔CN8010 1.2A/6V同步降压转换器芯片,集成350/230mΩ MOSFET与1.5MHz高频,用于汽车电子/IoT/便携仪器
嵌入式硬件·物联网·硬件工程