STM32
直播中

无厘头

13年用户 546经验值
擅长:基础元器件
私信 关注
[问答]

STM32F407ZE是怎样通过串口发送接收PC端串口助手消息的

STM32F407ZE是怎样通过串口发送接收PC端串口助手消息的?并控制LED灯的亮灭呢?

回帖(1)

张舒婷

2021-11-25 14:38:07
STM32F407ZE 通过串口发送接收PC端串口助手消息,并控制LED灯的亮灭
STM32串口USART1接收字符串
具体代码解析如下:
ustart.h部分

#ifndef USTART_H
#define USTART_H


#include
#include
#include "sys.h"


void USART1_Init();
void USART_SendString(USART_TypeDef* USARTx, char *DataString);
#endif


ustart.c部分


#include "ustart.h"
#include


void USART1_Init()
{
        GPIO_InitTypeDef         GPIOInit_Struct;
        USART_InitTypeDef         USARTInit_Struct;
       
        //1、使能时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
       
        //2、初始化对应的IO引脚复用为USART1功能
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
       
        GPIOInit_Struct.GPIO_Pin         = GPIO_Pin_9 | GPIO_Pin_10;
        GPIOInit_Struct.GPIO_Mode        = GPIO_Mode_AF;
        GPIOInit_Struct.GPIO_OType        = GPIO_OType_PP;
        GPIOInit_Struct.GPIO_Speed         = GPIO_Fast_Speed;
        GPIOInit_Struct.GPIO_PuPd        = GPIO_PuPd_UP;
        GPIO_Init(GPIOA,&GPIOInit_Struct);
       
        //将PA9  PA10复用为USART1功能
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
       
        //3、USART1初始化
        USARTInit_Struct.USART_BaudRate         = 115200;                                                                 //波特率
        USARTInit_Struct.USART_Parity                = USART_Parity_No;                                                //无校验位
        USARTInit_Struct.USART_StopBits                = USART_StopBits_1;                                                //1位停止位
        USARTInit_Struct.USART_WordLength        = USART_WordLength_8b;                                        //8位数据位
        USARTInit_Struct.USART_Mode                        = USART_Mode_Rx | USART_Mode_Tx;                //收发模式
        USARTInit_Struct.USART_HardwareFlowControl        = USART_HardwareFlowControl_None;//无硬件控制流
        USART_Init(USART1,&USARTInit_Struct);
       
        //4、开启串口
        USART_Cmd(USART1,ENABLE);
}


void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
        int i = 0;
        USART_ClearFlag(USARTx,USART_FLAG_TC);                                                                                //发送字符前清空标志位(否则缺失字符串的第一个字符)
        while(DataString != '')                                                                                                //字符串结束符
        {
                USART_SendData(USARTx,DataString);                                                                        //每次发送字符串的一个字符
                while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0);                                        //等待数据发送成功
                USART_ClearFlag(USARTx,USART_FLAG_TC);                                                                        //发送字符后清空标志位
                i++;
        }
}


main.c部分(接收PC端发送来的单个字符)


#include
#include "led.h"
#include "ustart.h"


int main()
{
        LED_Init();                                                                                                                        //LED灯初始化
        USART1_Init();                                                                                                                //串口初始化
        USART_SendString(USART1, "Hello world!rn");                                                //发送字符串
       
        char USART1_ReceiveData = 0;                                                                                //接收PC端发送过来的字符
        USART_ClearFlag(USART1,USART_FLAG_RXNE);                                                        //接收前先清空标志位
        while(1)
        {
                if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1)                        //USART_FLAG_RXNE判断数据,== 1则有数据
                {
                        USART1_ReceiveData = USART_ReceiveData(USART1);                                //通过USART1串口接收字符
                        USART_ClearFlag(USART1,USART_FLAG_RXNE);                                        //接收后先清空标志位
                }
               
                if( '1' == USART1_ReceiveData )                                                                        //如果数据为1,LED1灯电平翻转
                {
                        PFout(9) = !PFout(9);
                }
               
                if( '2' == USART1_ReceiveData )                                                                        //如果数据为2,LED2灯电平翻转
                {
                        PFout(10) = !PFout(10);
                }
                USART1_ReceiveData = 0;                                                                                        //数据清零
        }
}


sys.h部分:


#ifndef __SYS_H
#define __SYS_H         
#include "stm32f4xx.h"


//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414   
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14   
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     


#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010

//STM32中  对寄存器的访问  是不能单独访问寄存器的单个bit  只能以32bit地址访问寄存器
//这些位为只写形式,只能在字(word)--4byte、半字2byte 或字节模式下访问
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入


#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入


#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入


#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入


#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入


#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入


#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入


#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入


#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入




#endif


开启串口终端接收PC端串口助手发送过来的字符


ustart.c部分


#include "ustart.h"
#include


void USART1_Init()
{
        GPIO_InitTypeDef         GPIOInit_Struct;
        USART_InitTypeDef         USARTInit_Struct;
        NVIC_InitTypeDef          USARTNVIC_Struct;
       
        //1、使能时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
       
        //2、初始化对应的IO引脚复用为USART1功能
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
       
        GPIOInit_Struct.GPIO_Pin         = GPIO_Pin_9 | GPIO_Pin_10;
        GPIOInit_Struct.GPIO_Mode        = GPIO_Mode_AF;
        GPIOInit_Struct.GPIO_OType        = GPIO_OType_PP;
        GPIOInit_Struct.GPIO_Speed         = GPIO_Fast_Speed;
        GPIOInit_Struct.GPIO_PuPd        = GPIO_PuPd_UP;
        GPIO_Init(GPIOA,&GPIOInit_Struct);
       
        //将PA9  PA10复用为USART1功能
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
       
        //3、USART1初始化
        USARTInit_Struct.USART_BaudRate         = 115200;                                                                 //波特率
        USARTInit_Struct.USART_Parity                = USART_Parity_No;                                                //无校验位
        USARTInit_Struct.USART_StopBits                = USART_StopBits_1;                                                //1位停止位
        USARTInit_Struct.USART_WordLength        = USART_WordLength_8b;                                        //8位数据位
        USARTInit_Struct.USART_Mode                        = USART_Mode_Rx | USART_Mode_Tx;                //收发模式
        USARTInit_Struct.USART_HardwareFlowControl        = USART_HardwareFlowControl_None;//无硬件控制流
        USART_Init(USART1,&USARTInit_Struct);
       
        //开启串口中断
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
       
        USARTNVIC_Struct.NVIC_IRQChannel = USART1_IRQn;//stm32f4xx.h
        USARTNVIC_Struct.NVIC_IRQChannelPreemptionPriority = 0;
        USARTNVIC_Struct.NVIC_IRQChannelSubPriority        = 0;
        USARTNVIC_Struct.NVIC_IRQChannelCmd        = ENABLE;
        NVIC_Init(&USARTNVIC_Struct);
       
        //4、开启串口
        USART_Cmd(USART1,ENABLE);
}


void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
        int i = 0;
        USART_ClearFlag(USARTx,USART_FLAG_TC);                                                                                //发送字符前清空标志位(否则缺失字符串的第一个字符)
        while(DataString != '')                                                                                                //字符串结束符
        {
                USART_SendData(USARTx,DataString);                                                                        //每次发送字符串的一个字符
                while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0);                                        //等待数据发送成功
                USART_ClearFlag(USARTx,USART_FLAG_TC);                                                                        //发送字符后清空标志位
                i++;
        }
}


void USART1_IRQHandler(void)                                                                                                        //串口中断执行函数
{
        char USART1_ReceiveData = 0;                                                                                                //接收PC端发送过来的字符
       
        if(USART_GetFlagStatus(USART1,USART_IT_RXNE) == 1)                                                        //USART_FLAG_RXNE判断数据,== 1则有数据
        {               
                USART1_ReceiveData = USART_ReceiveData(USART1);                                                        //通过USART1串口接收字符
                USART_ClearFlag(USART1,USART_IT_RXNE);                                                                        //接收后先清空标志位
        }
       
        if( '1' == USART1_ReceiveData )                                                                                                //如果数据为1,LED1灯电平翻转
        {
                PFout(9) = !PFout(9);
        }
       
        if( '2' == USART1_ReceiveData )                                                                                                //如果数据为2,LED2灯电平翻转
        {
                PFout(10) = !PFout(10);
        }
}


ustart.h部分


#ifndef USTART_H
#define USTART_H


#include
#include
#include "sys.h"


void USART1_Init();
void USART_SendString(USART_TypeDef* USARTx, char *DataString);
#endif
举报

更多回帖

×
20
完善资料,
赚取积分