USART.h
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
// 初始化
void USART_Init(void);
// 发送一个字符
void USART_SendChar(uint8_t ch);
// 接收一个字符
uint8_t USART_ReceiveChar(void);
#endif
USART.c
#include "usart.h"
初始化
void USART_Init(void)
{
// 1. 配置时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
// 2. GPIO工作模式
// PA9 TX(发送端): 复用推挽输出:CNF-10,MODE-11
// PA10 RX(接收端): 浮空输入:CNF-01,MODE-00
GPIOA->CRH |= GPIO_CRH_MODE9;
GPIOA->CRH |= GPIO_CRH_CNF9_1;
GPIOA->CRH &= ~GPIO_CRH_CNF9_0;
GPIOA->CRH &= ~GPIO_CRH_MODE10;
GPIOA->CRH &= ~GPIO_CRH_CNF10_1;
GPIOA->CRH |= GPIO_CRH_CNF10_0;
// 3. 串口设置
// 3.1 波特率设置
USART1->BRR = 0x271;
// 3.2 收发使能及USART模块使能
USART1->CR1 |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE)
// 3.3 其他配置,设置数据帧格式
USART1->CR1 &= ~USART_CR1_M;
USART1->CR1 &= ~USART_CR1_PCE;
USART1->CR1 &= ~USART_CR1_PS;
USART1->CR2 &= ~USART_CR2_STOP;
}
发送和接收一个字符
// 发送一个字符
void USART_SendChar(uint8_t ch)
{
// 判断SR里TXE是否为1
while((USART1->SR & USART_SR_TXE) == 0) //TXE位为0时说明缓冲区未空,等待
{}
// 向DR写入新的要发送的数据
USART1->DR = ch;
}
// 接收一个字符
uint8_t USART_ReceiveChar(void)
{
while ((USART1->SR & USART_SR_RXNE) == 0)
{
// 增加一个判断空闲帧的条件
if (USART1->SR & USART_SR_IDLE)
{
// 字符串接收完毕
return 0;
}
}
// 读取已经接收到的数据,等待接收下一个数据
return USART1->DR;
}
发送和接收字符串
// 发送字符串
void USART_SendString(uint8_t *str, uint16_t size)
{
for (uint8_t i = 0; i < size; i++)
{
USART_SendChar(str[i]);
}
}
// 接收字符串
void USART_ReceiveString(uint8_t buffer[], uint8_t *size)
{
// 定义一个变量,用来保存已经接收到的字符个数
uint8_t i = 0;
while ((USART1->SR & USART_SR_IDLE) == 0)
{
buffer[i] = USART_ReceiveChar();
i++;
}
// 清除idle位,不清除会导致后面的while循环直接跳出,导致数据出错,idle的清除条件为读SR再读一次DR
// USART->SR; //前面一直有在读SR因此可以省略
USART1->DR;
* size = --i;
}
// void USART_ReceiveString(uint8_t buffer[], uint8_t *size)
// {
// // 定义一个变量,用来保存已经接收到的字符个数
// uint8_t i = 0;
// // 外层循环不停接收下一个字符
// while (1)
// {
// // 内存循环,判断当前数据帧是否接收完毕
// while ((USART1->SR & USART_SR_RXNE) == 0)
// {
// // 额外增加一个条件,判断当前是否检测到空闲帧
// if (USART1->SR & USART_SR_IDLE)
// {
// // 字符串接收完毕
// *size = i;
// return;
// }
// }
// // 把当前接收到的数据(字符)放入缓冲区
// buffer[i] = USART1->DR;
// i++;
// }
// }
main.c
#include "usart.h"
#include "delay.h"
#include <string.h>
// 定义一个全局变量,接收缓冲区的size
uint8_t buffer[100] = {0};
uint8_t size = 0;
int main(void)
{
// 初始化
USART_Init();
//发送单个字符
USART_SendChar('a');
USART_SendChar('t');
USART_SendChar('\n');
//发送字符串
uint8_t * str = "hello world!\n";
USART_SendString(str, strlen((char *)str));
while (1)
{
// // 发送字符
// USART_SendChar('x');
// USART_SendChar('\n');
// Delay_ms(1000);
/*----------------------------------*/
// 接收字符,再发回来
// uint8_t ch = USART_ReceiveChar();
// USART_SendChar(ch);
/*----------------------------------*/
// 接收字符串,再发回来
USART_ReceiveString(buffer, &size);
USART_SendString(buffer, size);
}
}