欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32——上位机串口通信实验(上位机用的就是野火配的)——Usart1实现控制GPIOA5的电平变化

程序员文章站 2024-02-22 12:07:28
...

今天复习了一下STM32串口的知识,感觉又忘了,到这里来做个笔记啦!!!

先直接上代码
bsp_gpioa5.h

#ifndef _BSP_GPIOA5_H
#define _BSP_GPIOA5_H

#include "stm32f10x.h"

#define ON  0
#define OFF 1   //这两句不加也行,移植时没删

/* 定义一个输出的GPIO端口(A5),野火上移植修改而来*/
#define GPIOA5_PORT     GPIOA                 /* GPIO端口 */
#define GPIOA5_CLK      RCC_APB2Periph_GPIOA  /* GPIO端口时钟 */
#define GPIOA5_PIN    GPIO_Pin_5           /* 连接到SCL时钟线的GPIO */


/* 直接操作寄存器的方法控制IO */
#define digitalHi(p,i)   {p->BSRR=i;}  //输出为高电平  
#define digitalLo(p,i)   {p->BRR=i;}  //输出低电平
#define digitalToggle(p,i) {p->ODR ^=i;} //输出反转状态

/* 定义控制IO的宏 */
#define GPIOA5_TOGGLE   digitalToggle(GPIOA5_PORT,GPIOA5_PIN)
#define GPIOA5_OFF     digitalHi(GPIOA5_PORT,GPIOA5_PIN)
#define GPIOA5_ON      digitalLo(GPIOA5_PORT,GPIOA5_PIN)
void GPIOA5_Config(void);  //声明GPIO的初始化函数

#endif

bsp_gpioa5.c

#include "./GPIO/bsp_gpioa5.h"
/**
  * @brief  初始化GPIOA5
  * @param  无
  * @retval 无
  */
  void GPIOA5_Config(void)
{  
  /*定义一个GPIO_InitTypeDef类型的结构体*/
  GPIO_InitTypeDef GPIO_InitStructure;

  /*开启GPIOA外设时钟*/
  RCC_APB2PeriphClockCmd(GPIOA5_CLK, ENABLE);

 /*选择要控制的GPIO引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIOA5_PIN; 

 /*设置引脚模式为通用推挽输出*/
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

 /*设置引脚速率为50MHz */   
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

 /*调用库函数,初始化GPIO*/
  GPIO_Init(GPIOA5_PORT, &GPIO_InitStructure); 

  /* 关BPIOA5 */
  GPIO_SetBits(GPIOA5_PORT, GPIOA5_PIN); 
}

bsp_usart.h

#ifndef _BSP_USART_H
#define _BSP_USART_H

#include "stm32f10x.h"
#include <stdio.h>

/** 
  * 串口宏定义,不同的串口挂载的总线不一样,移植时需要修改这几个宏
  */
#define  DEBUG_USARTx                   USART1
#define  DEBUG_USART_CLK                RCC_APB2Periph_USART1
#define  DEBUG_USART_APBxClkCmd         RCC_APB2PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200

// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

#define  DEBUG_USART_TX_GPIO_PORT         GPIOA   
#define  DEBUG_USART_TX_GPIO_PIN          GPIO_Pin_9
#define  DEBUG_USART_RX_GPIO_PORT       GPIOA
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_10

#define  DEBUG_USART_IRQ                USART1_IRQn
#define  DEBUG_USART_IRQHandler        USART1_IRQHandler

void USART_Config(void);
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
void Usart_SendString( USART_TypeDef * pUSARTx, char *str);
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch);

#endif

bsp_usart.c

#include "bsp_usart.h"
/**
  * @brief  USART GPIO 配置,工作参数配置
  * @param  无
  * @retval 无
  */

void USART_Config(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
 // 打开串口外设的时钟
 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
// 将USART Tx的GPIO配置为推挽复用模式
 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
// 将USART Rx的GPIO配置为浮空输入模式
 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
// 配置串口的工作参数
 // 配置波特率
 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
 // 配置 针数据字长
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 // 配置停止位
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 // 配置校验位
 USART_InitStructure.USART_Parity = USART_Parity_No ;
 // 配置硬件流控制
 USART_InitStructure.USART_HardwareFlowControl = 
 USART_HardwareFlowControl_None;
 // 配置工作模式,收发一起
 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 // 完成串口的初始化配置
 USART_Init(DEBUG_USARTx, &USART_InitStructure); 
// 使能串口
 USART_Cmd(DEBUG_USARTx, ENABLE);     
}

/*****************  发送一个字符 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
 /* 发送一个字节数据到USART */
 USART_SendData(pUSARTx,ch);
/* 等待发送数据寄存器为空 */
 while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); 
}

void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
 unsigned int k=0;
  do 
  {
      Usart_SendByte( pUSARTx, *(str + k) );
      k++;
  } while(*(str + k)!='\0');

/* 等待发送完成 */
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
  {}
}

/*****************  发送一个16位数 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{
uint8_t temp_h, temp_l;
/* 取出高八位 */
 temp_h = (ch&0XFF00)>>8;
 /* 取出低八位 */
 temp_l = ch&0XFF;
 /* 发送高八位 */
 USART_SendData(pUSARTx,temp_h); 
 while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
/* 发送低八位 */
 USART_SendData(pUSARTx,temp_l); 
 while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); 
}

///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
  /* 发送一个字节数据到串口 */
  USART_SendData(DEBUG_USARTx, (uint8_t) ch);
  /* 等待发送完毕 */
  while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);  
return (ch);
}

///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
/* 等待串口输入数据 */
  while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(DEBUG_USARTx);
}

bsp_usart.h和bsp_usart.c文件我是直接复制野火“串口控制RGB灯”那块的;bsp_gpioa5.h和bsp_gpio.c文件我也是只做了特别简单的define那块修改
下面的main.c自己动了点脑筋,但基本也是简单修改
main.c

#include "stm32f10x.h"
#include "./GPIO/bsp_gpioa5.h"
#include "./Usart/bsp_usart.h"

static void Show_Message(void);

int main(void){
char ch;  //获取串口发来的数据
GPIOA5_Config();
 USART_Config();
 Show_Message();
 while(1){
 ch=getchar();
  switch(ch){
      case '0':
       GPIOA5_ON;
         break;
         case '1':
       GPIOA5_OFF;
         break;
   }
 }
}

static void Show_Message(void)
{
  printf("\r\n   这是一个通过串口通信指令控制A5电平的实验 \n");
  printf("使用  USART  参数为:%d 8-N-1 \n",DEBUG_USART_BAUDRATE);
  printf("开发板接到指令后A5电平,指令对应如下:\n");
  printf("     0    ------    低 \n");
  printf("     1    ------    高 \n");
}

示波器查看电平变化
开发板接USB转串口接口(电脑安装CH340软件)
打开野火的串口调试助手
按下开发板复位键后出现如下图
STM32——上位机串口通信实验(上位机用的就是野火配的)——Usart1实现控制GPIOA5的电平变化
1、发送‘1’字符,波形变化过程STM32——上位机串口通信实验(上位机用的就是野火配的)——Usart1实现控制GPIOA5的电平变化
STM32——上位机串口通信实验(上位机用的就是野火配的)——Usart1实现控制GPIOA5的电平变化
2、发送‘0’字符变化
STM32——上位机串口通信实验(上位机用的就是野火配的)——Usart1实现控制GPIOA5的电平变化

一个简单的串口实验就完成啦,学习笔记勿喷
一个问题没解决:这个实现成功是因为我直接在野火的源文件上修改的,但我自己新建的文件(自己将有关配置文件放入文件夹)时候为什么编译时工程里少下图这些东西??后续更新这个问题STM32——上位机串口通信实验(上位机用的就是野火配的)——Usart1实现控制GPIOA5的电平变化

注意:自己新建的文件(自己将有关配置文件放入文件夹)的时候,应该将所有的子文件的属性中的“只读”去掉,否则编译文件时工程文件就都会文件上有“小钥匙”的情况,表示文件只能读。