打印
[其他ST产品]

STM32串口发送接收数据

[复制链接]
934|36
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1.串口通信

我用的32是stm32f10x最小系统没有UART4和UART5
USART : 通用同步异步收发器
UART : 通用异步收发器
nRTS : 请求发送
nCTS : 请求接收
区别:USART指单片机的一个IO端口模块,可以根据需要配置成同步模式(SPI,IIC),也可以配置成异步模式(UART).可以理解为USART为SPI,IIC对等的”协议”。 UART则不是一个协议,为一个实体。


使用特权

评论回复
沙发
在水一方00|  楼主 | 2023-9-24 00:43 | 只看该作者
串口的结构体

使用特权

评论回复
板凳
在水一方00|  楼主 | 2023-9-24 00:43 | 只看该作者

Fck : 串口的时钟(APB1 36M / APB2 72M )
USARTDIV : 无符号的定点数

115200= 72 * 1000000/16 * USARTDIV

使用特权

评论回复
地板
在水一方00|  楼主 | 2023-9-24 00:44 | 只看该作者
3.如何配置串口的发送
1.配置时钟: GPIO口的时钟,串口的时钟, 引脚复用的时钟
2.配置GPIO的结构体
3.配置串口的结构体
4.串口的发送

使用特权

评论回复
5
在水一方00|  楼主 | 2023-9-24 00:44 | 只看该作者

4.通过串口向电脑发送ok字符
按照上面的四个步骤进行编写
我们会发现只能一个一个发送字符,比较麻烦,所以后面封装了一个可以发送字符串的函数。
usart.c

使用特权

评论回复
6
在水一方00|  楼主 | 2023-9-24 00:44 | 只看该作者
#include "usart.h"
#include "stm32f10x.h"

void usart_init(void)
{
        GPIO_InitTypeDef gpio_init;
        USART_InitTypeDef usartStruct;
       
        //1.ÅäÖÃʱÖÓ£ºGPIO¿ÚµÄʱÖÓ£¬Òý½Å¸´ÓõÄʱÖÓ£¬´®¿ÚµÄʱÖÓ
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
       
        //2.ÅäÖÃGPIOµÄ½á¹¹Ìå
        //2.1 TX
        gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
        gpio_init.GPIO_Pin = GPIO_Pin_9;
        gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
       
        GPIO_Init(GPIOA,&gpio_init);
       
        //2.2 RX
        gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        gpio_init.GPIO_Pin = GPIO_Pin_10;
       
        GPIO_Init(GPIOA,&gpio_init);
       
        //3.ÅäÖô®¿ÚµÄ½á¹¹Ìå
        usartStruct.USART_BaudRate = 115200;
        usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        usartStruct.USART_Parity = USART_Parity_No;
        usartStruct.USART_StopBits = USART_StopBits_1;
        usartStruct.USART_WordLength = USART_WordLength_8b;
       
        USART_Init(USART1,&usartStruct);
        USART_Cmd(USART1, ENABLE );
       
}

使用特权

评论回复
7
在水一方00|  楼主 | 2023-9-24 00:45 | 只看该作者
usart.h
#include "stm32f10x.h"

void usart_init(void);

使用特权

评论回复
8
在水一方00|  楼主 | 2023-9-24 00:45 | 只看该作者
main.c

#include "stm32f10x.h"
#include "led.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "usart.h"

void delay(uint16_t time)
{
        uint16_t i =0;
        while(time--){
                i=12000;
                while(i--);
        }
}

int main()
{
        usart_init();
       
        while(1)
        {
                USART_SendData(USART1,'n');
                //ÏÂÃæUSART_GetFlagStatusΪÁËÅжÏÊý¾Ý¼Ä´æÆ÷ÊÇ·ñΪ¿Õ
                while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                USART_SendData(USART1,'t');
                while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                USART_SendData(USART1,'\n');
                while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                delay(1000);
        }

}

使用特权

评论回复
9
在水一方00|  楼主 | 2023-9-24 00:45 | 只看该作者

使用特权

评论回复
10
在水一方00|  楼主 | 2023-9-24 00:45 | 只看该作者
封装发送字符串函数
注意:在封装发送字符串函数时,while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);是为了把数据发送完
usart.c
#include "usart.h"
#include "stm32f10x.h"

void usart_init(void)
{
        GPIO_InitTypeDef gpio_init;
        USART_InitTypeDef usartStruct;
       
        //1.ÅäÖÃʱÖÓ£ºGPIO¿ÚµÄʱÖÓ£¬Òý½Å¸´ÓõÄʱÖÓ£¬´®¿ÚµÄʱÖÓ
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
       
        //2.ÅäÖÃGPIOµÄ½á¹¹Ìå
        //2.1 TX
        gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
        gpio_init.GPIO_Pin = GPIO_Pin_9;
        gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
       
        GPIO_Init(GPIOA,&gpio_init);
       
        //2.2 RX
        gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        gpio_init.GPIO_Pin = GPIO_Pin_10;
       
        GPIO_Init(GPIOA,&gpio_init);
       
        //3.ÅäÖô®¿ÚµÄ½á¹¹Ìå
        usartStruct.USART_BaudRate = 115200;
        usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        usartStruct.USART_Parity = USART_Parity_No;
        usartStruct.USART_StopBits = USART_StopBits_1;
        usartStruct.USART_WordLength = USART_WordLength_8b;
       
        USART_Init(USART1,&usartStruct);
        USART_Cmd(USART1, ENABLE );
       
}

//·â×°ÁËһϷ¢ËÍ×Ö·û
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
        USART_SendData(USARTx,Data);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

}

//·¢ËÍ×Ö·û´®
void usartSendStr(USART_TypeDef* USARTx,char *str)
{
        uint16_t i = 0;
        do{
                usartSendByte(USARTx,*(str+i));
                i++;
        }while(*(str+i) != '\0');

        //ÅжÏÊÇ·ñ·¢ËÍÍê
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}

使用特权

评论回复
11
在水一方00|  楼主 | 2023-9-24 00:46 | 只看该作者
usart.h
#include "stm32f10x.h"

void usart_init(void);
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data);
void usartSendStr(USART_TypeDef* USARTx,char *str);

使用特权

评论回复
12
在水一方00|  楼主 | 2023-9-24 00:46 | 只看该作者
main.c
#include "stm32f10x.h"
#include "led.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "usart.h"

void delay(uint16_t time)
{
        uint16_t i =0;
        while(time--){
                i=12000;
                while(i--);
        }
}

int main()
{
        usart_init();
       
        while(1)
        {
                usartSendStr(USART1,"Finny\r\n");
                delay(1000);
        }

}

使用特权

评论回复
13
在水一方00|  楼主 | 2023-9-24 00:46 | 只看该作者

使用特权

评论回复
14
在水一方00|  楼主 | 2023-9-24 00:46 | 只看该作者
6.重定向printf串口发送
要使用printf,我们需要添加#include <stdio.h>头文件(学过c的都应该知道吧)

记得要给下图框住的内容打勾哦

使用特权

评论回复
15
在水一方00|  楼主 | 2023-9-24 00:47 | 只看该作者
stdio.h文件中有一个宏定义fputc,我们需要使用printf只需要重定向fputc就可以使用啦

使用特权

评论回复
16
在水一方00|  楼主 | 2023-9-24 00:47 | 只看该作者
usart.h
#include "stm32f10x.h"
#include <stdio.h>

void usart_init(void);
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data);
void usartSendStr(USART_TypeDef* USARTx,char *str);

使用特权

评论回复
17
在水一方00|  楼主 | 2023-9-24 00:47 | 只看该作者
usart.c
#include "usart.h"
#include "stm32f10x.h"

void usart_init(void)
{
        GPIO_InitTypeDef gpio_init;
        USART_InitTypeDef usartStruct;
       
        //1.ÅäÖÃʱÖÓ£ºGPIO¿ÚµÄʱÖÓ£¬Òý½Å¸´ÓõÄʱÖÓ£¬´®¿ÚµÄʱÖÓ
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
       
        //2.ÅäÖÃGPIOµÄ½á¹¹Ìå
        //2.1 TX
        gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
        gpio_init.GPIO_Pin = GPIO_Pin_9;
        gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
       
        GPIO_Init(GPIOA,&gpio_init);
       
        //2.2 RX
        gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        gpio_init.GPIO_Pin = GPIO_Pin_10;
       
        GPIO_Init(GPIOA,&gpio_init);
       
        //3.ÅäÖô®¿ÚµÄ½á¹¹Ìå
        usartStruct.USART_BaudRate = 115200;
        usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        usartStruct.USART_Parity = USART_Parity_No;
        usartStruct.USART_StopBits = USART_StopBits_1;
        usartStruct.USART_WordLength = USART_WordLength_8b;
       
        USART_Init(USART1,&usartStruct);
        USART_Cmd(USART1, ENABLE );
       
}

//·â×°ÁËһϷ¢ËÍ×Ö·û
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
        USART_SendData(USARTx,Data);
        while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);

}

//·¢ËÍ×Ö·û´®
void usartSendStr(USART_TypeDef* USARTx,char *str)
{
        uint16_t i = 0;
        do{
                usartSendByte(USARTx,*(str+i));
                i++;
        }while(*(str+i) != '\0');

        //ÅжÏÊÇ·ñ·¢ËÍÍê
        while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
}

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

使用特权

评论回复
18
在水一方00|  楼主 | 2023-9-24 00:47 | 只看该作者
main.c
#include "stm32f10x.h"
#include "led.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "usart.h"
#include "stdio.h"

void delay(uint16_t time)
{
        uint16_t i =0;
        while(time--){
                i=12000;
                while(i--);
        }
}

int main()
{
        usart_init();
       
        GPIO_SetBits(GPIOA, GPIO_Pin_3);
        GPIO_SetBits(GPIOC, GPIO_Pin_13);
       
        while(1)
        {
//                usartSendStr(USART1,"°ÂÀï¸ø\r\n");
                int i = printf("Finny\r\n");
                printf("%d\r\n",i);
//                putchar('2');
               
                delay(1000);
        }
}


使用特权

评论回复
19
在水一方00|  楼主 | 2023-9-24 00:48 | 只看该作者
图下为什么i不是5而是7呢,因为\r\n各占了1

重定向fputc不只可以使用printf还可以使用putchar,大伙可以试试呀

使用特权

评论回复
20
在水一方00|  楼主 | 2023-9-24 00:48 | 只看该作者
串口输入控制LED灯开关
输入o让led灯打开并输出Open LED light success,输入c让led灯关闭并输出Close LED light success

提示: main.c中会看见有外部中断的代码,这是之前做震动感应灯的点此进入 STM32 EXTI(外部中断)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

567

帖子

0

粉丝