STM32串口发送接收数据 您所在的位置:网站首页 stm32串口中断接收数据包 STM32串口发送接收数据

STM32串口发送接收数据

2024-01-06 19:25| 来源: 网络整理| 查看: 265

目录 1.串口通信2.串口的结构体3.如何配置串口的发送4.通过串口向电脑发送ok字符5.封装发送字符串函数6.重定向printf串口发送7.串口输入控制LED灯开关遇到的问题

1.串口通信

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

2.串口的结构体

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 Fck : 串口的时钟(APB1 36M / APB2 72M ) USARTDIV : 无符号的定点数

115200= 72 * 1000000/16 * USARTDIV

3.如何配置串口的发送

1.配置时钟: GPIO口的时钟,串口的时钟, 引脚复用的时钟 2.配置GPIO的结构体 3.配置串口的结构体 4.串口的发送

在这里插入图片描述

4.通过串口向电脑发送ok字符

按照上面的四个步骤进行编写 我们会发现只能一个一个发送字符,比较麻烦,所以后面封装了一个可以发送字符串的函数。 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 ); }

usart.h

#include "stm32f10x.h" void usart_init(void);

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); } }

在这里插入图片描述

5.封装发送字符串函数

注意:在封装发送字符串函数时,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); }

usart.h

#include "stm32f10x.h" void usart_init(void); void usartSendByte(USART_TypeDef* USARTx, uint16_t Data); void usartSendStr(USART_TypeDef* USARTx,char *str);

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); } }

在这里插入图片描述

6.重定向printf串口发送

要使用printf,我们需要添加#include 头文件(学过c的都应该知道吧)

记得要给下图框住的内容打勾哦 在这里插入图片描述 stdio.h文件中有一个宏定义fputc,我们需要使用printf只需要重定向fputc就可以使用啦 在这里插入图片描述 usart.h

#include "stm32f10x.h" #include void usart_init(void); void usartSendByte(USART_TypeDef* USARTx, uint16_t Data); void usartSendStr(USART_TypeDef* USARTx,char *str);

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); }

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); } }

图下为什么i不是5而是7呢,因为\r\n各占了1

重定向fputc不只可以使用printf还可以使用putchar,大伙可以试试呀 在这里插入图片描述

7.串口输入控制LED灯开关

输入o让led灯打开并输出Open LED light success,输入c让led灯关闭并输出Close LED light success

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

#include "stm32f10x.h" void Led_init(void);

led.c

#include "stm32f10x.h" #include "led.h" void Led_init(void) { GPIO_InitTypeDef Led_init; //1.ʹÄÜAPB2µÄʱÖÓGPIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //2.½á¹¹ÌåÅäÖà Led_init.GPIO_Mode = GPIO_Mode_Out_PP; Led_init.GPIO_Pin = GPIO_Pin_13; Led_init.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOC, &Led_init); }

usart.h

#include "stm32f10x.h" #include void usart_init(void); void usartSendByte(USART_TypeDef* USARTx, uint16_t Data); void usartSendStr(USART_TypeDef* USARTx,char *str);

usart.c

#include "usart.h" #include "stm32f10x.h" void usart_init(void) { GPIO_InitTypeDef gpio_init; USART_InitTypeDef usartStruct; NVIC_InitTypeDef nvic_initStruct; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //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_ITConfig(USART1,USART_IT_RXNE,ENABLE);//ÅäÖô®¿ÚÖÐ¶Ï USART_Cmd(USART1, ENABLE ); nvic_initStruct.NVIC_IRQChannel = USART1_IRQn; nvic_initStruct.NVIC_IRQChannelPreemptionPriority = 1; nvic_initStruct.NVIC_IRQChannelSubPriority = 1; nvic_initStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_initStruct); } //·â×°ÁËһϷ¢ËÍ×Ö·û 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); } int fgetc(FILE *f) { while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int) USART_ReceiveData(USART1); }

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() { Led_init(); Relay_Init(); Shake_init(); exti_init(); usart_init(); //³õʼ»¯Òý½Å GPIO_SetBits(GPIOA, GPIO_Pin_3); GPIO_SetBits(GPIOC, GPIO_Pin_13); } void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus( EXTI_Line1 ) != RESET){// ÅжÏÊÇ·ñ·¢ÉúÖÐ¶Ï GPIO_ResetBits(GPIOA, GPIO_Pin_3); usartSendStr(USART1,"Open light success\r\n"); delay(1000); GPIO_SetBits(GPIOA, GPIO_Pin_3); usartSendStr(USART1,"Close light success\r\n"); } EXTI_ClearFlag(EXTI_Line1); } void USART1_IRQHandler(void) { char temp; if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET){ temp = USART_ReceiveData(USART1); if(temp == 'o'){ GPIO_ResetBits(GPIOC, GPIO_Pin_13); usartSendStr(USART1,"Open LED light success\r\n"); } if(temp == 'c'){ GPIO_SetBits(GPIOC, GPIO_Pin_13); usartSendStr(USART1,"Close LED light success\r\n"); } } } 遇到的问题

评论区中小鲸鱼uu私信我了一个问题,就是他串口输出乱码 为什么senddata不能发送int的数字,因为将数字转换成ASCII码输出了,至于ASCII码表百度一下吧



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有