基于stm32的简单串口通信

本文详细介绍了STM32使用USART进行串口通信的过程,包括硬件连接、NVIC初始化、GPIO配置、USART设置、中断服务函数以及在Keil工程中的实际应用,展示了如何连续发送数据并处理接收到的反馈。
摘要由CSDN通过智能技术生成

一、STM32串口通信USART

1.硬件原理图:

在这里插入图片描述

2.代码编写

(1)新建NVIC.h、NVIC.c、User_USART.h、User_USART.c、main.c 5个文件,将stm32f10x_it.c、stm32f10x_it.h、stm32f10x_conf.h拷贝到工程目录。
(2)NVIC.h
1 #ifndef __NVIC_H
2 #define __NVIC_H
3 
4 void User_NVIC_Config(void);
5 
6 
7 
8 #endif
(3)NVIC.c
#include "NVIC.h"
 2 #include "stm32f10x.h"
 3 
 4 void User_NVIC_Config(void)
 5 {
 6     NVIC_InitTypeDef NVIC_Config;
 7     
 8     //设置中断控制器优先级组类别
 9     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
10 
11     //初始化NVIC_InitTypeDef结构体
12     NVIC_Config.NVIC_IRQChannel = USART1_IRQn;
13     NVIC_Config.NVIC_IRQChannelPreemptionPriority = 1;
14     NVIC_Config.NVIC_IRQChannelSubPriority = 1;
15     NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
16 
17     //初始化NVIC中断控制器
18     NVIC_Init(&NVIC_Config);
19     
20 }
(4)User_USART.h
#ifndef __USER_USART_H
 2 #define __USER_USART_H
 3 #include "stm32f10x.h"
 4 
 5 void User_USART_GPIO_Config(void); //USART使用到的GPIO口设置
 6 void User_USART_Config(void);    //USART相关寄存器设置
 7 void User_USART_Send_Byte(USART_TypeDef* pUSARTX, uint8_t Data);     //向串口发送一个字节数据
 8 void User_UART_Send_String(USART_TypeDef* pUSARTX, char* str);        //向串口发送一个字符串数据,即可以发送包含多个字节的数据
 9 
10 
11 #endif
(5)User_USART.c
#include "User_USART.h"
 2 #include "stm32f10x.h"
 3 
 4 
 5 //USART使用到的GPIO口设置
 6 void User_USART_GPIO_Config(void)
 7 {
 8     GPIO_InitTypeDef USART_GPIO_TX,USART_GPIO_RX;
 9 
10     //先使能USART对应的GPIO口使用,USART使用的都是GPIOA组
11     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
12 
13     //初始化GPIO_InitTypeDef结构体--USART TX PIN
14     USART_GPIO_TX.GPIO_Mode = GPIO_Mode_AF_PP;
15     USART_GPIO_TX.GPIO_Pin = GPIO_Pin_9;
16     USART_GPIO_TX.GPIO_Speed = GPIO_Speed_50MHz;
17     
18     //设置USART TX PIN对应的控制寄存器
19     GPIO_Init(GPIOA, &USART_GPIO_TX);
20 
21     
22     //初始化GPIO_InitTypeDef结构体--USART RX PIN  此为输入,所以不用初始化速率GPIO_Speed成员
23     USART_GPIO_RX.GPIO_Mode = GPIO_Mode_IN_FLOATING;
24     USART_GPIO_RX.GPIO_Pin = GPIO_Pin_10;
25     
26     //设置USART RX PIN对应的控制寄存器
27     GPIO_Init(GPIOA, &USART_GPIO_RX);
28     
29 
30 }
31 
32 
33 //USART相关寄存器设置
34 void User_USART_Config(void)
35 {
36 
37     USART_InitTypeDef USART_Config;
38 
39     //使能USART1时钟
40     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
41 
42     //初始化USART_InitTypeDef结构体
43     USART_Config.USART_BaudRate = 115200;
44     USART_Config.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
45     USART_Config.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
46     USART_Config.USART_Parity = USART_Parity_No;
47     USART_Config.USART_StopBits = USART_StopBits_1;
48     USART_Config.USART_WordLength = USART_WordLength_8b;
49 
50     //设置USART1对应的寄存器
51     USART_Init(USART1, &USART_Config);
52 
53     //使能USART1 数据接收RXEN中断寄存器,即接收数据寄存器有数据可读时,RXEN寄存器产生中断
54     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
55 
56     //使能串口USART1,使其进行工作
57     USART_Cmd(USART1, ENABLE);
58     
59     
60 }
61 
62 
63 
64 //向串口发送一个字节数据
65 void User_USART_Send_Byte(USART_TypeDef* pUSARTX, uint8_t Data)
66 {
67 
68     //向数据寄存器写入8bit数据
69     pUSARTX->DR = (Data & (uint16_t)0x01FF);    
70 
71     //USART_GetFlagStatus检查数据是否发送完成
72     while(USART_GetFlagStatus(pUSARTX, USART_FLAG_TXE) == RESET);
73     
74 }
75 
76 
77 //向串口发送一个字符串数据,即可以发送包含多个字节的数据,char类型为8bit,其字符串中的每个字符都可用一个int数表示,即ASCII标准
78 void User_UART_Send_String(USART_TypeDef* pUSARTX, char* str)
79 {
80     int i;
81 
82     for(i = 0; i < sizeof(str); i++)
83     {
84         User_USART_Send_Byte(pUSARTX, *(str + i));
85 
86         //USART_GetFlagStatus检查多个数据是否发送完成
87         while(USART_GetFlagStatus(pUSARTX, USART_FLAG_TC) == RESET);
88 
89 
90     }
91 
92 }
(6)stm32f10x_it.h
void USART1_IRQHandler(void); //中断服务函数
(7)stm32f10x_it.c
//中断服务函数,前面在User_USART.c  void User_USART_Config(void)函数中
 2 //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);使能了数据接收中断,所以
 3 //将处理接收数据时的中断服务
 4 void USART1_IRQHandler(void)
 5 {
 6 
 7     uint8_t temp;
 8 
 9     if(USART_GetFlagStatus(USART1, USART_IT_RXNE) != RESET)
10     {
11         temp = USART_ReceiveData(USART1);
12         USART_SendData(USART1, temp);
13 
14 
15     }
16 
17 
18 }
(8)main.c
#include "NVIC.h"
 2 #include "User_USART.h"
 3 #include "stm32f10x.h"
 4 
 5 int main(void)
 6 {
 7 
 8     User_USART_GPIO_Config();
 9     User_NVIC_Config();
10     User_USART_Config();
11 
12     User_UART_Send_String(USART1, "test!\n");
13 
14     while(1)
15     {
16 
17     }
18 
19 }

3.结果展示

在这里插入图片描述

二、系统连续发送“hello”至win10

1.cubeMX工程

(1)芯片选择

在这里插入图片描述

(2)rcc设置

在这里插入图片描述

(3)sys设置

在这里插入图片描述

(4)usart设置

在这里插入图片描述

(5)nvic设置

在这里插入图片描述

(6)时钟设置

在这里插入图片描述

(7)创建项目

在这里插入图片描述

2.keil工程

main.c中添加代码
 char c;
  char message[]="hello windows\n";
  char tips[]="CommandError\n";
  char tips1[]="Start.....\n";
  char tips2[]="Stop.....\n";
  int flag=0;


在这里插入图片描述

HAL_UART_Receive_IT (&huart1,(uint8_t *)&c,1);

 if(flag==1){
		  HAL_UART_Transmit(&huart1 ,(uint8_t *)&message ,strlen(message),0xFFFF);
		  HAL_Delay (1000);
	  }

在这里插入图片描述

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(c=='0')
	{
		flag=0;
		 HAL_UART_Transmit(&huart1 ,(uint8_t *)&tips2 ,strlen(tips2),0xFFFF);
	}
	else if(c=='1')
	{
		flag=1;
		HAL_UART_Transmit(&huart1 ,(uint8_t *)&tips1 ,strlen(tips1),0xFFFF);
	}
	else{
		flag=0;
		HAL_UART_Transmit(&huart1 ,(uint8_t *)&tips ,strlen(tips),0xFFFF);
	}
	HAL_UART_Receive_IT (&huart1,(uint8_t *)&c,1);

在这里插入图片描述

3.结果展示

(1)烧录

在这里插入图片描述

(2)串口助手

在这里插入图片描述

三、keil中仿真波形图

1.设置

在这里插入图片描述

2.选中串口

在这里插入图片描述

3.结果

在这里插入图片描述

参考:
(https://www.pianshen.com/article/8285571527/)
(https://blog.csdn.net/qq_47281915/article/details/121053903)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基于STM32串口通信课程设计可以通过以下步骤实现: 1. 确定硬件平台:选择STM32F103单片机作为主控芯片,同时选择串口通信模块和LED模块作为外设。 2. 确定通信协议:选择虚拟串口软件实现串口助手与STM32的通信,可以使用常见的串口通信协议如UART、SPI等。 3. 实现LED控制:通过串口助手分别发送'A'、'B'、'C'控制三个LED亮;分别发送'a'、'b'、'c'控制三个LED灭。 4. 实现OLED显示:OLED显示通过串口接收到的字符数据,并且将收到的数据通过串口发送至串口助手端,实现串口双向通信。 5. 实现LoRa数据收发:使用Ra-01SC模组和LLCC68芯片实现LoRa数据的收发。 以下是一个基于STM32串口通信课程设计的代码示例: ```c #include "stm32f10x.h" #include "stdio.h" void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); } void USART1_SendChar(char ch) { while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1, (uint8_t)ch); } void USART1_SendString(char* str) { while (*str) { USART1_SendChar(*str++); } } char USART1_ReceiveChar(void) { while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (char)USART_ReceiveData(USART1); } int main(void) { char ch; USART1_Init(); LED_Init(); while (1) { ch = USART1_ReceiveChar(); switch (ch) { case 'A': GPIO_SetBits(GPIOC, GPIO_Pin_13); break; case 'B': GPIO_ResetBits(GPIOC, GPIO_Pin_13); break; case 'C': USART1_SendString("Hello World!\r\n"); break; default: break; } } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值