ARM_day6:实现字符串数据收发函数的封装

程序代码:

uart4.h:

#ifndef __UART4_H__
#define __UART4_H__
#include"stm32mp1xx_gpio.h"
#include"stm32mp1xx_rcc.h"
#include"stm32mp1xx_uart.h"
void uart4_config();
void putchar(char dat);
char getchar();
void puts(char *s);
void gets(char *s);
#endif

uart4.c:

#include "uart4.h"

void uart4_config()
{
    //使能GPIOB\GPIOG\UART4的外设时钟
    RCC->MP_AHB4ENSETR |= (0x1<<1);
    RCC->MP_AHB4ENSETR |= (0x1<<6);
    RCC->MP_APB1ENSETR |= (0x1<<16);
    //设置PG11和PB2为管脚复用功能
    //PB2
    GPIOB->MODER &= (~(0x3<<4));
    GPIOB->MODER |= (0x2<<4);
    //PG11
    GPIOG->MODER &= (~(0x3<<22));
    GPIOG->MODER |= (0x2<<22);
    //设置PG11为UART4_TX功能
    GPIOG->AFRH &= (~(0xf<<12));
    GPIOG->AFRH |= (0X6<<12);
    //设置PB2为UART4_RX功能
    GPIOB->AFRL &= (~(0xf<<8));
    GPIOB->AFRL |= (0X8<<8);
    //设置串口不使能
    USART4->CR1 &= (~0x1);
    //设置8位数据位
    USART4->CR1 &= (~(0x1<<12));
    USART4->CR1 &= (~(0x1<<28));
    //设置没有校验位
    USART4->CR1 &= (~(0x1<<10));
    //设置时钟频率不分频
    USART4->PRESC &= (~0xf);
    //设置16倍过采样
    USART4->CR1 &= (~(0x1<<15));
    //设置1位停止位
    USART4->CR2 &= (~(0x3<<12));
    //设置波特率为115200
    USART4->BRR=0X22B;
    //使能发送器
    USART4->CR1 |= (0X1<<3);
    //使能接收器
    USART4->CR1 |= (0X1<<2);
    //使能串口
    USART4->CR1 |= (0X1<<0);
}

//发送单个字符
void putchar(char dat)
{
    //当发送数据寄存器中没有数据时可以发送
    while (!(USART4->ISR & (0x1<<7)));//当TDR中有数据时阻塞等待没有数据
    USART4->TDR = dat;//向发送数据寄存器中写入数据
    //等大传输完成函数结束
    while (!(USART4->ISR & (0x1<<6)));
}

//接收单个字符
char getchar()
{
    //当接收数据寄存器中有有效数据时读取
    while (!(USART4->ISR & (0x1<<5)));
    //将读取到的数据返回
    return USART4->RDR;
}

//发送字符串
void puts(char *s)
{
    while(1)
    {
        if(*s=='\0')
        {
            break;
        }
        putchar(*s);
        s++;
    }
    //发送一个回车
    putchar('\r');//回车
     //换行
    putchar('\n');
}
//接收字符串
void gets(char *s)
{
    while(1)
    {
        *s=getchar();
        //循环接收单个字符,检测到回车键被按下,结束'\r'
        if(*s=='\r')
        {
            break;
        }
        putchar(*s);
        s++;
    }
     //在接收的字符串最后补上一个'\0'
     *s='\0';
   //发送一个'\n'表示在串口下一行进行显示
   putchar('\n');
}

main.c:

#include "uart4.h"
//手动封装延时函数
void delay_ms(int ms)
{
    int i,j;
    for(i=0;i<ms;i++)
    {
        for(j=0;j<2000;j++)
        {

        }
    }
}
int main()
{
    //uart4初始化
    uart4_config();
	char s[128];
    while(1)
    {
		gets(s);
		puts(s);
    }
    return 0;
}

运行结果:

2、通过串口发送指令,控制LED\蜂鸣器等外设工作

程序代码:

uart4.h:

#ifndef __UART4_H__
#define __UART4_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_uart.h"
void led_init();
void uart4_init();
void myputchar(char i);
char mygetchar();
void puts(char *s);
char *gets();
int mystrcmp(char *dest, char *src);

#endif

uart4.c:

#include "uart4.h"

char buf[51] = {0};
// led数据初始化
void led_init()
{
    // 设置GPIOE/GPIOF时钟使能
    RCC->MP_AHB4ENSETR |= (0x3 << 4);
    // 设置PE10/PE8/PF10为输出模式
    GPIOE->MODER &= (~(0x3 << 20));
    GPIOE->MODER |= (0x1 << 20);
    GPIOE->MODER &= (~(0x3 << 16));
    GPIOE->MODER |= (0x1 << 16);
    GPIOF->MODER &= (~(0x3 << 20));
    GPIOF->MODER |= (0x1 << 20);
    // 设置PE10/PE8/PF10为推挽输出
    GPIOE->OTYPER &= (~(0x1 << 10));
    GPIOE->OTYPER &= (~(0X1 << 8));
    GPIOF->OTYPER &= (~(0x1 << 10));
    // 设置PE10/PE8/PF10输出速度为低速
    GPIOE->OSPEEDR &= (~(0x3 << 20));
    GPIOE->OSPEEDR &= (~(0X3 << 16));
    GPIOF->OSPEEDR &= (~(0x3 << 20));
    // 设置PE10/PE8/PF10无上拉下拉
    GPIOE->PUPDR &= (~(0x3 << 20));
    GPIOE->PUPDR &= (~(0X3 << 16));
    GPIOF->PUPDR &= (~(0X3 << 20));
}

// 串口数据初始化
void uart4_init()
{
    // 设置UART4的RCC时钟使能
    // RCC_MP_APB1ENSETR[16]->1
    RCC->MP_APB1ENSETR |= (0x1 << 16);
    // 设置GPIOB和GPIOG的时钟使能
    // RCC_MP_AHB4ENSETR[6]->1
    // RCC_MP_AHB4ENSETR[1]->1
    RCC->MP_AHB4ENSETR |= (0x1 << 1);
    RCC->MP_AHB4ENSETR |= (0X1 << 6);
    // 设置PG11和PB2功能复用为UART4功能
    // PG11
    // GPIOG_MODER[23:22]->10
    GPIOG->MODER &= (~(0X3 << 22));
    GPIOG->MODER |= (0X2 << 22);
    // GPIOG_AFRH[15:12]->0110
    GPIOG->AFRH &= (~(0xf << 12));
    GPIOG->AFRH |= (0x6 << 12);
    // PB2
    // GPIOB_MODER[5:4]->10
    // GPIOB_AFRL[11:8]->1000
    GPIOB->MODER &= (~(0x3 << 4));
    GPIOB->MODER |= (0X2 << 4);
    GPIOB->AFRL &= (~(0xF << 8));
    GPIOB->AFRL |= (0x8 << 8);
    // 禁用串口
    USART4->CR1 &= (~0x1);
    // 设置数据8个数据位 CR1[28]->0  CR1[12]-》0
    USART4->CR1 &= (~(0X1 << 28));
    USART4->CR1 &= (~(0X1 << 12));
    // 设置没有校验位CR1[10]->0
    USART4->CR1 &= (~(0X1 << 10));
    // 设置1个停止位CR2[13:12]->00
    USART4->CR2 &= (~(0x3 << 12));
    // 设置16倍采样 CR1[15]->0
    USART4->CR1 &= (~(0X1 << 15));
    // 设置波特率为115200 BRR=0X22B
    USART4->BRR |= 0X22B;
    // 设置1分频 PRESC[3:0]->0000
    USART4->PRESC &= (~(0XF));
    // 使能发送器 CR1[3]->1
    USART4->CR1 |= (0X1 << 3);
    // 使能接收器 CR1[2]->1
    USART4->CR1 |= (0X1 << 2);
    // 使能串口 CR1[0]->1
    USART4->CR1 |= (0X1);
}
// 封装函数发送一个字符数据
void myputchar(char c)
{
    // 判断发送数据寄存器有没有数据,没有数据时可以发送
    while (!(USART4->ISR & (0X1 << 7)))
        ;
    USART4->TDR = c; // 将要发送的数据保存在发送寄存器中
    while (!(USART4->ISR & (0X1 << 6)))
        ; // 数据传输完成,函数结束
}
char mygetchar()
{
    char c;
    // 判断是否有数据准备好
    while (!(USART4->ISR & (0X1 << 5)))
        ; // 数据传输完成,函数结束
    c = USART4->RDR;
    return c;
}

// 输出一个字符串
void puts(char *s)
{
    while (*s)
    {
        myputchar(*s++);
    }
    myputchar('\n'); // 切换到下一行
    myputchar('\r'); // 切换到一行的开头
}

// 读取一个字符串
char *gets()
{
    unsigned int i;
    for (i = 0; i < 50; i++)
    {
        buf[i] = mygetchar();
        myputchar(buf[i]);
        if (buf[i] == '\r')
            break;
    }
    buf[i] = '\0';
    myputchar('\n');
    myputchar('\r');

    return buf;
}

int mystrcmp(char *dest, char *src)
{
    while (*dest && *src)
    {
        if (*dest != *src)
            return *dest - *src;
        dest++;
        src++;
    }
    if (*dest == *src)
        return 0;
}

main.c:

#include "uart4.h"

int main()
{
    led_init();
    // 1.串口的初始化
    uart4_init();
    char *str;
    // char a;

    // 现象是发送一个a串口工具打印一个b
    while (1)
    {
        str = gets();
        puts(str);
        // // 2.从串口读取一个字符
        // a = mygetchar();
        // // 3.将读取到的字符+1发送回去
        // myputchar(a + 1);

        if (mystrcmp(str, "led1_on") == 0)
            GPIOE->ODR |= (0x1 << 10);
        else if (mystrcmp(str, "led1_off") == 0)
            GPIOE->ODR &= ~(0x1 << 10);
        else if (mystrcmp(str, "led2_on") == 0)
            GPIOF->ODR |= (0x1 << 10);
        else if (mystrcmp(str, "led2_off") == 0)
            GPIOF->ODR &= ~(0x1 << 10);
        else if (mystrcmp(str, "led3_on") == 0)
            GPIOE->ODR |= (0x1 << 8);
        else if (mystrcmp(str, "led3_off") == 0)
            GPIOE->ODR &= ~(0x1 << 8);
    }
    return 0;
}

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

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

相关文章

GeoServer 样式指南

毫无疑问,Geoserver 是遵循 OGC 标准共享空间数据的最佳方式之一。 Geoserver 允许我们以 WMS 格式公开数据,通过以栅格(png、jpeg 等)格式显示大量矢量数据,使开发人员和用户的工作变得非常轻松。 本博客介绍了 GeoServer 功能的又一领域,即动态设置数据样式。首先,矢量…

AGM AG32 MCU在汽车UWB应用方案

AG32的汽车UWB应用方案 汽车电子产品的日益成熟&#xff0c;包括ADAS和车载信息娱乐&#xff0c;正在推动对CPLD的需求。例如&#xff0c;利用安装在车上的各种传感器&#xff08;如雷达、摄像头和激光雷达等&#xff09;来感知周围环境&#xff0c;实现实时监测和数据处理。这…

2023年网络安全行业:机遇与挑战并存

2023年全球网络安全人才概况 根据ISC2的《2023年全球网络安全人才调查报告》&#xff0c;全球的网络安全专业人才数量达到了550万&#xff0c;同比增长了8.7%。然而&#xff0c;这一年也见证了网络安全人才短缺达到了历史新高&#xff0c;缺口数量接近400万。尤其是亚太地区&am…

Centos7 的 Open Stack T 版搭建流程 --- (三)配置消息队列

配置消息队列 文章目录 配置消息队列&#xff08;1&#xff09;安装 RabbitMQ 服务并配置新用户权限controller &#xff08;2&#xff09;如何开启图形化&#xff08;拓展&#xff09; &#xff08;1&#xff09;安装 RabbitMQ 服务并配置新用户权限 controller yum install…

【支持CPU机器】一个Python文件搭建你本地图片生成编辑会话系统——TaskMatrix架构解读

一. 先上效果 TaskMatrix通过ChatGPT 和一系列 Visual Foundation 模型&#xff0c;通过聊天实现图片的绘制、问答和编辑。 二. 流程概览 1. 使用者流程 多模型会话上下文用户指令输入到本系统 -> 多模式会话基础模型 -> 理解用户指令上下文&#xff0c;调用API选择器&…

使用ssh无显示器连接树莓派并配置vnc

配置网络连接并开启ssh 使用树莓派官方的烧录工具&#xff1a; Windows下载链接 Linux下载连接 Mac下载链接 Linux还可以使用命令下载 sudo apt install rpi-imager 在烧录前点击小齿轮配置好网络连接和ssh 如果你不知道树莓派的ip地址&#xff0c;可以使用网线连接电脑和…

新品上线!这个真核宿主-宏病毒组分析流程,太合我意了吧!

病毒被称为地球的“暗物质”&#xff0c;亟待研究。近年来&#xff0c;宏病毒组&#xff08;富集/不富集&#xff09;的研究呈爆炸式增长&#xff0c;人们越来越意识到病毒在调节微生态平衡上发挥着重要作用。 对于宏病毒组项目而言&#xff0c;在新病毒的发现、病毒溯源和进化…

FastJson2中FastJsonHttpMessageConverter找不到类问题

问题描述 如果你最近也在升级FastJson到FastJson2版本&#xff0c;而跟我一样也遇到了FastJsonHttpMessageConverter找不到类问题以及FastJsonConfig找不到问题&#xff0c;那么恭喜你&#xff0c;看完本文&#xff0c;安装完fastjson2、fastjson2-extension、fastjson2-exte…

【Linux学习】Linux调试器-gdb使用

这里写目录标题 &#x1f302;背景&#x1f302;gdb使用&#x1f302;指令总结&#xff1a; &#x1f302;背景 程序的发布方式有两种&#xff0c;debug模式和 release模式 其中&#xff0c;debug模式是可以被调试的&#xff0c;到那时release模式是不能被调试的&#xff1b; …

【Python】使用Python计算简单数值积分

题外话&#xff0c;Python语言命名的来源&#xff1a;&#xff08;见下图&#xff09;Monty Python巨蟒剧团 1、积分题目&#xff08;3&#xff09; 2、解析解答 3、Python计算代码 import math import scipy.integrate as integrate# 积分区间 # x_min 0.0 # 1 # x_min …

Android14 - WindowManagerService之客户端Activity布局

Android14 - WindowManagerService之客户端Activity布局 一、主要角色 WMS作为一个服务端&#xff0c;有多种客户端与其交互的场景。我们以常见的Activity为例&#xff1a; Activity&#xff1a;在ActivityThread构建一个Activity后&#xff0c;会调用其attach方法&#xff0c;…

elementui单个输入框回车刷新整个页面

<!-- 搜索 --> <el-form :model"queryParams" ref"queryForm" :inline"true"><el-form-item label"名称" prop"nameLike"><el-input v-model"queryParams.nameLike" placeholder"请输入…

docker的安装以及docker中nginx配置

机器 test3 192.168.23.103 1机器初始化配置 1.1关闭防火墙&#xff0c;清空防火墙规则 systemctl stop firewalld iptables -F setenforce 01.2部署时间同步 yum install ntp ntpdate -y1.3安装基础软件包 yum install -y wget net-tools nfs-utils lrzsz gcc gcc-c make…

nvm管理多个node版本,快速来回切换node版本

前言 文章基于 windows环境 使用nvm安装多版本nodejs。 最近公司有的项目比较老需要降低node版本才能运行&#xff0c;由于来回进行卸载不同版本的node比较麻烦&#xff1b;所以需要使用node工程多版本管理&#xff0c;后面自己就简单捯饬了一下nvm来管理node&#xff0c;顺便…

将城市名称替换成简写

图片左边是城市全称&#xff0c;右边是城市简写。 现在有一句话“this is Republic of Korea,that is United States of America”&#xff0c;要将其中的城市全称替换成城市简写。 #"Republic of Korea"替换成 South Korea s"this is Republic of Korea,that …

C语言数据结构之链表

目录 前言 \color{maroon}{前言} 前言1.链表的概念及结构2.链表的分类3.无头单向非循环链表的实现4.带头双向循环链表的实现5.顺序表和链表的对比 前言 \color{maroon}{前言} 前言 在上一篇博客中我们提到&#xff0c;线性表包括顺序表和链表&#xff0c;顺序表在上篇博客中已…

【Java基础】23.接口

文章目录 一、接口的概念1.接口介绍2.接口与类相似点3.接口与类的区别4.接口特性5.抽象类和接口的区别 二、接口的声明三、接口的实现四、接口的继承五、接口的多继承六、标记接口 一、接口的概念 1.接口介绍 接口&#xff08;英文&#xff1a;Interface&#xff09;&#xf…

运维小技能:nacos部署(外接mysql)

文章目录 I 安装nacos(m1版本)1.1 镜像启动1.2 查看docker容器日志1.3 开启鉴权II 外接mysql的docker部署方式2.1 复制mysql-schema.sql2.2 导入mysql-schema.sqlIII 配置远程用户3.1 创建数据库远程用户3.2 查看远程用户是否有密码I 安装nacos(m1版本) docker search nacos:查…

【前端工程化指南】Git常见操作之仓库相关操作

初始化本地仓库&#xff08;init&#xff09; 我们可以使用git init命令在当前或指定目录中初始化一个新的本地仓库&#xff0c;创建.git目录并设置仓库的基本配置。初始化仓库完成后&#xff0c;你可以使用其他 Git 命令来进行版本控制、提交更改以及与远程仓库进行交互。 命…

3月衣物清洁行业数据概况和趋势分析:总销额环比上涨超60%!

人们日常生活离不开衣物清洁产品&#xff0c;同时随着生活品质得提高和消费者健康意识得增强&#xff0c;对于衣物清洁行业的需求量与日俱增。作为日常必备的消耗品&#xff0c;衣物清洁产品备受消费者关注。借此&#xff0c;衣物清洁行业在3月份表现出稳定的发展态势。 根据鲸…