STM32串口发送接收数据 | 您所在的位置:网站首页 › stm32串口中断接收数据包 › STM32串口发送接收数据 |
目录
1.串口通信2.串口的结构体3.如何配置串口的发送4.通过串口向电脑发送ok字符5.封装发送字符串函数6.重定向printf串口发送7.串口输入控制LED灯开关遇到的问题
1.串口通信
115200= 72 * 1000000/16 * USARTDIV 3.如何配置串口的发送1.配置时钟: GPIO口的时钟,串口的时钟, 引脚复用的时钟 2.配置GPIO的结构体 3.配置串口的结构体 4.串口的发送 按照上面的四个步骤进行编写 我们会发现只能一个一个发送字符,比较麻烦,所以后面封装了一个可以发送字符串的函数。 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); } }注意:在封装发送字符串函数时,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); } }要使用printf,我们需要添加#include 头文件(学过c的都应该知道吧) 记得要给下图框住的内容打勾哦 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,大伙可以试试呀 输入o让led灯打开并输出Open LED light success,输入c让led灯关闭并输出Close LED light success 提示: main.c中会看见有外部中断的代码,这是之前做震动感应灯的点此进入 STM32 EXTI(外部中断) 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 实验室设备网 版权所有 |