首页 > 其他分享 >串口通信-stm32

串口通信-stm32

时间:2024-09-15 14:25:22浏览次数:12  
标签:NVIC Addr USART 通信 stm32 InitStructure 串口 GPIO define

【实验目的】

深入理解串口协议和串口程序编制方法;

【实验要求】

1.学会编写串口通信程序

2.能够使用按键控制通信消息的发送

2.学会在两块开发板之间通信的方式

【实验内容】

1.将开发板和PC机串口连接,并通过串口线和另一块开发板连接;

2.在发送开发板上按下发送键,则向目标开发板发送一个字符串;

3.目标开发板通过另一个串口将接收到的字符串发串口助手显示;

【实验过程】

1.硬件连接

*使用战舰开发板完成实验

使用USART1的USB串口与PC完成连接,使用USART2通过杜邦线与另一块开发板的USART2跳线处完成连接。

图1 硬件连接(仅显示数据线连接,需共地线)

2.接口技术

USART:通用同步异步串口,通信方式为全双工通信方式,可同时接发数据。其中开发板的USART1与CH340转串口芯片连接,将USART TTL转化为USB通信与PC机相连。USART通过RX,TX,GND与另一块开发板相连。

2.程序逻辑

在与PC机相连的开发板上,通过将USART2接受到的数据反馈到USART1中,通过串口助手可以查看数据,方便调试。

在未与PC相连的开发板中,按下独立按键Key1后,串口USART2发送数据,另一块开发板收到信息后,点亮开发板LED灯,并向USART1发送数据。

3.程序展示

(1)按键及LED初始化【使用位带操作】

LED_KEY_Init

  1. GPIO_InitTypeDef GPIO_InitStructure;  
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟  
  3. GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//KEY0-KEY2  
  4. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入  
  5. GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4  
  6. //初始化 WK_UP-->GPIOA.0      下拉输入  
  7. GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉       
  9. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0    
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);   //使能PB,PE端口时钟  
  11. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                //LED0-->PB.5 端口配置  
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽输出  
  13. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //IO口速度为50MHz  
  14. GPIO_Init(GPIOB, &GPIO_InitStructure);                   //根据设定参数初始化GPIOB.5  
  15. GPIO_SetBits(GPIOB,GPIO_Pin_5);                      //PB.5 输出高  
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                //LED1-->PE.5 端口配置, 推挽输出  
  17. GPIO_Init(GPIOE, &GPIO_InitStructure);                   //推挽输出 ,IO口速度为50MHz  
  18. GPIO_SetBits(GPIOE,GPIO_Pin_5);                          //PE.5 输出高   
  19. GPIO_InitTypeDef GPIO_InitStructure;  
  20. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟  
  21. GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//KEY0-KEY2  
  22. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入  
  23. GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4  
  24. //初始化 WK_UP-->GPIOA.0      下拉输入  
  25. GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  
  26. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉       
  27. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0  

Led_Key

  1. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))   
  2. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))   
  3. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))   
  4. //IO口地址映射  
  5. #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C   
  6. #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C   
  7. #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C   
  8. #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C   
  9. #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C   
  10. #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C      
  11. #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C      
  12.   
  13. #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808   
  14. #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08   
  15. #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008   
  16. #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408   
  17. #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808   
  18. #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08   
  19. #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08   
  20. //IO口操作,只对单一的IO口!  
  21. //确保n的值小于16!  
  22. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出   
  23. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入   
  24. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出   
  25. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入   
  26. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出   
  27. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入   
  28. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出   
  29. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入   
  30. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出   
  31. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入  
  32. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出   
  33. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入  
  34. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出   
  35. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入  

头文件声明

  1. #define LED0 PBout(5)  
  2. #define LED1 PEout(5)  
  3. #define Key0 PEin(4)  
  4. #define Key1 PEin(3)  
  5. #define Key2 PEin(2)  

按键中断

  1. NVIC_InitTypeDef NVIC_InitStructure;  
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能复用功能时钟  
  3. EXTI_InitTypeDef EXTI_InitStructure;  
  4. EXTI_InitStructure.EXTI_Line = EXTI_Line0;  
  5. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  
  6. EXTI_Init(&EXTI_InitStructure); // 根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器  
  7.   
  8. NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;             // 使能按键WK_UP所在的外部中断通道  
  9. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; // 抢占优先级2,  
  10. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;        // 子优先级3  
  11. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              // 使能外部中断通道  
  12. NVIC_Init(&NVIC_InitStructure);  
  13.   
  14. NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;             // 使能按键KEY2所在的外部中断通道  
  15. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; // 抢占优先级2,  
  16. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;        // 子优先级2  
  17. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              // 使能外部中断通道  

(2)串口初始化

  1. void Serial_Init()  
  2. {  
  3.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
  4.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);  
  5.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);  
  6.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);  
  7.       
  8.     GPIO_InitTypeDef g;  
  9.     g.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  10.     g.GPIO_Pin = GPIO_Pin_3;  
  11.     g.GPIO_Speed = GPIO_Speed_50MHz;  
  12.     GPIO_Init(GPIOA, &g);  
  13.     g.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  14.     g.GPIO_Pin =GPIO_Pin_10;  
  15.     g.GPIO_Speed = GPIO_Speed_50MHz;  
  16.     GPIO_Init(GPIOA,&g);  
  17.       
  18.     g.GPIO_Mode =GPIO_Mode_AF_PP;  
  19.     g.GPIO_Pin = GPIO_Pin_2;  
  20.     g.GPIO_Speed = GPIO_Speed_50MHz;  
  21.     GPIO_Init(GPIOA, &g);  
  22.     g.GPIO_Mode = GPIO_Mode_AF_PP;  
  23.     g.GPIO_Pin =GPIO_Pin_9;  
  24.     g.GPIO_Speed = GPIO_Speed_50MHz;  
  25.     GPIO_Init(GPIOA,&g);  
  26.       
  27.     USART_InitTypeDef u;  
  28.     u.USART_BaudRate = 9600;  
  29.     u.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
  30.     u.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
  31.     u.USART_Parity = USART_Parity_No;  
  32.     u.USART_StopBits = USART_StopBits_1;  
  33.     u.USART_WordLength = USART_WordLength_8b;  
  34.     USART_Init(USART2, &u);  
  35.     USART_Init(USART1, &u);  
  36.       
  37.     NVIC_InitTypeDef n;  
  38.     n.NVIC_IRQChannel = USART2_IRQn;  
  39.     n.NVIC_IRQChannelCmd = ENABLE;  
  40.     n.NVIC_IRQChannelPreemptionPriority = 1;  
  41.     n.NVIC_IRQChannelSubPriority = 2;  
  42.     NVIC_Init(&n);  
  43.     n.NVIC_IRQChannel = USART1_IRQn;  
  44.     n.NVIC_IRQChannelCmd = ENABLE;  
  45.     n.NVIC_IRQChannelPreemptionPriority = 1;  
  46.     n.NVIC_IRQChannelSubPriority = 1;  
  47.     NVIC_Init(&n);  
  48.     USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  
  49.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  
  50.     USART_Cmd(USART1,ENABLE);  
  51.     USART_Cmd(USART2,ENABLE);  
  52. }  

(3)中断操作配置

  1. void USART2_IRQHandler()  
  2. {  
  3.     if(USART_GetITStatus(USART2, USART_IT_RXNE) == 1)  
  4.     {  
  5.         usart2_read[p++]= USART_ReceiveData(USART2);  
  6.         USART_ClearITPendingBit(USART2, USART_IT_RXNE);  
  7.     }  
  8. }  
  9. void USART1_IRQHandler()  
  10. {  
  11.     if(USART_GetITStatus(USART1, USART_IT_RXNE) == 1)  
  12.     {  
  13.         usart1_read[q++]= USART_ReceiveData(USART1);  
  14.         USART_ClearITPendingBit(USART1, USART_IT_RXNE);  
  15.     }  
  16.       
  17. }  
  18. // 外部中断2服务程序  
  19. void EXTI2_IRQHandler(void)  
  20. {  
  21.     Delay_ms(10);  // 消抖  
  22.     if (Key2 == 0) // 按键KEY2  
  23.     {  
  24.         USART2_send();  
  25.         LED0=0;  
  26.     }  
  27.     EXTI_ClearITPendingBit(EXTI_Line2); // 清除LINE2上的中断标志位  
  28. }  

(4)逻辑操作_按键跳转函数

  1. void USART2_send()  
  2. {  
  3.     uint8_t i=0;  
  4.     for(i=0;i<8;i++)  
  5.     {  
  6.         while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)!= 1 );  
  7.         USART_SendData(USART2,cmd1[i]);  
  8.     }  
  9. }  

Main

  1. while(1)  
  2. {  
  3.     if(p==7);  
  4.     {     
  5.         p=0;              
  6.         for(i=0;i<8;i++)  
  7.         {  
  8.             while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)!= 1 );  
  9.             USART_SendData(USART1,usart2_read[i]);  
  10.         }  
  11.     }     
  12. }  

4.效果展示

标签:NVIC,Addr,USART,通信,stm32,InitStructure,串口,GPIO,define
From: https://blog.csdn.net/hilws760/article/details/142257953

相关文章

  • MATLAB中的无线通信系统设计有哪些最佳实践
    在无线通信系统设计领域,MATLAB提供了一套强大的工具箱,使得系统设计、仿真、测试和分析变得更加高效和精确。本文将探讨MATLAB在无线通信系统设计中的最佳实践,包括信号处理、调制与解调、信道建模、误码率分析以及无线通信标准的实现。1.信号处理信号处理是无线通信系统设......
  • MATLAB在无线通信系统建模和仿真中的应用
    在无线通信系统的设计与分析中,MATLAB提供了一套全面的建模和仿真工具,这些工具帮助工程师和研究人员在早期阶段验证设计概念,优化系统性能,并预测系统在实际环境中的行为。本文将详细介绍MATLAB在无线通信系统建模和仿真中的应用,包括信道建模、调制解调、射频(RF)链路分析以及硬......
  • Linux下使用pipe进行父子进程间通信
    引入之前我们介绍了多进程以及创建进程的函数fork,下面我们将继续深入,讨论一下多进程间的通信问题;pipe管道谈论多进程通信,就离不开pipe(管道),这是一个系统调用,用于在UNIX和类UNIX系统(如Linux)上创建一个管道(pipe),实现进程间通信。它创建了一个双向的通信通道,允许一个进程向另一......
  • (2)Proteus8.7添加STM32F103C6直接使用编译xxx.hex文件关键步骤
    1)新建工程中选项 2)Protues8.7支持芯片如下:3)点击STM32选择Keil编译生成的xxx.hex文件 4)使用virtualterminal显示串口信息。仿真状态,点击Debug菜单项,按图操作。 ......
  • cJSON-轻量级解析模块、字符串的神——编织STM32C8T6与阿里云信息传递的纽带
            编写方向:本人就不泛泛的编写一篇什么一文学会cJSON了,没什么突出点,也就我水水字数,你们看来看去也不懂,本人是从上阿里云传信息接触的cJSON的,我就此写一篇针对性的文章,希望对大家有用,后期我在其他方面用到还会继续更新。一、简介        cJSON是一个用C......
  • php和go进行跨进程fifo通信
    fifo的文件需要提前建立好,或者用程序处理php<?php$fifoName="my_fifo";//打开命名管道进行读取$fifo=fopen($fifoName,"r+");if($fifo===false){die("UnabletoopenFIFO:$fifoName");}//读取数据$data=fread($fifo,1024);echo"Re......
  • 使用micropython设计STM32蓝牙智能小车
    1、前言    最近在使用micropython来使用STM32F411CEU6TR,给我的感觉是:没有像使用c语言那样的自由,有一些引脚不能够自主设计,不触及底层代码,但是对于初学者来说非常友好,可操作性大大提高,各种代码的使用接近口语,方便使用。2、软件的使用    一个是MU,这个对于有......
  • 蓝桥杯-基于STM32G432RBT6的LCD进阶(LCD界面切换以及高亮显示界面)
    目录一、页面切换内容详解1.逻辑解释2.代码详解code.c(内含详细讲解)code.hmain.c3.效果图片展示​编辑二、页面选项高亮内容详解1.逻辑解释2.读入数据FIRST.第一种高亮类型code.c(内含代码详解)code.hmain.cSECOND.第二种高亮类型3.效果展示开源代码一、页......
  • stm32驱动HX711称重传感器 c++代码分享
    一、HX711模块介绍HX711模块是一种专门用于称重传感器的放大器模块。它的主要功能是将测得的微小电压信号放大到可以被微控制器读取的范围。HX711模块通常配合称重传感器一起使用,例如压力传感器、负载细胞等。它采用24位的模数转换器(ADC)来精确测量传感器的电压变化。HX711模块具......
  • STM32CubeIDE看门狗
    看门狗简介看门狗:本质是一个递减的计数器当程序有BUG或硬件问题导致的程序卡死或跑飞时,看门狗可及时复位程序作用:防止程序卡死或程序跑飞,保证系统的可靠性和稳定性STM32有独立看门狗(IWDG)和窗口看门狗(WWDG)两种类型独立看门狗:独立工作,对时间精度要求较低窗口看门狗:时间精......