当前位置: 首页 > news >正文

四、GPIO中断实现按键功能

4.1 GPIO简介

        输入输出(I/O)是一个非常重要的概念。I/O泛指所有类型的输入输出端口,包括单向的端口如逻辑门电路的输入输出管脚和双向的GPIO端口。而GPIO(General-Purpose Input/Output)则是一个常见的术语,指的是通用输入输出接口。

        下面有请DeepSeek发言

LPC1110系列Cortex-M0微控制器的GPIO口的结构特点:

1端口可由软件配置为输入输出
2引脚默认为输入(所以点灯时需要改下方向)
3端口引脚的读写操作可屏蔽
4每个单独引脚可被用作外部中断输入引脚
5每个GPIO中断可配置为 高、低电平、下降、上升沿或双边沿触发
6可对单独端口的中断级别进行配置

4.2 GPIO口的寄存器

        所有GPIO寄存器都为32位 

        GPIO端口基址为

端口0  0x5000 0000
端口1  0x5001 0000

端口2

 0x5002 0000
端口3 0x5003 0000

4.2.1 数据寄存器  GPIOnDATA

        用于读取输入引脚的状态数据或者配置输出引脚的输出状态

        对应端口位置后四位范围为 0000 ~ 3FFC

11:0PIOn_0 ~ PIOn_11的输入/输出数据
31:12保留

4.2.2 方向寄存器 GPIOnDIR

11:0PIOn_0 ~ PIOn_11的输入/输出方向   0为输入, 1为输出  位数0-11与0-11引脚一一对应
31:12保留

4.2.3 中断触发寄存器 GPIOnIS

        相较于基地址偏移量0x8004 即0x500n 8004

11:0PIOn_x    0为边沿触发,1为电平触发
31:12保留

4.2.4 中断双边沿触发寄存器 GPIOnIBE

        相较于基地址偏移量0x8008 即0x500n 8008

11:0

0为通过4.2.5中寄存器GPIOnIEV控制PIOn_x的中断

1为通过PIOn_x上双边沿触发中断

31:12保留

4.2.5 中断事件寄存器 GPIOnIEV

        相较于基地址偏移量0x800C 即0x500n 800C

11:0

0为上升沿或者高电平触发中断

1为下降沿或者低电平触发中断

具体边沿还是电平 看4.2.3中GPIOnIS的设置

31:12保留

4.2.6 中断屏蔽寄存器 GPIOnIE

        相较于基地址偏移量0x8010 即0x500n 8010

11:0

0为中断被屏蔽

1为中断不被屏蔽

31:12保留

4.2.7 原始中断状态寄存器 GPIOnIRS

        相较于基地址偏移量0x8014 即0x500n 8014

        屏蔽之前的中断状态

11:0

0为无中断

1为满足中断要求

31:12保留

4.2.8 屏蔽中断状态寄存器 GPIOnMIS

        相较于基地址偏移量0x8018 即0x500n 8018

        考虑了屏蔽操作之后是否有中断

11:0

0为无中断,或者中断被屏蔽

1为满足中断要求

31:12保留

4.2.9 中断清除寄存器 GPIOnIC

        相较于基地址偏移量0x801C 即0x500n 801C

11:0

0无操作

1为清除PIOn_x上的边沿检测逻辑

31:12保留

4.3 LPC上的GPIO按键

        按键按下引脚低电平,不按是高电平

4.4 按键控制LED闪烁频率

任务:

1. BUTTON(PIO3_5)按键按下,闪烁频率为1Hz,再次按下,恢复闪烁频率为0.5Hz;

2. WEAKUP(PIO1_4)按键按下,闪烁频率为2Hz,再次按下,恢复闪烁频率为0.5Hz;

3. 适当考虑按键防抖功能。            

思路:

        对于闪烁频率的修改,首先考虑用什么控制LED闪烁,结合上章可以用SysTick,然后按键按下改变SysTick周期即可

        对于按键防抖,由于按键固有的物理结构,按下后弹簧一上一下会影响中断,需要用延时函数过滤抖动。

抖动时间大概10ms这样, 我们可以用个延时函数过滤掉这个抖动过程,延时20ms就足够了

代码:

利用之前写过的函数即可,复制个新工程,然后main文件里代码如下

#include <LPC11xx.h>
#include "LED.h"//延时ms函数 // 太粗糙了,而且要根据机器指令与时钟周期关系调整,也就防抖延时用一下
__inline void delay_ms(uint32_t a)    //约1ms延时函数 
{                           uint32_t i;while( a -- != 0){for(i = 0; i<5500; i++);}             
}int flag1 = 0, flag2 = 0; // 判断botton 和 wakeup 按键上一次状态
int main()
{LED_Init(); // PIO1_4LPC_IOCON->PIO1_4 &= ~(0x1F);  // 清除之前的配置LPC_IOCON->PIO1_4 |= 0x00;     // 配置为GPIO功能LPC_GPIO1->DIR &= ~(1UL << 4);// 设置GPIO方向为输入LPC_GPIO1->IS &= ~(0x1 << 4); // 清除第 4 位,设置为边沿触发LPC_GPIO1->IBE &= ~(0x1 << 4); // 清除第 4 位,设置为单边沿触发LPC_GPIO1->IEV &= ~(0x1 << 4); // 清除第 4 位,设置为低电平触发LPC_GPIO1 -> IE |= (0x1<<4); // 使能端口中断LPC_IOCON->PIO1_4 |= (1UL << 5);          // 使能滞后模式LPC_GPIO1->IC |= (1UL << 4); // 清除中断标志位NVIC_EnableIRQ(EINT1_IRQn); // 使能GPIO1中断// PIO3_5LPC_IOCON->PIO3_5 &= ~(0x1F);   // 清除之前的配置LPC_IOCON->PIO3_5 |= 0x00;      // 配置为GPIO功能LPC_GPIO3->DIR &= ~(1UL << 5);// 设置GPIO方向为输入LPC_GPIO3->IS &= ~(0x1 << 5); // 清除第 5 位,设置为边沿触发LPC_GPIO3->IBE &= ~(0x1 << 5); // 清除第 5 位,设置为单边沿触发LPC_GPIO3->IEV &= ~(0x1 << 5); // 清除第 5 位,设置为低电平触发LPC_GPIO3 -> IE |= (0x1<<5); // 使能端口中断LPC_IOCON->PIO3_5 |= (1UL << 5);  // 使能滞后模式LPC_GPIO3->IC |= (1UL << 5); //清除中断标志NVIC_EnableIRQ(EINT3_IRQn);SysTick_Config(SystemCoreClock/100); // 0.01s进一次中断 1s翻转一次 0.5 Hzwhile(1){}
}void SysTick_Handler() /// 系统节拍定时器中断函数
{static unsigned long ticks;if(ticks++ >= 99){ticks = 0;LED_Toggle();}
}// GPIO3_5的中断服务函数,处理BUTTON按键按下事件
void PIOINT3_IRQHandler(void)
{if((LPC_GPIO3->MIS & (1UL << 5)) == (1UL << 5))// 检查是否是PIO3_5的中断{ delay_ms(20); // 消抖while((LPC_GPIO3->DATA & (1UL << 5)) == 0);delay_ms(20);if(flag1)SysTick_Config(SystemCoreClock/100); // 0.01s进一次中断 1s翻转一次 0.5 Hzelse SysTick_Config(SystemCoreClock/200); // 0.005s进一次中断 0.5s翻转一次 1 Hzflag1 = !flag1;LPC_GPIO3->IC |= (1UL << 5);          // 清除中断标志}
}
// GPIO1_4的中断服务函数,处理WAKEUP按键按下事件
void PIOINT1_IRQHandler(void)
{if((LPC_GPIO1->MIS & (1UL << 4)) == (1UL << 4)) // 检查是否是PIO1_4的中断{delay_ms(20);while((LPC_GPIO1->DATA & (1UL << 4)) == 0);delay_ms(20);if(flag2)SysTick_Config(SystemCoreClock/100); // 0.01s进一次中断 1s翻转一次 0.5 Hzelse SysTick_Config(SystemCoreClock/400); // 0.0025s进一次中断 0.2s翻转一次 2 Hz flag2 = !flag2;LPC_GPIO1->IC |= (1UL << 4);           // 清除中断标志}
}

模块化一下,新建Button.c Button.h文件,便于之后移植工程

main.c

#include <LPC11xx.h>
#include "LED.h"
#include "Button.h"int main()
{LED_Init(); WAKEUP_Init();Button_Init();while(1){}
}void SysTick_Handler() /// 系统节拍定时器中断函数
{static unsigned long ticks;if(ticks++ >= 99){ticks = 0;LED_Toggle();}
}

Button.c

#include "Button.h"
int flag1 = 0, flag2 = 0; // 判断botton 和 wakeup 按键上一次状态//延时ms函数 // 太粗糙了,而且要根据机器指令与时钟周期关系调整,也就防抖延时用一下
__inline void delay_ms(uint32_t a)    //约1ms延时函数 
{                           uint32_t i;while( a -- != 0){for(i = 0; i<5500; i++);}             
}void WAKEUP_Init(void)
{LPC_SYSCON -> SYSAHBCLKCTRL |= (1UL << 6) | (1UL << 16); // 使能GPIO时钟和IO时钟// PIO1_4LPC_IOCON->PIO1_4 &= ~(0x1F);  // 清除之前的配置LPC_IOCON->PIO1_4 |= 0x00;     // 配置为GPIO功能LPC_GPIO1->DIR &= ~(1UL << 4);// 设置GPIO方向为输入LPC_GPIO1->IS &= ~(0x1 << 4); // 清除第 4 位,设置为边沿触发LPC_GPIO1->IBE &= ~(0x1 << 4); // 清除第 4 位,设置为单边沿触发LPC_GPIO1->IEV &= ~(0x1 << 4); // 清除第 4 位,设置为低电平触发LPC_GPIO1 -> IE |= (0x1<<4); // 使能端口中断LPC_IOCON->PIO1_4 |= (1UL << 5);          // 使能滞后模式LPC_GPIO1->IC |= (1UL << 4); // 清除中断标志位NVIC_EnableIRQ(EINT1_IRQn); // 使能GPIO1中断
}void Button_Init(void)
{LPC_SYSCON -> SYSAHBCLKCTRL |= (1UL << 6) | (1UL << 16); // 使能GPIO时钟和IO时钟// PIO3_5LPC_IOCON->PIO3_5 &= ~(0x1F);   // 清除之前的配置LPC_IOCON->PIO3_5 |= 0x00;      // 配置为GPIO功能LPC_GPIO3->DIR &= ~(1UL << 5);// 设置GPIO方向为输入LPC_GPIO3->IS &= ~(0x1 << 5); // 清除第 5 位,设置为边沿触发LPC_GPIO3->IBE &= ~(0x1 << 5); // 清除第 5 位,设置为单边沿触发LPC_GPIO3->IEV &= ~(0x1 << 5); // 清除第 5 位,设置为低电平触发LPC_GPIO3 -> IE |= (0x1<<5); // 使能端口中断LPC_IOCON->PIO3_5 |= (1UL << 5);  // 使能滞后模式LPC_GPIO3->IC |= (1UL << 5); //清除中断标志NVIC_EnableIRQ(EINT3_IRQn);
}// GPIO3_5的中断服务函数,处理BUTTON按键按下事件
void PIOINT3_IRQHandler(void)
{if((LPC_GPIO3->MIS & (1UL << 5)) == (1UL << 5))// 检查是否是PIO3_5的中断{ delay_ms(20); // 消抖while((LPC_GPIO3->DATA & (1UL << 5)) == 0);delay_ms(20);if(flag1)SysTick_Config(SystemCoreClock/100); // 0.01s进一次中断 1s翻转一次 0.5 Hzelse SysTick_Config(SystemCoreClock/200); // 0.005s进一次中断 0.5s翻转一次 1 Hzflag1 = !flag1;LPC_GPIO3->IC |= (1UL << 5);          // 清除中断标志}
}
// GPIO1_4的中断服务函数,处理WAKEUP按键按下事件
void PIOINT1_IRQHandler(void)
{if((LPC_GPIO1->MIS & (1UL << 4)) == (1UL << 4)) // 检查是否是PIO1_4的中断{delay_ms(20);while((LPC_GPIO1->DATA & (1UL << 4)) == 0);delay_ms(20);if(flag2)SysTick_Config(SystemCoreClock/100); // 0.01s进一次中断 1s翻转一次 0.5 Hzelse SysTick_Config(SystemCoreClock/400); // 0.0025s进一次中断 0.2s翻转一次 2 Hz flag2 = !flag2;LPC_GPIO1->IC |= (1UL << 4);           // 清除中断标志}
}

Button.h

#ifndef _BUTTON_H_
#define _BUTTON_H_#include <LPC11xx.h>void WAKEUP_Init(void);
void Button_Init(void);#endif

相关文章:

四、GPIO中断实现按键功能

4.1 GPIO简介 输入输出&#xff08;I/O&#xff09;是一个非常重要的概念。I/O泛指所有类型的输入输出端口&#xff0c;包括单向的端口如逻辑门电路的输入输出管脚和双向的GPIO端口。而GPIO&#xff08;General-Purpose Input/Output&#xff09;则是一个常见的术语&#xff0c…...

Linux安装zookeeper

1, 下载 Apache ZooKeeperhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apa…...

【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(二)

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;贪心算法篇–CSDN博客 文章目录 前言例题1.买卖股票的最佳时机2.买卖股票的最佳时机23.k次取…...

007 JSON Web Token

文章目录 https://doc.hutool.cn/pages/jwt/#jwt%E4%BB%8B%E7%BB%8D JWT是一种用于双方之间安全传输信息的简洁的、URL安全的令牌标准。这个标准由互联网工程任务组(IETF)发表&#xff0c;定义了一种紧凑且自包含的方式&#xff0c;用于在各方之间作为JSON对象安全地传输信息。…...

Windsurf cursor vscode+cline 与Python快速开发指南

Windsurf简介 Windsurf是由Codeium推出的全球首个基于AI Flow范式的智能IDE&#xff0c;它通过强大的AI助手功能&#xff0c;显著提升开发效率。Windsurf集成了先进的代码补全、智能重构、代码生成等功能&#xff0c;特别适合Python开发者使用。 Python环境配置 1. Conda安装…...

将markdown文件和LaTex公式转为word

通义千问等大模型生成的回答多数是markdown类型的&#xff0c;需要将他们转为Word文件 一 pypandoc 介绍 1. 项目介绍 pypandoc 是一个用于 pandoc 的轻量级 Python 包装器。pandoc 是一个通用的文档转换工具&#xff0c;支持多种格式的文档转换&#xff0c;如 Markdown、HTM…...

grpc 和 http 的区别---二进制vsJSON编码

gRPC 和 HTTP 是两种广泛使用的通信协议&#xff0c;各自适用于不同的场景。以下是它们的详细对比与优势分析&#xff1a; 一、核心特性对比 特性gRPCHTTP协议基础基于 HTTP/2基于 HTTP/1.1 或 HTTP/2数据格式默认使用 Protobuf&#xff08;二进制&#xff09;通常使用 JSON/…...

C#面向对象(封装)

1.什么是封装? C# 封装 封装 被定义为“把一个或多个项目封闭在一个物理的或者逻辑的包中”。 在面向对象程序设计方法论中&#xff0c;封装是为了防止对实现细节的访问。 抽象和封装是面向对象程序设计的相关特性。 抽象允许相关信息可视化&#xff0c;封装则使开发者实现所…...

kamailio-kamctl monitor解释

这段输出是 Kamailio 服务器的运行时信息和统计数据的摘要。以下是对每个部分的详细解释&#xff1a; 1. Kamailio Runtime Details cycle #: 3: 表示 Kamailio 的主循环已经运行了 3 个周期。Kamailio 是一个事件驱动的服务器&#xff0c;主循环用于处理事件和请求。if const…...

39. I2C实验

一、IIC协议详解 1、ALPHA开发板上有个AP3216C&#xff0c;这是一个IIC接口的器件&#xff0c;这是一个环境光传感器。AP3216C连接到了I2C1上: I2C1_SCL: 使用的是UART4_TXD这个IO&#xff0c;复用位ALT2 I2C1_SDA: 使用的是UART4_RXD这个IO。复用为ALT2 2、I2C分为SCL和SDA&…...

GPIO配置通用输出,推挽输出,开漏输出的作用,以及输出上下拉起到的作用

通用输出说明&#xff1a; ①输出原理&#xff1a; 对输出数据寄存器的对应位写0 或 1&#xff0c;就可以控制对应编号的IO口输出低/高电平 ②输出类型 推挽输出&#xff1a;IO口可以输出高电平&#xff0c;也可以输出低电平 开漏输出&#xff1a;IO口只能输出低电平 所以…...

Spring AOP 入门教程:基础概念与实现

目录 第一章&#xff1a;AOP概念的引入 第二章&#xff1a;AOP相关的概念 1. AOP概述 2. AOP的优势 3. AOP的底层原理 第三章&#xff1a;Spring的AOP技术 - 配置文件方式 1. AOP相关的术语 2. AOP配置文件方式入门 3. 切入点的表达式 4. AOP的通知类型 第四章&#x…...

DeepSeek 核心技术全景解析

DeepSeek 核心技术全景解析&#xff1a;突破性创新背后的设计哲学 DeepSeek的创新不仅仅是对AI基础架构的改进&#xff0c;更是一场范式革命。本文将深入剖析其核心技术&#xff0c;探讨 如何突破 Transformer 计算瓶颈、如何在 MoE&#xff08;Mixture of Experts&#xff09…...

90,【6】攻防世界 WEB Web_php_unserialize

进入靶场 进入靶场 <?php // 定义一个名为 Demo 的类 class Demo { // 定义一个私有属性 $file&#xff0c;默认值为 index.phpprivate $file index.php;// 构造函数&#xff0c;当创建类的实例时会自动调用// 接收一个参数 $file&#xff0c;用于初始化对象的 $file 属…...

实现网站内容快速被搜索引擎收录的方法

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/6.html 实现网站内容快速被搜索引擎收录&#xff0c;是网站运营和推广的重要目标之一。以下是一些有效的方法&#xff0c;可以帮助网站内容更快地被搜索引擎发现和收录&#xff1a; 一、确…...

WSL2中安装的ubuntu搭建tftp服务器uboot通过tftp下载

Windows中安装wsl2&#xff0c;wsl2里安装ubuntu。 1. Wsl启动后 1&#xff09;Windows下ip ipconfig 以太网适配器 vEthernet (WSL (Hyper-V firewall)): 连接特定的 DNS 后缀 . . . . . . . : IPv4 地址 . . . . . . . . . . . . : 172.19.32.1 子网掩码 . . . . . . . .…...

机器学习优化算法:从梯度下降到Adam及其变种

机器学习优化算法&#xff1a;从梯度下降到Adam及其变种 引言 最近deepseek的爆火已然说明&#xff0c;在机器学习领域&#xff0c;优化算法是模型训练的核心驱动力。无论是简单的线性回归还是复杂的深度神经网络&#xff0c;优化算法的选择直接影响模型的收敛速度、泛化性能…...

[SAP ABAP] 静态断点的使用

在 ABAP 编程环境中&#xff0c;静态断点通过关键字BREAK-POINT实现&#xff0c;当程序执行到这一语句时&#xff0c;会触发调试器中断程序的运行&#xff0c;允许开发人员检查当前状态并逐步跟踪后续代码逻辑 通常情况下&#xff0c;在代码的关键位置插入静态断点可以帮助开发…...

129.求根节点到叶节点数字之和(遍历思想)

Problem: 129.求根节点到叶节点数字之和 文章目录 题目描述思路复杂度Code 题目描述 思路 遍历思想(利用二叉树的先序遍历) 直接利用二叉树的先序遍历&#xff0c;将遍历过程中的节点值先利用字符串拼接起来遇到根节点时再转为数字并累加起来&#xff0c;在归的过程中&#xf…...

NCCL、HCCL、通信、优化

文章目录 从硬件PCIE、NVLINK、RDMA原理到通信NCCL、MPI原理&#xff01;通信实现方式&#xff1a;机器内通信、机器间通信通信实现方式&#xff1a;通讯协调通信实现方式&#xff1a;机器内通信&#xff1a;PCIe通信实现方式&#xff1a;机器内通信&#xff1a;NVLink通信实现…...

unity学习21:Application类与文件存储的位置

目录 1 unity是一个跨平台的引擎 1.1 使用 Application类&#xff0c;去读写文件 1.2 路径特点 1.2.1 相对位置/相对路径&#xff1a; 1.2.2 固定位置/绝对路径&#xff1a; 1.3 测试方法&#xff0c;仍然挂一个C#脚本在gb上 2 游戏数据文件夹路径&#xff08;只读&…...

17 一个高并发的系统架构如何设计

高并发系统的理解 第一:我们设计高并发系统的前提是该系统要高可用&#xff0c;起码整体上的高可用。 第二:高并发系统需要面对很大的流量冲击&#xff0c;包括瞬时的流量和黑客攻击等 第三:高并发系统常见的需要考虑的问题&#xff0c;如内存不足的问题&#xff0c;服务抖动的…...

Spring Boot 实例解析:配置文件

SpringBoot 的热部署&#xff1a; Spring 为开发者提供了一个名为 spring-boot-devtools 的模块来使用 SpringBoot 应用支持热部署&#xff0c;提高开发者的效率&#xff0c;无需手动重启 SpringBoot 应用引入依赖&#xff1a; <dependency> <groupId>org.springfr…...

pytorch图神经网络处理图结构数据

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 图神经网络&#xff08;Graph Neural Networks&#xff0c;GNNs&#xff09;是一类能够处理图结构数据的深度学习模型。图结构数据由节点&#xff08;vertices&#xff09;和边&#xff08;edges&#xff09;组成&a…...

计算机网络一点事(23)

传输层 端口作用&#xff1a;标识主机特定进程&#xff0c;TCP&#xff0c;UDP协议 端口号分类&#xff1a;服务器&#xff1a;0-1023&#xff0c;熟知 1024-49151 登记 客户端&#xff1a;49152-65535 功能&#xff1a;实现端到端&#xff0c;进程到进程的通信&#xff0c…...

(9)下:学习与验证 linux 里的 epoll 对象里的 EPOLLIN、 EPOLLHUP 与 EPOLLRDHUP 的不同。小例子的实验

&#xff08;4&#xff09;本实验代码的蓝本&#xff0c;是伊圣雨老师里的课本里的代码&#xff0c;略加改动而来的。 以下是 服务器端的代码&#xff1a; 每当收到客户端的报文时&#xff0c;就测试一下对应的 epoll 事件里的事件标志&#xff0c;不读取报文内容&#xff0c;…...

DeepSeek-R1模型1.5b、7b、8b、14b、32b、70b和671b有啥区别?

deepseek-r1的1.5b、7b、8b、14b、32b、70b和671b有啥区别&#xff1f;码笔记mabiji.com分享&#xff1a;1.5B、7B、8B、14B、32B、70B是蒸馏后的小模型&#xff0c;671B是基础大模型&#xff0c;它们的区别主要体现在参数规模、模型容量、性能表现、准确性、训练成本、推理成本…...

一、html笔记

(一)前端概述 1、定义 前端是Web应用程序的前台部分,运行在PC端、移动端等浏览器上,展现给用户浏览的网页。通过HTML、CSS、JavaScript等技术实现,是用户能够直接看到和操作的界面部分。上网就是下载html文档,浏览器是一个解释器,运行从服务器下载的html文件,解析html、…...

AI大模型开发原理篇-2:语言模型雏形之词袋模型

基本概念 词袋模型&#xff08;Bag of Words&#xff0c;简称 BOW&#xff09;是自然语言处理和信息检索等领域中一种简单而常用的文本表示方法&#xff0c;它将文本看作是一组单词的集合&#xff0c;并忽略文本中的语法、词序等信息&#xff0c;仅关注每个词的出现频率。 文本…...

基于微信小程序的实习记录系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...