STM32自学历程:USART传输实验-串口发送
实验现象
成功在电脑串口助手上显示中文“你好,世界”
代码分析
打开时钟
开启USART1的时钟,USART1的时钟在APB2上,其余USART时钟均在APB1上.
开启GPIOA的时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
配置引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
初始化USART
使用USART_Init函数,同时配置好USART结构体参数
结构体参数有6个参数需要配置,如下图:
第一个参数:设置波特率。这里我们直接数据即可,硬件部分会自动帮助我们进行分频
第二个参数:设置数据位长度。可选择8位,或者9位,8位就是无校验位,9位就是有校验位。
第三个参数:设置停止位。可选1,1.5,2,0。一般选停止位为0。
第四个参数:设置校验位。可选择奇校验,偶校验,无校验,一般选择无校验
第五个参数:设置转态。可选输入状态,输出状态,或者双状态。一般要么输入,要么输出。
第六个参数:硬件流控制。一般选择无控制。
USART_InitTypeDef USART_InitStruct={9600,
USART_WordLength_8b,
USART_StopBits_1,
USART_Parity_No,
USART_Mode_Tx,
USART_HardwareFlowControl_None};
USART_Init(USART1,&USART_InitStruct);
打开USART
使用USART_cmd(),这个函数相当于是给USART通电,让USART工作,告诉STM32我要使用USART,给我打开它。
USART_Cmd(USART1,ENABLE);
编写发送函数
1,发送字节函数
USART_SendData
2,判断是否传输完毕,读取标志位
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
如果传输完成,则函数返回SET,否则一直循环。这里也不需要手动置零,因为在下一次调用USART_SendData时,系统会自动将标志位清零。
编写——发送一个字符的函数
这个不用编写——直接发送字符对应的十六进制数,或者用单引号引起来——‘A’。
如下:
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}
如果是0x**,则表示为16进制发送
如果是‘某个字符’,则表示为字符发送,但USART会转换成16进制发送
如果是数字,没有加任何前缀,则默认十进制发送,但USART还是会转换成16进制发送
// Serial_SendByte(0+65);//发送A
// Serial_SendByte(‘A’);//也是发送A// Serial_SendByte(0x41);//也是发送A
编写——发送一个字符串的函数
void Serial_SendString(char *String)
{
uint16_t i;
for (i =0; String[i]!= '\0' ;i++)
{
Serial_SendByte(String[i]);
}
}
原理是:由C语言知识可知,字符串结尾是一个转义字符0,所以只要用\0来作为结尾判断就可以一位一位的读取字符串里面的字符,从而打印出字符串。
编写——发送一组数字的函数
感觉这个没有太大作用。
代码展示
main.c
#include "stm32f10x.h" // Device header
#include "serial.h"
int main(void)
{
OLED_Init();
Serial_Init();
Serial_SendString("你好,世界\r\n");
while (1)
{
}
}
USART.c
#include "stm32f10x.h" // Device header
#include "serial.h"
#include "stdio.h"
#include "stdarg.h"
void Serial_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStruct={9600,USART_WordLength_8b,USART_StopBits_1,
USART_Parity_No,USART_Mode_Tx,USART_HardwareFlowControl_None};
USART_Init(USART1,&USART_InitStruct);
USART_Cmd(USART1,ENABLE);
}
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}
void Serial_SendString(char *String)
{
uint16_t i;
for (i =0; String[i]!= '\0' ;i++)
{
Serial_SendByte(String[i]);
}
}
uint32_t Serial_Pow(uint32_t x,uint32_t y)
{
uint32_t result=1;
while(y--)
{
result = result*x;
}
return result;
}
void Serial_SendNumber(uint32_t Number,uint8_t Length)
{
uint8_t i;
for(i=0; i< Length; i++)
{
Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+48);
}
}
int fputc(int ch,FILE *f)
{
Serial_SendByte(ch);
return ch;
}
void Seial_Printf(char *format,...)
{
char String[100];
va_list arg;
va_start(arg,format);
vsprintf(String,format,arg);
va_end(arg);
Serial_SendString(String);
}
USART.h
#ifndef _SERIAL_H
#define _SERIAL_H
#include<stdio.h>
void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendString(char *String);
void Serial_SendNumber(uint32_t Number,uint8_t Length);
int fputc(int ch,FILE *F);
void Seial_Printf(char *format,...);
#endif
谢谢大家!