day6:STM32MP157——串口通信实验

使用的是cortex A7内核

【串口通信的工作原理】

本次实验使用的是uart4的串口,分别使用了uart4_tx和uart4_rx两个引脚。根据板子的原理图我们可以知道,他们分别对应着芯片的PG11和PB2

从引脚名字也可以知道使用了GPIO口,所以本次实验同样需要使用到GPIO模块。再加上uart模块和RCC使能模块。所以本次实验一共需要使用到三个模块。基本工作框图如下:

【RCC使能】

通过芯片手册可以知道RCC对GPIO使能使用的是AHB总线,对UART使能是通过APB1总线

再在芯片手册中直接查询这两个总线的寄存器即可知道需要对哪一位数据进行修改进行使能

具体使能操作情况如下

    //使能GPIOB,GPIOG,UART4
    RCC->MP_AHB4ENSETR |= (0x1 << 1);
    RCC->MP_AHB4ENSETR |= (0x1 << 6);
    RCC->MP_APB1ENSETR |= (0x1 << 16);

【GPIO功能复用】

通过查询芯片手册可知,只需要对GPIO的AFRL或者AFRH寄存器进行修改即可。

端口复用寄存器存在两个的原因:

对端口的复用需要4位,而每个寄存器只有32位,所以每个端口复用寄存器只能操作8个GPIO口。但是每个口都有16个,所以需要两个端口复用寄存器来分别控制低8位口和高8位口,AFRL就操作0-7这8个,AFRH就操作8-15这8个口

所以本次使用的两个口PB2和PG11分别要修改的寄存器为GPIOB_AFRL和AFRHG_AFRH寄存器,再根据寄存器的结构便可以知道要修改的是哪几位。

现在我们知道了需要设置哪几位,但是设置成什么数字并不知道,继续查询芯片手册,我们需要把它复用成uart4的模式。

从上面这两张表就可以知道,只需要把PG11对应的几位设置成AF6,把PB2对应的几位设置成AF8即可,至此GPIO口的uart4复用功能就实现了。

【UART模块设置】

对uart模块的设置相对繁琐,具体分为以下几步:

1、设置数据长度为8

2、设置16位过采样

3、设置不需要校验位

4、设置1位停止位

5、设置不分频

6、设置波特率

7、对发送器、接收器、串口分别进行使能

对上面三张图的寄存器的对应位进行修改即可实现上述七个步骤。

值得一提的是在对BRR进行波特率设置的时候可以通过直接赋值的方式直接设置波特率,但是这个需要设置的值收到过采样频率的影响,由于8倍的过采样频率过于复杂,本次实验采用16倍采样频率,具体公式如下:

设置值 = 模块工作频率(HZ)/ 要设置的波特率(bit/s)

对uart模块进行读写操作的步骤

1、判断是否有数据需要读取或写入(对USART_ISR寄存器相应的位进行判断)

2、将需要读取的数据放入读取寄存器中(数据会存储在USART_RDR寄存器等待用户读取)

3、将需要发送的数据放入写寄存器中(将数据直接写入USART_TDR寄存器即可发送数据)

【代码】

在了解了以上串口工作原理之后就可以开始编写代码了。本次代码结合了昨天的led模块,实现了串口对灯的控制。具体功能见视频:

https://blink.csdn.net/details/1666295?spm=1001.2014.3001.5501

具体代码如下:

main.c

#include "uart4.h"

#include "led.h"



void delay(int ms)

{

	int i,j;

	for(i=ms;i>0;i--)

	{

		for(j=2000;j>0;j--)

		{}

	}

}



int main()

{

	uart4_init();

	led_init();

	// char i;

	char buf[30];

	while(1)

	{

		// i = getchar();

		// putchar(i + 1);

		gets(buf);

		if(strcmp(buf,"led1 on")==0)

		{

			led1_on();

			puts("exec success\r\n");

		}

		else if(strcmp(buf,"led1 off")==0)

		{

			led1_off();

			puts("exec success\r\n");

		}

		else if (strcmp(buf, "led2 on") == 0)

		{

			led2_on();

			puts("exec success\r\n");

		}

		else if (strcmp(buf, "led2 off") == 0)

		{

			led2_off();

			puts("exec success\r\n");

		}

		else if (strcmp(buf, "led3 on") == 0)

		{

			led3_on();

			puts("exec success\r\n");

		}

		else if (strcmp(buf, "led3 off") == 0)

		{

			led3_off();

			puts("exec success\r\n");

		}

		else

		{

			puts("error cmd\r\n");

		}

		

	}

	return 0;

}

uart4.c

#include "uart4.h"


void uart4_init()
{
    //使能GPIOB,GPIOG,UART4
    RCC->MP_AHB4ENSETR |= (0x1 << 1);
    RCC->MP_AHB4ENSETR |= (0x1 << 6);
    RCC->MP_APB1ENSETR |= (0x1 << 16);
    //设置pb2和pg11的管脚复用pb2/pg11
    GPIOB->MODER &= ~(0x3 << 4);
    GPIOG->MODER &= ~(0x3 << 22);
    GPIOB->MODER |= (0x1 << 5);
    GPIOG->MODER |= (0x3 << 23);

    GPIOB->AFRL &= ~(0xf << 8);
    GPIOB->AFRL |= (0x1 << 11);
    GPIOG->AFRH &= ~(0xf << 12);
    GPIOG->AFRH |= (0x3 << 13);

    //设置串口不使能,ue=0
    USART4->CR1 &= (~(0x1));
    //设置8位数据位
    USART4->CR1 &= (~(0x1 << 12));
    USART4->CR1 &= (~(0x1 << 28));
    //设置没有奇偶校验位
    USART4->CR1 &= (~(0x1 << 10));
    //设置1位停止位
    USART4->CR2 &= (~(0x3 << 12));
    //设置16倍过采样
    USART4->CR1 &= (~(0x1 << 15));
    //设置时钟不分频
    USART4->PRESC &= (~(0xf));
    //设置波特率为115200
    USART4->BRR = 0x22b;
    //使能发送器
    USART4->CR1 |= (0x1 << 3);
    //使能接收器
    USART4->CR1 |= (0x1 << 2);
    //使能uart4
    USART4->CR1 |= (0x1);
}

void putchar(char a)
{
    //先判断发送寄存器是否为空
    while(!(USART4->ISR & 0x1<<7)); //取出第七位的数据,如果是1表示 当前寄存器为空
    USART4->TDR = a;
    //不为空阻塞等待
    //为空向寄存器中写入数据
    //写入完成判断发送是否完成,未完成阻塞,完成函数结束
    while (!(USART4->ISR & 0x1 << 6));
}

char getchar()
{
    //判断接收寄存器中是否有数据有数据读取,没数据阻塞
    //读取成功返回该字符
    char a;
    while (!(USART4->ISR & 0x1 << 5));
    a = USART4->RDR;
    return a;
}

void puts(char *s)
{
    while(*s)
    {
        putchar(*s);
        s++;
    }
    putchar('\r');
    putchar('\n');
}

void gets(char *s)
{
    while(1)
    {
        *s = getchar();
        putchar(*s);
        if (*s == '\r')
        {
            break;
        }
        s++;
    }
    *s = '\0';
}


int strcmp(char *src,char *dest)
{
    char *p = src, *q = dest;
    while(*p==*q&&*p!='\0'&&*q!='\0')
    {
        p++;
        q++;
    }
    if(*p>*q)
    {
        return 1;
    }
    else if(*p<*q)
    {
        return -1;
    }
    else 
    {
        return 0;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/485481.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MCGS学习——用户管理

用户管理介绍 用户管理主要是为了实现触摸屏的安全操作&#xff0c;工业过程控制中&#xff0c;应该尽量避免由于人为的误操作所引发的故障或事故&#xff0c;而某些失误带来的后果是致命的&#xff1b;通过用户管理严格限制各类操作的权限&#xff0c;使不具备操作资格的人员…

软考高级:架构与中间件技术-软件复用概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

CHAT~(持续更新)

CHAT&#xff08;持续更新&#xff09; 实现一个ChatGPT创建API设计页面布局业务操作技术架构 编码其他 实现一个ChatGPT 创建API 最简单也最需要信息的一步 继续往下做的前提 此处省略&#xff0c;想要获取接口创建方式联系 设计 页面布局 按照官网布局 业务操作 注册登…

Linux 进程通信:匿名管道、实现进程池

目录 一、进程间通信 1、 为什么需要进程通信 2、发展和分类 二、管道 1、概念 2、特点 2、复制并共享 3、用fork来共享管道原理 4、站在文件描述符角度-深度理解管道 5、站在内核角度-管道本质 三、匿名管道 1、概念 2、创建 3、snprintf 4、父子进程中进行单…

抽取CLOB字段中XML的特定元素的VALUE值

在ORACLE数据库中&#xff0c;有时XML文件会被保存在CLOB字段中。 这时候&#xff0c;若是我们要获取此字段XML中特定元素的VALUE值&#xff0c;就需要用到xmltype 这个函数。 如下面的 XML文件&#xff0c;保存在 TABLE_A 的CLOB_K 字段&#xff0c;若是我们要获取其中的 Y…

onnx | onnx-simplifier安装和使用

安装&#xff1a; pip install -i https://pypi.douban.com/simple onnx-simplifierpip install -i http://mirrors.aliyun.com/pypi/simple onnx-simplifier 使用&#xff1a; python -m onnxsim face.onnx face_sim.onnx

Unity Canvas的三种模式

一、简介&#xff1a; Canvas的Render Mode一共有三种模式&#xff1a;Screen Space -OverLay、Screen Space-Camera、World Space Screen Space - Overlay&#xff08;屏幕空间 - 覆盖&#xff09;&#xff1a; 这是最简单的 Canvas 渲染模式。UI 元素在这个模式下将渲染在屏…

Oracle参数文件详解

1、参数文件的作用 参数文件用于存放实例所需要的初始化参数&#xff0c;因为多数初始化参数都具有默认值&#xff0c;所以参数文件实际存放了非默认的初始化参数。 2、参数文件类型 1&#xff09;服务端参数文件&#xff0c;又称为 spfile 二进制的文件&#xff0c;命名规则…

PostgreSQL11 | Windows系统安装PostgreSQL

本教程选取与参考书籍《PostgreSql11 从入门到精通》&#xff08;清华大学出版社&#xff09;的11大版本最新小版本11.22的安装作为教程案例 下载 下载PostgreSQL installer 下载到本地 安装 运行安装引导器 中国地区语言选项&#xff08;暂时&#xff09; Chinese(Simplifie…

2024牛客寒假算法基础集训营4补题

E&#xff1a;贪心数据结构 首先&#xff0c;我们看一个例子&#xff1a; 114514&#xff0c;令k3,我们从左开始&#xff0c;1&#xff0c;1&#xff0c;4&#xff0c;此时为3的倍数&#xff0c;那么我们就截断。 因为若我们在此截断&#xff0c;后面的5会对以后的数产生有利…

SSM | SSM框架整合

目录: 一、整合环境搭建整合思路准备所需JAR包编写配置文件 二、整合应用测试 作者简介 &#xff1a;一只大皮卡丘&#xff0c;计算机专业学生&#xff0c;正在努力学习、努力敲代码中! 让我们一起继续努力学习&#xff01; 该文章参考学习教材为&#xff1a; 《Java EE企业级应…

Qt——2D画图

基础画图函数 矩形 painter.drawRect(50,50,200,100); 圆角矩形 painter.drawRoundRect(50,50,200,200,50,50); xRadius和yRadius分别以矩形宽度和高度的一半的百分比指定&#xff0c;并且应该在0.0到100.0的范围内 弧线 painter.drawArc(50,50,200,200, -90*16, 90*16);…

基于nodejs+vue学生作业管理系统python-flask-django-php

他们不仅希望页面简单大方&#xff0c;还希望操作方便&#xff0c;可以快速锁定他们需要的线上管理方式。基于这种情况&#xff0c;我们需要这样一个界面简单大方、功能齐全的系统来解决用户问题&#xff0c;满足用户需求。 课题主要分为三大模块&#xff1a;即管理员模块和学生…

[AutoSar]BSW_ECUC模块配置

目录 关键词平台说明一、背景二、EcucGeneral2.1 BswInitialization 三、EcucHardware四、EcucPduCollection五、EcucPartitionCollection 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c; EB芯片厂商TI 英飞凌编程语…

三星解释其 108MP Nonacell 传感器中的 PDAF 像素遮蔽

Electronic Imaging 发表了三星论文“采用 Nonacell 和 Super PD 的 CMOS 图像传感器的新型 PDAF 校正方法,以提高合并模式下的图像质量”,作者为 Yeongheup Jang、Hyungwook Kim、Kundong Kim、Sungsu Kim、Sungyong Lee 和 Joonseo Yim。 本文提出了一种新的 PDAF 校正方法…

【stable diffusion扩散模型】一篇文章讲透

目录 一、引言 二、Stable Diffusion的基本原理 1 扩散模型 2 Stable Diffusion模型架构 3 训练过程与算法细节 三、Stable Diffusion的应用领域 1 图像生成与艺术创作 2 图像补全与修复 3 其他领域 四、Stable Diffusion的优势与挑战 &#x1f449;优势 &#x1f…

【云开发笔记No.9】Kanban与敏捷开发

Kanban看板起源于丰田。 看板&#xff08;Kanban&#xff09;一词来自日文&#xff0c;本义是可视化卡片。如下图所示&#xff0c;看板工具的实质是&#xff1a;后道工序在需要时&#xff0c;通过看板向前道工序发出信号——请给我需要数量的输入&#xff0c;前道工序只有得到看…

OpenHarmony IDL工具规格及使用说明书(仅对系统应用开放)

IDL接口描述语言简介 当客户端和服务器进行IPC通信时&#xff0c;需要定义双方都认可的接口&#xff0c;以保障双方可以成功通信&#xff0c;OpenHarmony IDL&#xff08;OpenHarmony Interface Definition Language&#xff09;则是一种定义此类接口的工具。OpenHarmony IDL先…

SpringBoot 文件上传(三)

之前讲解了如何接收文件以及如何保存到服务端的本地磁盘中&#xff1a; SpringBoot 文件上传&#xff08;一)-CSDN博客 SpringBoot 文件上传&#xff08;二&#xff09;-CSDN博客 这节讲解如何利用阿里云提供的OSS&#xff08;Object Storage Service)对象存储服务保存文件。…

Linux升级GCC

文章目录 一、安装 EPEL 仓库二、更新yum三、安装 CentOS 开发工具组四、安装scl五、安装gcc 11六、启用gcc 11七、设置永久使用 一、安装 EPEL 仓库 命令&#xff1a; yum install epel-release -y二、更新yum 命令&#xff1a; yum update -y三、安装 CentOS 开发工具组 …
最新文章