底层10.3——串口实验复习

目录

通信协议 

A7

uart4.h

 uart4.c

main.c

M4(核心代码)


串口一共有三根线:RXD\TXD\GND

RXD:接收数据线

TXD:发送数据线

GND:地线

通信协议 

1.空闲态: UART总线不在传输数据的时候,总线处于空闲状态,为高电平

2.起始信号 开始信号,串口通信的开始标志位

3.数据位 串口发送数据,先发低位,再发高位

4.奇/偶校验位:校验数据是否正确

        奇校验:数据位和校验位1的个数为奇数

                假设数据位0x55(0101 0101),校验位1

                假设数据位0x51(0101 0001),校验位0

        偶校验:数据位和校验位1的个数为偶数

                假设数据位0x55(0101 0101),校验位0

                假设数据位0x51(0101 0001),校验位1

5.停止信号:发送数据结束,回到高电平状态,校准时钟信号 一帧数据发送结束后,需要校准时钟信号,为什么需要校准时钟信号呢?

        因为串口采用的是异步通信方式,双方都有自己独立的时钟源,虽然设置了双方的时钟源保持一致, 但是在发送数据时,每发送一帧数据时,都会产生误差,越往后,发送的数据,累计误差越大, 所以每发送一帧数据之后,需要校准时钟信号

A7

uart4.h

#ifndef __UART4_H__
#define __UART4_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_uart.h"
//1.初始化函数
void uart4_init();
//2.发送一个字符
void put_char(const char str);
//3.接收一个字符
char get_char();
//4.发送一个字符串
void put_string(const char *str);
//5.接收一个字符串
char *get_string();




#endif

 uart4.c

#include "uart4.h"
extern void delay_ms(int ms);
//1.初始化函数
void uart4_init()
{
	//rcc章节初始化
	RCC->MP_AHB4ENSETR |= (0x1<<1);//GPIOB ENSETR
	RCC->MP_AHB4ENSETR |= (0x1<<6);//GPIOG ENSETR
	RCC->MP_APB1ENSETR |=(0x1<<16);//UART4 ENSETR
	//gpio章节初始化
	GPIOB->MODER &= (~(0x3<<4));
	GPIOB->MODER |= (0x2<<4);
	GPIOG->MODER &= (~(0x3<<22));
	GPIOG->MODER |= (0x2<<22);
	
	GPIOB->AFRL &= (~(0xf<<8));
	GPIOB->AFRL |= (0x8<<8);
	GPIOG->AFRH &= (~(0xf<<12));
	GPIOG->AFRH |= (0x6<<12);
	//uart章节初始化
	if (USART4->CR1 & (0x1<<0))
	{
		delay_ms(500);
		USART4->CR1 &= (~(0x1<<0));//将UE位禁止
	}
	//1.串口初始化 8位数据位 无奇偶校验
	USART4->CR1 &= (~(0x1<<12));
	USART4->CR1 &= (~(0x1<<28));//8数据位
	USART4->CR1 &= (~(0x1<<10));//无奇偶校验
	//2.设置串口一位停止位
	USART4->CR2 &= (~(0x3<<12));
	//3.设置串口的16位采样率
	USART4->CR1 &= (~(0x1<<15));
	//4.设置串口不分频
	USART4->PRESC &=(~(0xf));
	//5.设置串口波特率为115200
	USART4->BRR &=(~(0xffff));
	USART4->BRR |=(0x22b);
	//6.设置串口发送且使能
	USART4->CR1 |= (0x1<<3);//无奇偶校验
	//7.设置串口接收器使能
	USART4->CR1 |= (0x1<<2);//无奇偶校验
	//8.设置串口使能
	USART4->CR1 |= (0x1<<0);//无奇偶校验
}
//2.发送一个字符
void put_char(const char str)
{
	//1.判断发送数据寄存器是否有数据ISR[7]
	//读0说明发送数据寄存器满,需要等待
	//读1发送数据寄存器为空,才可以发送下一个字节数据
	
	while(!(USART4->ISR & (0x1<<7)));
	
	//2.将要发送的字符,写入到发送数据寄存器中
	USART4->TDR &=(~(0xff));
	USART4->TDR=str;
	//3.判断数据是否发送完成
	//读0发送数据没有完成
	//读1发送数据完成,可以发送下一帧数据
	while(!(USART4->ISR & (0x1<<6)));
}

//3.接收一个字符
char get_char()
{
	char ch;
	//1.判断接收寄存器是否有数据可读
	//读0:没有数据可读
	//读1:有数据可读
	while(!(USART4->ISR & (0x1<<5)));
	//2.将接收数据寄存器中的内容读出来
	ch=USART4->RDR;

	return ch;
}
//4.发送一个字符串
void put_string(const char* str)
{
	put_char('\n');
	put_char('\r');
	while(*str != '\0')
	{
		put_char(*str);
		str++;
	}
	put_char('\n');
	put_char('\r');
}
char buf[50]={0};

//5.接收一个字符串
char* get_string()
{
	//1.循环进行接收
	//2.循环实现,接受一个字符之后,发送一个字符
	//当键盘的回车键按下之后,代表字符串接收结束'\r'
	while(!(USART4->ISR & (0x1<<5)));
	int i=0;
	while ((buf[i]=get_char())!='\r')
	{
		put_char(buf[i]);
		i++;
	}
	//3.字符串补'\0';
	buf[i]='\0';
	//put_char('\n');
	return buf;
}




main.c

#include "uart4.h"



extern void printf(const char *fmt, ...);

void delay_ms(int ms)

{

	int i,j;

	for(i=0;i<ms;i++)

		for (j=0;j<1800;j++);

		

}

int main()

{

	uart4_init();

	

	while (1)

	{

		//put_char(get_char()+1);

		put_string(get_string());

	}

	return 0;

}

M4

    int fputc(int ch,FILE* stream)
{
//判断发送寄存器是否为空
while(!(huart4.Instance->ISR & (0x1 << 7)));
//将要发送的数据放入到发送寄存器中
huart4.Instance->TDR = ch;

//判断是否为'\n'
if(ch == '\n')
{
//判断发送寄存器是否为空
while(!(huart4.Instance->ISR & (0x1 << 7)));
huart4.Instance->TDR = '\r';
}
return ch;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值