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

谢谢大家!

物联沃分享整理
物联沃-IOTWORD物联网 » STM32自学历程:USART传输实验-串口发送

发表评论