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为管脚复用功能//PB2GPIOB->MODER &= (~(0x3<<4));GPIOB->MODER |= (0x2<<4);//PG11GPIOG->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));//设置波特率为115200USART4->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]->1RCC->MP_APB1ENSETR |= (0x1 << 16);// 设置GPIOB和GPIOG的时钟使能// RCC_MP_AHB4ENSETR[6]->1// RCC_MP_AHB4ENSETR[1]->1RCC->MP_AHB4ENSETR |= (0x1 << 1);RCC->MP_AHB4ENSETR |= (0X1 << 6);// 设置PG11和PB2功能复用为UART4功能// PG11// GPIOG_MODER[23:22]->10GPIOG->MODER &= (~(0X3 << 22));GPIOG->MODER |= (0X2 << 22);// GPIOG_AFRH[15:12]->0110GPIOG->AFRH &= (~(0xf << 12));GPIOG->AFRH |= (0x6 << 12);// PB2// GPIOB_MODER[5:4]->10// GPIOB_AFRL[11:8]->1000GPIOB->MODER &= (~(0x3 << 4));GPIOB->MODER |= (0X2 << 4);GPIOB->AFRL &= (~(0xF << 8));GPIOB->AFRL |= (0x8 << 8);// 禁用串口USART4->CR1 &= (~0x1);// 设置数据8个数据位 CR1[28]->0  CR1[12]-》0USART4->CR1 &= (~(0X1 << 28));USART4->CR1 &= (~(0X1 << 12));// 设置没有校验位CR1[10]->0USART4->CR1 &= (~(0X1 << 10));// 设置1个停止位CR2[13:12]->00USART4->CR2 &= (~(0x3 << 12));// 设置16倍采样 CR1[15]->0USART4->CR1 &= (~(0X1 << 15));// 设置波特率为115200 BRR=0X22BUSART4->BRR |= 0X22B;// 设置1分频 PRESC[3:0]->0000USART4->PRESC &= (~(0XF));// 使能发送器 CR1[3]->1USART4->CR1 |= (0X1 << 3);// 使能接收器 CR1[2]->1USART4->CR1 |= (0X1 << 2);// 使能串口 CR1[0]->1USART4->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串口工具打印一个bwhile (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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【电机参数】直流无刷电机机械转速、ud、uq、us、输出功率、相反电动势幅值、载波周期、转矩常数

【电机参数】直流无刷电机机械转速、ud、uq、us、输出功率、相反电动势幅值、载波周期、转矩常数 前言 【电机控制】直流有刷电机、无刷电机汇总——持续更新 使用工具&#xff1a; 1.示波器&#xff1a;PICO2205A 2.电桥LCR&#xff1a;VICIOR4090A 3.电流钳&#xff1a;汉泰…

接口测试相关

接口测试&#xff0c;接口 接口是数据交互的入口和出口 接口是一套规范和标准 统一设计标准 前后端相对独立 扩展型灵活 接口文档。 接口测试 接口测试环境&#xff0c;运行程序&#xff0c;自己搭建环境 接口测试插件 谷歌postman 火狐 restclient java测试工具为j…

Linux系统的磁盘管理与文件系统

目录 一、磁盘结构 1.物理结构 2.数据结构 二、MBR与磁盘分区表示 1.MBR 2.磁盘分区表示 分区的优点 分区的缺点 三、文件系统类型 1.文件系统的组成 XFS SWAP EXT4 2.磁盘管理工具 四、Linux系统添加新硬盘的步骤 一、磁盘结构 1.物理结构 所有存储的设备都在…

【面试经典 150 | 数组】最后一个单词的长度

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;遍历 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

Android 性能优化之黑科技开道(二)

3. 其它可以黑科技优化的方向 3.1 核心线程绑定大核 3.1.1 定义 核心线程绑定大核的思路也很容易理解&#xff0c;现在的 CPU 都是多核的&#xff0c;大核的频率比小核要高不少&#xff0c;如果我们的核心线程固定运行在大核上&#xff0c;那么应用性能自然会有所提升。 核…

【Qt】Qt界面构建与对象管理:从 “Hello World“ 到内存释放

文章目录 1. 通过图形化界面创建控件2. 通过纯代码方式创建控件3. 对象树管理与内存管理小结&#xff1a; 在软件开发中&#xff0c;构建用户界面是至关重要的一步。Qt作为一个跨平台的C框架&#xff0c;提供了强大的界面构建工具和对象树管理机制&#xff0c;使得界面开发变得…

Leetcode 3123. Find Edges in Shortest Paths

Leetcode 3123. Find Edges in Shortest Paths 1. 解题思路2. 代码实现 题目链接&#xff1a;3123. Find Edges in Shortest Paths 1. 解题思路 这一题思路上的话就是一个最短路径的求解问题&#xff0c;我们使用一个堆排即可对其进行实现。 不过&#xff0c;做题的时候挺犹…

单页面首屏优化,打包后大小减少64M,加载速度快了13.6秒

需求背景 从第三方采购的vue2 ElementUI实现的云管平台&#xff0c;乙方说2011年左右就开始有这个项目了&#xff08;那时候有Vue了吗&#xff0c;思考.jpg&#xff09;。十几年的项目&#xff0c;我何德何能可以担此责任。里面的代码经过多人多年迭代可以用惨不忍睹来形容&a…

Qt做关于界面

在上位机系统中&#xff0c;经常需要显示当前软件版本&#xff0c;当前fpga版本&#xff0c;那么咱就做一个help的菜单的关于界面 解决的问题&#xff1a; 解决显示版本信息的UI Axure界面图&#xff1a; 如何实现&#xff1a; 实现文件的存储&#xff1a;QSetting来存储版…

初始jQuery

目录 前言: 1.jQuery介绍 2.引入jQuery 3.工厂函数$() 3.1使用CSS选择器获取元素&#xff1a; 3.2将原生JavaScript对象转换为jQuery对象&#xff1a; 3.3从jQuery对象转换到原生JavaScript对象&#xff1a; 4. jQuery获取元素 4.1基础选择器 4.1.1标签选择器&#xf…

【入门深入篇】本章包括条件查询、排序查询、分页查询、分页实战举例(小程序之云函数开发入门到使用发布上线实操)

1. 条件查询 假设我们需要查询年龄大于等于 18 岁的用户记录: // 云函数入口函数 exports.main = async (event, context) => {const {minAge } = event; // 从事件中获取用户提供的最小年龄try {<

玩转Virtual Box虚拟机

玩转Virtual Box虚拟机 虚拟化技术和虚拟机简介 什么是虚拟化技术&#xff1f; 虚拟化技术是将计算机的各种硬件资源予以抽象、转换、分割、组合的一种计算机技术。虚拟化技术打破了实体结构间不可切割的障碍&#xff0c;从而使用户可以按照需求重新组合硬件资源&#xff0c…

NX二次开发UF_MTX(矩阵运算)常用函数

目录 一、概述 二、函数的介绍 2.1 UF_MTX3_copy&#xff08;复制原来矩阵&#xff09; 2.2 UF_MTX3_determinant&#xff08;计算矩阵的行列式&#xff09; 2.3 UF_MTX3_identity&#xff08;单位矩阵&#xff09; 2.4 UF_MTX3_initialize&#xff08;可以根据X、Y方向向…

写在30岁

关于新角色 怀孕之后感觉自己的天空从蓝色变成了灰色。 以前的生活&#xff0c;说很累&#xff0c;也不累。每天早上一杯咖啡&#xff0c; 然后噼里啪啦开始一天的工作。即使有压力、会烦心&#xff0c;但是身体上不会有任何的不适。在入职的第一年&#xff0c;整个月报备 6 点…

linux 驱动-匹配

目录 匹配入口 匹配顺序(platform_match ) 方式1: 方式2&#xff08;重点&#xff09; 方式3 方式4 (重点) 匹配入口 driver_match_device 实际调用platform_match driver_match_device(drv, dev);static inline int driver_match_device(struct device_driver *drv,str…

R: 阿尔法α多样性计算和箱图制作,以及差异分析

# install.packages("vegan") library(vegan) library(ggplot2) library(ggpubr)setwd("xxx") # 使用read.table()函数读取数据 df <- read.table("xxx", header TRUE, row.names 1)# 转置数据框 df <- t(df)# 计算每个样品的香农多样性…

数据中台建设五步法之高阶规划

​系统都是为应用而生的&#xff0c;数据中台也不例外。要构建一套数据中台服务于企业内部和外部运营&#xff0c;需要有成熟的建设方法论作为指导。数据中台建设方法论可分为高阶规划、系统设计、开发实施、试运行和持续运营 5 个阶段。 本篇内容为大家讲解第一阶段——高阶规…

Linux Kernel入门到精通系列讲解(QEMU-虚拟化篇) 2.2 新增加CPU外设之UART、中断控制器和pFLASH

1.概述 上一章节我们将CPU和部分memory已经初始化完成了,具体实现可以查看代码仓库,本章节我们将在上一章节的基础之上去增加pFlash设备(作为初始化完ROM后的第一个代码存储区)、中断控制器和UART设备。 static const MemMapEntry naruto_soc_memmap[] = {[NARUTO_SOC_RO…

【Linux】虚拟机与Xshell及VS Code的连接

一、基础环境 虚拟机&#xff1a;VMware Workstation Pro 虚拟机镜像&#xff1a;ubuntu-18.04.5-desktop-amd64.iso 其他&#xff1a;Xshell 6、Xftp 6、Visual Studio Code 上述软件的安装操作不再赘述&#xff0c;CSDN上有大量的优秀博文&#xff0c;可参考&#xff1a;详细…

SpringBoot---------Lombook

Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具&#xff0c;通过使用对应的注解&#xff0c;可以在编译源码的时候生成对应的方法&#xff0c;也就是简化咱们之前pojo&#xff0c;实体类里面臃肿的get/set有参无参。 首先查看一…