今天学习了如何使用stm32通过USART进行简单的无奇偶校验位的异步串口通信,USART:通用同步异步收发器。在学习之前应先了解硬件设备的连接情况,stm32f407的PA9,PA10分别是USART1的TX和RX,通过对这两个GPIO口的配置,完成对一部串口通信的初始化函数,以及收发函数。
串口通信的初始化包括以下五个步骤:
第一步:打开USART1和GPIOA的时钟;
第二步:对GPIOA的第九第十管脚进行配置;
第三步:打开USART1发送和接受使能;
第四步:对小数波特率进行配置;
第五步:打开串口通信使能
下面是通过串口通信对单片机开发板上的led和蜂鸣器进行控制。led与蜂鸣器电路图参考上一篇文章。点击打开链接
usart.c
#include "usart.h"
void Usart_Init(void)
{
RCC->AHB1ENR |= (1<<0);//开启GPIOA时钟
RCC->APB2ENR |= (1<<4);//开启USART1时钟
//对PA9,PA10进行端口配置
GPIOA->MODER &=~ (0xF<<18);
GPIOA->MODER |= (0xA<<18);//复用功能
GPIOA->OTYPER &=~ (3<<9);//推挽输出
GPIOA->OSPEEDR |= (0xf<<18);//输出速率最高
GPIOA->PUPDR &=~ (0xf<<18);
GPIOA->PUPDR |= (5<<18); //上拉模式
GPIOA->AFR[1] &=~ (0xFF<<4);
GPIOA->AFR[1] |= (0x77<<4);//复用功能高位寄存器 配置为USART1功能
USART1->CR1 |= (1<<2)|(1<<3);//打开USART1的接收器和发送器使能
float USARTDIV = 84000000.0f/16/115200;//定义一个浮点型USARTDIV用来表示将要配置的波特率
uint32_t Mantissa,Fraction;//定义两个int型数据用来存放整数部分和小数部分
Mantissa = USARTDIV;
Fraction = (USARTDIV - Mantissa)*16;
//将设置好的数据存放到波特率寄存器中 USART1->BRR波特率寄存器 低四位是小数部分
USART1->BRR = (Mantissa<<4) + Fraction;
USART1->CR1 |= (1<<13);//开启串口使能
}
void Usart_Tx(uint8_t data) //发送一位数据
{
while((USART1->SR & (1<<6)) == 0);
USART1->DR = data;
}
uint8_t Usart_Rx(void) //接收一位数据
{
while((USART1->SR & (1<<5)) == 0);
return USART1->DR;
}
usart.h
#ifndef USART_H
#define USART_H
#include "stm32f4xx.h"
void Usart_Init(void);
void Usart_Tx(uint8_t data);
uint8_t Usart_Rx(void);
#endif
gpio.c
#include "gpio.h"
void Gpio_Init(GPIO_TypeDef * GPIOx, uint8_t Pin)
{
GPIOx->MODER &=~ (3<<(Pin+Pin));
GPIOx->MODER |= (1<<(Pin+Pin));
GPIOx->OTYPER &=~ (1<<Pin);
GPIOx->OSPEEDR |= (3<<(Pin+Pin));
GPIOx->PUPDR &=~ (3<<(Pin+Pin));
GPIOx->PUPDR |= (1<<(Pin+Pin));
}
void Led_Init(void)
{
RCC->AHB1ENR |= (1<<5);
RCC->AHB1ENR |= (1<<2);
Gpio_Init(GPIOF,6);
Gpio_Init(GPIOF,9);
Gpio_Init(GPIOF,10);
Gpio_Init(GPIOC,0);
}
void Beep_Init(void)
{
RCC->AHB1ENR |= (1<<5);
Gpio_Init(GPIOF,8);
}
gpio.h
#ifndef GPIO_H
#define GPIO_H
#include "stm32f4xx.h"
#define LED1_TOGGLE() GPIOF->ODR ^= (1<<6)
#define LED2_TOGGLE() GPIOF->ODR ^= (1<<9)
#define LED3_TOGGLE() GPIOF->ODR ^= (1<<10)
#define LED4_TOGGLE() GPIOC->ODR ^= (1<<0)
#define BEEP_TOGGLE() GPIOF->ODR ^= (1<<8)
void Gpio_Init(GPIO_TypeDef * GPIOx, uint8_t Pin);
void Led_Init(void);
void Beep_Init(void);
#endif
main.c
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
uint8_t temp;
Usart_Init();
Led_Init();
Beep_Init();
while (1)
{
temp = Usart_Rx();
Usart_Tx(temp);
switch(temp)
{
case '1': LED1_TOGGLE();break;
case '2': LED2_TOGGLE();break;
case '3': LED3_TOGGLE();break;
case '4': LED4_TOGGLE();break;
case '5': BEEP_TOGGLE();break;
default: break;
}
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT HOLMES *****END OF FILE****/