STM32单片机并口通信编程实例:代码详解与应用案例

news2024/11/16 5:57:25

 

引言: 单片机并口通信是一种传统而常用的通信方式,通过并行方式进行数据传输。尽管串口通信在现代应用中更加普遍,但并口通信在一些特定领域的应用仍然具有重要意义。本文将介绍单片机并口通信的原理、配置和实践方法,并给出STM32单片机的示例代码和详细的代码说明和注释。

一、单片机并口通信的原理和工作方式 1.1 并口通信的基本原理 1.2 数据线和控制线的功能与作用 1.3 并口通信的工作流程和时序

二、STM32单片机并口通信的硬件配置与连接 2.1 并口通信引脚的配置 2.2 外部电路的设计与连接 2.3 STM32的GPIO模式配置与初始化

三、STM32单片机并口通信的编程方法 3.1 并口通信寄存器的配置与初始化 3.2 并口数据的发送和接收 3.3 并口通信中的常见问题和解决方法

四、STM32单片机并口通信的实例代码和注释

#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"

#define DATA_BUS_GPIO_PORT  GPIOB
#define DATA_BUS_GPIO_PIN_0 GPIO_PIN_0
#define DATA_BUS_GPIO_PIN_1 GPIO_PIN_1
#define DATA_BUS_GPIO_PIN_2 GPIO_PIN_2
#define DATA_BUS_GPIO_PIN_3 GPIO_PIN_3
#define DATA_BUS_GPIO_PIN_4 GPIO_PIN_4
#define DATA_BUS_GPIO_PIN_5 GPIO_PIN_5
#define DATA_BUS_GPIO_PIN_6 GPIO_PIN_6
#define DATA_BUS_GPIO_PIN_7 GPIO_PIN_7

#define CTRL_PORT GPIOA
#define WE_PIN    GPIO_PIN_0
#define RE_PIN    GPIO_PIN_1

void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  while (1)
  {
    // 数据写入并口
    HAL_GPIO_WritePin(DATA_BUS_GPIO_PORT, DATA_BUS_GPIO_PIN_0 | DATA_BUS_GPIO_PIN_1 | DATA_BUS_GPIO_PIN_2 | DATA_BUS_GPIO_PIN_3 | DATA_BUS_GPIO_PIN_4 | DATA_BUS_GPIO_PIN_5 | DATA_BUS_GPIO_PIN_6 | DATA_BUS_GPIO_PIN_7, GPIO_PIN_SET);
    HAL_GPIO_WritePin(CTRL_PORT, WE_PIN, GPIO_PIN_RESET); // 写使能信号
    HAL_Delay(1);                                         // 延时一段时间,保证写操作稳定
    HAL_GPIO_WritePin(CTRL_PORT, WE_PIN, GPIO_PIN_SET);   // 停止写操作

    // 数据从并口读出
    HAL_GPIO_WritePin(CTRL_PORT, RE_PIN, GPIO_PIN_RESET); // 读使能信号
    HAL_Delay(1);                                         // 延时一段时间,保证读操作稳定
    uint8_t data = HAL_GPIO_ReadPort(DATA_BUS_GPIO_PORT); // 读取数据
    HAL_GPIO_WritePin(CTRL_PORT, RE_PIN, GPIO_PIN_SET);   // 停止读操作
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 360;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
  {
    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = DATA_BUS_GPIO_PIN_0 | DATA_BUS_GPIO_PIN_1 | DATA_BUS_GPIO_PIN_2 | DATA_BUS_GPIO_PIN_3 | DATA_BUS_GPIO_PIN_4 | DATA_BUS_GPIO_PIN_5 | DATA_BUS_GPIO_PIN_6 | DATA_BUS_GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(DATA_BUS_GPIO_PORT, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = WE_PIN | RE_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(CTRL_PORT, &GPIO_InitStruct);
}

void Error_Handler(void)
{
  while (1)
  {
  }
}

代码说明和注释:

  • 代码开头定义了使用的引脚和控制端口。

  • main()函数中,通过调用HAL_GPIO_WritePin()HAL_GPIO_ReadPort()函数进行数据的写入和读取。

  • SystemClock_Config()函数配置了系统时钟,使用的是外部高速晶振。

  • MX_GPIO_Init()函数对引脚进行初始化,将数据总线和控制端口设置为输出模式。

  • Error_Handler()函数是错误处理函数,当出现错误时将会进入死循环。

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

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

相关文章

中电金信通过KCSP认证 云原生能力获权威认可

中电金信通过KCSP(Kubernetes Certified Service Provider)认证,正式成为CNCF(云原生计算基金会)官方认证的 Kubernetes 服务提供商。 Kubernetes是容器管理编排引擎,底层实现为容器技术,是云原…

【数据结构与算法】普里姆算法

普里姆算法 最小生成树 最小生成树,简称MST。 给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这就叫最小生成树。N 个顶点,一定有 N - 1 条边半酣全部顶点N - 1 条边都在图中举例说明…

爬虫逆向实战(五)--猿人学第三题

一、数据接口分析 主页地址:猿人学第三题 1、抓包 通过抓包可以发现数据接口是api/match/3 2、判断是否有加密参数 请求参数是否加密? 无请求头是否加密? 无响应是否加密? 无cookie是否加密? 无 二、发送请求 …

【Java】智慧工地SaaS平台源码:AI/云计算/物联网/智慧监管

智慧工地是指运用信息化手段,围绕施工过程管理,建立互联协同、智能生产、科学管理的施工项目信息化生态圈,并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析,提供过程趋势预测及专家预案,实现工程…

Redis对象和五种常用数据类型

Redisobject 对象 对象分为键对象和值对象 键对象一般是string类型 值对象可以是string,list,set,zset,hash q:redisobj的结构 typedef struct redisObject { //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层实现…

ArcGIS Pro如何制作不规则形状图例

在默认的情况下,ArcGIS Pro生成的图例是标准的点、直线和矩形的,对于湖泊等要素而言,这样的表示方式不够直观,我们可以将其优化一下,制作不规则的线和面来代替原有图例,这里为大家介绍一下制作方法&#xf…

广东灯具3D扫描抄数建模服务3D测绘出图纸三维逆向设计-CASAIM

灯具三维逆向建模是一种将实际物体转换为数字模型的过程。通过逆向工程技术,可以将现有的灯具进行3D扫描,然后利用专业的逆向设计软件将其转换为准确的三维模型。 以下是CASAIM实施灯具三维逆向建模的一般步骤图: 1. 扫描:三维扫…

基于Prometheus监控Kubernetes集群

目录 一、环境准备 1.1、主机初始化配置 1.2、部署docker环境 二、部署kubernetes集群 2.1、组件介绍 2.2、配置阿里云yum源 2.3、安装kubelet kubeadm kubectl 2.4、配置init-config.yaml 2.5、安装master节点 2.6、安装node节点 2.7、安装flannel、cni 2.8、部署测…

读高性能MySQL(第4版)笔记03_监控

1. 服务级别帮助你定义客户满意的程度和标准,以便你在解决性能、可扩展性挑战等事情与开发内部工具之间做出时间权衡 2. 服务水平指标(SLI) 2.1. 如何衡量客户是否满意 3. 服务水平目标(SLO) 3.1. 为了确保客户满意…

三维模型OSGB格式轻量化顶点压缩主要技术方法分析

三维模型OSGB格式轻量化顶点压缩主要技术方法分析 在三维模型应用中,轻量化处理是提高数据传输效率、减少渲染时间和优化用户体验的重要手段。而OSGB格式是一种常见的三维模型格式,在进行轻量化处理时,顶点压缩是一种常用的技术方法。本文将…

Redis 十大数据类型

Redis数据类型都有哪些? Redis支持丰富的数据类型,那么具体在Redis7中都有哪些数据类型呢?请看下图: 官网介绍:https://redis.io/docs/data-types/。 其中,String、Hash、List、Set、Sorted Set等类型是大…

爬虫逆向实战(十五)--阿某某营登录

一、数据接口分析 主页地址:阿某某营 1、抓包 通过抓包可以发现登录接口是Users/Login 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块可以发现有一个s加密参数 请求头是否加密? 无响应是否加密? 无cookie是…

2022年电赛C题——小车跟随行驶系统——做题记录以及经验分享

前言 自己打算将做过的电赛真题,主要包含控制组的,近几年出现的小车控制题目,自己做过的真题以及在准备电赛期间刷真题出现的问题以及经验分享给大家 这次带来的是22年电赛C题——小车跟随行驶系统,这道题目指定使用的是TI的单片…

uniapp微信小程序区分正式版,开发版,体验版

小程序代码区分是正式版,开发版,还是体验版 通常正式和开发环境需要调用不同域名接口,发布时需要手动更换 或者有些东西不想在正式版显示,只在开发版体验版中显示,也需要去手动隐藏 官方没有明确给出判断环境的方法&a…

web实现酷炫的canvas粒子动画背景

文章目录 前言一、particle-bg1. git地址:2. 安装3. 使用4. 完整demo 二、tsParticles1. 源码地址:2. 安装3. 引入4. 使用5. 几个例子5.1 ts粒子五彩纸屑烟花5.2 多粒子产卵器-用tsParticles制作5.3 ts粒子鼠标吸引力5.4 粒子烟花 源码地址完结 前言 粒…

C++--深入类和对象(上)

引言: 本篇博客将深入探究C中的类和对象。我们将从普通高校教学点开始,逐步介绍类的定义、对象的创建和使用,以及类与对象之间的关系。通过详细讲解访问控制和成员函数,我们将揭示封装的重要性以及如何实现数据的隐藏和安全性。 目…

Docker容器:docker基础概述、安装、网络及资源控制

文章目录 一.docker容器概述1.什么是容器2. docker与虚拟机的区别2.1 docker虚拟化产品有哪些及其对比2.2 Docker与虚拟机的区别 3.Docker容器的使用场景4.Docker容器的优点5.Docker 的底层运行原理6.namespace的六项隔离7.Docker核心概念 二.Docker安装 及管理1.安装 Docker1.…

图数据库_Neo4j基于docker服务版安装_Neo4j Desktop桌面版安装---Neo4j图数据库工作笔记0004

然后我们来看看如何用docker来安装Neo4j community server 首先去执行docker pull neo4j:3.5.22-community 去拉取镜像 然后执行命令就可以安装了 可以用docker ps查看一下 看看暴露了哪些端口 然后再看一下访问一下这个时候,要用IP地址了注意 然后再来看一下安装Desktop 去下…

如何在前端实现WebSocket发送和接收UDP消息(多线程模式)

目录 简介:步骤1:创建WebSocket连接步骤2:创建Web Workers步骤3:发送和接收UDP消息(多线程模式)结束语: 简介: 本文将继续介绍如何在前端应用中利用WebSocket技术发送和接收UDP消息…

数学建模的概念和学习方法(什么是数学建模)

一、初步认识数学建模 数学建模是将数学方法和技巧应用于实际问题的过程。它涉及使用数学模型来描述和分析现实世界中的现象、系统或过程,并通过数学分析和计算来预测、优化或解决问题。数学建模可以应用于各种领域,包括自然科学、工程、经济学、环境科学…