铁头山羊STM32串口(2)

什么是串口

在这里插入图片描述

串口空闲状态和数据帧格式

串口空闲状态时,默认为高电平,当串口想要发送数据,将高电平变为低电平,作为一个起始位。将数据发送完毕后,串口又进入空闲状态,即高电平
串口有四种数据帧格式,分别是:8位无校验,8位带校验。9位无校验,9位带校验
在这里插入图片描述

奇校验和偶校验

奇校验:当发送数据有奇数个1时,校验位写0,当发送数据有偶数个1时,校验位写1
奇校验的核心是保证发送数据中有奇数个1。当接收数据时,会计算该数据有几个1,如果为奇数个1,那么则认为该数据在传输过程中没有错误,收到的数据是正确的。
如果为偶数个1,就说明数据在传输过程中出现了变形。
偶校验:当发送数据有偶数个1时,校验位写0,当发送数据有奇数个1时,校验位写1
偶校验的核心是保证发送数据中有偶数个1。当接收数据时,会计算该数据有几个1,如果为偶数个1,那么则认为该数据在传输过程中没有错误,收到的数据是正确的。
如果为奇数个1,就说明数据在传输过程中出现了变形。
不足:假如接受数据时,有两位或者多位数据发生了变形,奇校验和偶校验并不能准确的识别数据的对错。例如,假如我发送的数据是9位奇校验 010101011,该数据在传输时发生了变形,变为000100011,此时有两位数据发生了变形,但是接收该数据时,仍计算出为奇数个1,此时会认为该数据准确,没有发生变形

串口的波特率

在这里插入图片描述
波特率:每秒钟最多传输多少比特位
串口常用波特率为9600,115200,38400
波特率的计算公式为:时钟/分频器/16=波特率
假如输入的时钟信号为72MHz,我们想得到9600的波特率,那么该如何配置分频器呢?即 72MHz/16/9600=x;解得x=39.025。即需要将分频器配置为39.025,就可以输出9600的波特率。

串口的发送和接收,以及串并转换

在这里插入图片描述
串口的发送:当串口需要发送一个数据时,首先将该数据发送到发送数据寄存器,再将该数据整体移动到移位寄存器。最后从最右边(即最低位)通过TX一个数据一个数据的依次发送。发送后,最低位变为最高位,最高位变为最低位,将数据前后顺序进行倒转。这也叫串口发送时,低位先行。
串口的接收:从数据的最高位通过RX,依次进入移位寄存器的右端(此时又进行了一次倒转,两次倒转使数据恢复到原样),再整体移动到接受数据寄存器。
像发送数据寄存器这种,将整个数据一起移动的,称为并行转换。而像移位数据寄存器这种一个一个数据依次移动的,称为串行转换。

串口的标志位

串口发送时需要用到的标志位
在这里插入图片描述
在这里插入图片描述
串口接收时需要用到的标志位
在这里插入图片描述

## 串口初始化

1.首先打开GPIO和USART1的时钟
2.依次将GPIO和USART1进行初始化(串口的发送和接收引脚分别是PA9和PA10,串口发送时,需配置成复用推挽输出,串口接收时,需配置成上拉输入)
3.闭合USART1的开关,即USART-Cmd

编程接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

串口发送和串口重定向的代码

串口发送的代码
Serial.c

#include "stm32f10x.h"                  // Device header
#include <stdio.h>


void MySerial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //打开GPIOA的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//打开USART1的时钟
	//@GPIO初始化,先初始化PA9(串口发送),后初始化PA10(串口接收)
	GPIO_InitTypeDef GPIO_InitStructrue;
	GPIO_InitStructrue.GPIO_Mode=GPIO_Mode_AF_PP;//串口发送需要配置成复用推挽输出
	GPIO_InitStructrue.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStructrue.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructrue);
	
	GPIO_InitStructrue.GPIO_Mode=GPIO_Mode_IPU;//串口接收需要配置成上拉输入
	GPIO_InitStructrue.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStructrue.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructrue);
	
	//@USART1初始化
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate=9600;//波特率
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不使用硬件流控
	USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//串口发送和接收
	USART_InitStructure.USART_Parity=USART_Parity_No;//无校验
	USART_InitStructure.USART_StopBits=USART_StopBits_1;//1位停止位
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;//数据长度为8个字节
	USART_Init(USART1,&USART_InitStructure);
	
	USART_Cmd(USART1,ENABLE);//打开USART1
}

//串口发送多个字节
void My_USART1_Send(USART_TypeDef *USARTx,uint8_t *pData,uint8_t Size)
{
	for(int i=0;i<Size;i++)
	{
		while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
		USART_SendData(USART1,pData[i]);
	}
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "Serial.h"
#include <stdio.h>
#include "Delay.h"



int main(void)
{

	uint8_t pata[]={6,8,9,0};
	
MySerial_Init();
	
My_USART1_Send(USART1,pata,4);
//	Delay_ms(40);
	printf("Hello world. \r\n");//串口打印
while(1)	
{
	



}	
	
	
}

注意:使用串口重定向需打开魔术棒处的USE MicroLIB和加上#include <stdio.h>头文件)
在这里插入图片描述
重定向函数:

int fputc(int ch,FILE *f)
{
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
	USART_SendData(USART1,(uint8_t)ch);
	
	return ch;
}
	

串口接收,利用串口来控制PA0的亮灭,PA0为推挽模式

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "Serial.h"
#include <stdio.h>
#include "Delay.h"



int main(void)
{

	
	LED_Init();
MySerial_Init();


	
while(1)	
{
	
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);
uint8_t byte=USART_ReceiveData(USART1);
if(byte==0)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_0);
}
if(byte==1)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_0);
}
}	
	
	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值