51单片机——串口通信

2023-10-29


本篇博客的最终效果是实现51单片机用串口发送Hello World,netty监听串口读到Hello World后回发给51单片机,最终51单片机回显到LCD1602显示屏。

串口通信?

其实我压根不知道串口通信是啥,我在这方面也是小白,只知道按照标准做就可以实现通信。
在这里插入图片描述
上图示是四孔串口,应该算是全双工通信的,复杂的有9针串口,提供额外的口子可以调控发送速率等。

在这里插入图片描述

开发板原理图如下:
在这里插入图片描述

串口通信的原理?

我们知道串口通信是要设置一个波特率的,比如4800bit/s, 那么这个数据发送速率如何控制呢?
定时器那篇博客里说了12MHz的晶振,一个指令周期是1us,每过一个1us,定时器+1,加到溢出了,发出一个溢出中断,然后就去发送码元数据,这样去控制码元的发送速率。

定时器初值的计算
关于串口定时器初值计算,我没搞懂,但是他有公式,套用公式即可
公式:TL1 = 256 - fosc * (SMOD + 1) / (384 * 波特率)
我的单片机是11.0592MHz,fosc=11.0592*1000000, 晶振每s振动次数
TL1= 256 - 11059200/384/4800 = 250 = 0xFA

这里用的定时器是定时器1,8位重装,8位最大255,加到溢出值256,初始值和重装值都设置为0xFA
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值

软件计算
感觉之所以出11.0592MHz的原因可能就是用这个计算误差为0,如果是12MHz的不管怎么计算都会有误差,但是12MHz的采用12分频的话一个指令周期正好1us。
在这里插入图片描述

串口的配置

在这里插入图片描述SCON配置
在这里插入图片描述REN::接收使能,为0代表51单片机的串口不接受数据,我们需要接收置位为1
TB8,RB8:不用管,只有在方式2和方式3 9位UART下才用得到
TI:发送数据中断标志位,在发完8位数据后,由内部硬件自动置位为1,我们需要软件复位为0
RI:接收数据中断标志位,在接完8位数据后,由内部硬件自动置位为1,我们需要软件复位为0
SCON=0x50

SBUF是一字节缓冲区,发送的时候直接SBUF='A’就把A发送到串口了,接收的时候char a = SBUF就可以了

PCON配置
在这里插入图片描述
B7的SMOD=1开启倍速,我们不需要倍速,8为全0就好。
PCON=0; 为了不影响其他位一般这样写PCON &= 0x7F;

IE配置
这里配的是UART中断的配置‘
在这里插入图片描述EA=1,ES=1允许UART中断,netty从串口发来的数据,是要经过这个中断处理程序的:void UART_Routine() interrupt 4

串口模式图:
在这里插入图片描述
在这里插入图片描述

定时器的配置

之前有详细说过定时器0的配置,这里就不说了,具体查看STC89C52文档第7章

	//定时器配置
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	//上面两行等价TMOD=0x20
	TL1 = 0xFA;		//设定定时初值
	TH1 = 0xFA;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断,这里不需要定时器的中断,只需要计时
	TR1 = 1;		//启动定时器1

c源代码

Delay.c


void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}


Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

LCD1602.c

#include <REGX52.H>
#include <Delay.h>
//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0


/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	Delay(1);
	LCD_EN=0;
	Delay(1);
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	Delay(1);
	LCD_EN=0;
	Delay(1);
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}

/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);
	}
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

/**
  * @brief  在LCD1602指定位置开始显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~65535
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>=0)
	{
		LCD_WriteData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriteData('-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以十六进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFF
  * @param  Length 要显示数字的长度,范围:1~4
  * @retval 无
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}

/**
  * @brief  在LCD1602指定位置开始以二进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
}

LCD1602.h

#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif

UART.h

#ifndef __UART_H__
#define __UART_H__

void UART_Init();
void UART_SendByte(unsigned char Byte);

#endif

UART.c

#include <REGX52.H>


//11.0592MHz
//fosc=11.0592*1000000, 晶振每s振动次数
// TL1 = 256 - fosc * (SMOD + 1) / (384 * 波特率)
// TL1= 256 - 11059200/384/4800 = 250 = 0xfa
void UART_Init()
{
	//PCON |= 0x80; //波特率倍速 smod=1,9600
	//TL1 = 0xF4;		//设定定时初值
	//TH1 = 0xF4;		//设定定时器重装值
	PCON=0;
	//PCON &= 0x7F;		//波特率不倍速 smod=0,4800
	SCON = 0x50;		//8位数据,可变波特率
	
	//定时器配置
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFA;		//设定定时初值
	TH1 = 0xFA;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	
	//串口中断配置
	EA=1;
	ES=1;
}
/**
  * @brief  串口发送一个字节数据
  * @param  Byte 要发送的一个字节数据
  * @retval 无
  */
void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	//到这里说明TI=1,因为硬件置为1
	//手工复位
	TI=0;
}

main.c

#include <REGX52.H>
#include "Delay.h"
#include "UART.h"
#include "LCD1602.h"
void main()
{
	unsigned char cs[] = {0x10,11,'H','e','l','l','o',' ','W','o','r','l','d',0x16};
	char i = 0;
	LCD_Init();
	
	UART_Init();			//串口初始化
	
	Delay(3000);		//延时
	
	
	while(i<14){
		UART_SendByte(cs[i]);	//串口发送一个字节
		Delay(10);		//延时
		i++;
	}
			
	while(1){}
	
}

//下面这个中断程序是接收netty的返回数据
char col = 0;
unsigned char rcs[14];
char i = 0;
void UART_Routine() interrupt 4
{
	if(RI==1)					//如果接收标志位为1,接收到了数据
	{
		rcs[col++] = SBUF;
		if(col==14){
			LCD_ShowString(1,0,rcs);
		}
		RI=0;					//接收标志位清0
	}
}

netty源代码

netty代码有点多,我就说个大概,可以去git拉。

整体流程如下:
在这里插入图片描述
协议如下图
在这里插入图片描述单片机发送的数据如下:
unsigned char cs[] = {0x10,11,‘H’,‘e’,‘l’,‘l’,‘o’,’ ',‘W’,‘o’,‘r’,‘l’,‘d’,0x16};

第一步经过FrameDecoder
在这里插入图片描述
第二步经过PacketDecoder
在这里插入图片描述第三步经过PacketHandler
在这里插入图片描述

git码云代码,代码在com.lry.netty01.rx,其他代码不用管,另外java串口通信需要一些jar包,放到jdk里面,具体的自己搜搜看

结果

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

51单片机——串口通信 的相关文章

  • Netty 与 Apache MINA

    它们都提供大致相同的功能 我应该选择哪一款来开发我的高性能 TCP 服务器 有什么优点和缺点 参考链接 阿帕奇米娜 source Netty source 虽然 MINA 和 Netty 有着相似的目标 但它们在实践中却有很大不同 您应该仔
  • 548、基于51单片机的比赛计分仿真设计(简易,LCD1602,独立按键)

    毕设帮助 开题指导 技术解答 有偿 见文末 目录 一 设计功能 二 proteus仿真 三 原理图 四 程序源码 五 资料包括 一 设计功能 二 proteus仿真 三 原理图 四 程序源码 五 资料包括
  • Java的引用类型有几种?区别是什么?

    nbsp Java的引用类型有几种 区别是什么 在开始前我有一些资料 是我根据自己从业十年经验 熬夜搞了几个通宵 精心整理了一份 Java的资料从专业入门到高级教程 工具包 点个关注 全部无偿共享给大家 在评论区回复 888 之后私信回复
  • netty源码:(24)EventExecutorChooserFactory类

    该类定义了一个内部接口EventExecutorChooser 该接口有一个方法 next EventExecutorChooserFactory类有个默认实现类 DefaultEventExecutorChooserFactory 该类有
  • AsyncHttpClient 是否知道为所有 HTTP 请求分配多少个线程

    我正在评估异步Http客户端 https github com AsyncHttpClient async http client对于大负载 1M HTTP 请求 对于每个请求 我想使用 AsyncCompletionHandler 调用回
  • 以编程方式关闭 netty

    我正在使用 netty 4 0 24 Final 我需要以编程方式启动 停止 netty 服务器 启动服务器时 线程被阻塞在 f channel closeFuture sync 请帮助提供一些如何正确执行的提示 下面是 Main 类调用的
  • Java NIO 窗口实现

    在使用 NIO 2 AIO 功能进行项目时 我查看了 旧的 NIO 选择器实现 发现在 Windows 上使用了默认的选择函数 由于内部实现不良 该函数在 Windows 上根本无法扩展 大家都知道 在 Windows 上 IOCP 是唯一
  • Netty的并发编码

    编码器的encode方法会并发执行吗 我观察到编码方法可能是由不同线程并发的 管道定义为 Channels pipeline idleHandler new AmfDecoder
  • 使用netty高速发送消息时出现OOM异常

    我用netty编写了一个客户端 以便以高速率发送消息 通过 jConsole 我看到 老一代 正在增加 最后它抛出 java lang OutOfMemoryError 超出 GC 开销限制 是否有一些方法或配置可以避免此异常 以下是我的测
  • 出站 ChannelHandler 的捕获所有异常处理

    在 Netty 中 您有入站和出站处理程序的概念 只需在管道的末尾 尾部 添加一个通道处理程序并实现一个捕获所有入站异常处理程序即可实现exceptionCaught覆盖 如果未沿途处理 沿入站管道发生的异常将沿着处理程序传播 直到遇到最后
  • 监控 Netty 事件循环队列的大小

    我们已经实现了对 Netty 事件循环队列的监控 以便了解一些 Netty 模块的问题 该显示器使用io netty util concurrent SingleThreadEventExecutor pendingTasks方法 适用于大
  • 无法加载库:[netty_tcnative_linux_arm_32、netty_tcnative_linux_arm_32_fedora、netty_tcnative_arm_32、netty_tcnative]

    我正在尝试在 raspberry pi modal 3 上使用 jar 运行 java 应用程序 我无法解决此问题 有人可以建议我如何在树莓派上进行这项工作吗 在 pom 中 我包含了 google cloud speech 依赖项 0 5
  • 如何在 Netty 客户端中使用 Socks4/5 代理处理程序 (4.1)

    我需要在Netty客户端中配置socks代理 通过socks4或5代理请求不同的站点 尝试了很多免费袜子列表中的代理 例如 www socks proxy net http sockslist net http sockslist net
  • Docker 服务在一段时间后停止通信

    我有 6 个容器在 docker swarm 中运行 Kafka Zookeeper MongoDB A B C 和接口 Interface 是公共的主要访问点 只有此容器发布端口 5683 Interface 容器在启动期间连接到 A B
  • 如何知道Netty ByteBuf中是否没有数据可读取?

    我是 Netty 新手 文件传输的问题让我困惑了好几天 我想发送image文件从客户端到服务器 下面的代码是可执行的 但只有我shutdown服务器强制我可以正常打开收到的图像文件 否则 显示 您似乎没有查看此文件的权限 检查权限并重试 所
  • 如何阻止netty在服务器套接字上监听和接受

    有没有办法告诉 netty 停止侦听和接受套接字上的新连接 但完成当前连接上任何正在进行的工作 你可以直接关闭ServerSocketChannel由创建的ChannelFactory 通常 ServerSocketChannel由返回Se
  • 如何在Netty中使用多个ServerBootstrap对象

    我正在尝试使用 Netty 4 0 24 在一个应用程序 一个主要方法 中创建多个服务器 多个 ServerBootstrap 我看到了这个问题 答案 但它留下了许多未解答的问题 Netty 4 0多端口 每个端口有不同的协议 https
  • Java 互操作——Netty + Clojure

    我正在尝试通过 clojure 使用 netty 我可以启动服务器 但是它无法初始化接受的套接字 下面分别是错误消息和代码 有谁知道什么是 或可能是错误的 我相信问题在于 Channels pipeline server handler T
  • 使用 Play WS 并获取 java.net.ConnectException:Amazon Cloudfront 上的握手超时

    在我的 Play 应用程序中 我需要从 Amazon Cloudfront 下载大量文件 使用 SSL 我在链接上随机收到以下错误 play api http HttpErrorHandlerExceptions anon 1 Execut
  • Netty中连接关闭后重新连接的最佳方法是什么

    简单场景 扩展 SimpleChannelUpstreamHandler 的较低级别的类 A 此类是发送消息和接收响应的主力 系统其他部分可以使用顶级类 B 来发送和接收消息 可以模拟同步和异步 此类创建 ClientBootstrap 设

随机推荐

  • 十行代码,我用Python做一个迷你版的美图秀秀!

    美图秀秀相信大家都不陌生 大家只要操作美图秀秀 就可以P掉图片中脸上的一些瑕疵 让人变得更加的美丽 今天小编就带领大家来借助Python和Flask来实现一个美图秀秀的网页设计 大家只需要通过网页上传需要美颜的图片 然后就可以从网页下载美颜
  • linux-shell是什么

    由于安全 复杂 繁琐等原因 用户不能直接解除内核 需要一个程序来接收用户的操作 进行处理后再传给内核 这一过程不仅做到了简化 同时也保护了内核 说白了Shell就是用来解释用户命令的 linuxshell可以看成一种脚本语言 高级语言能做到
  • 华为OD机试真题-匿名信C++实现【2023.Q1】

    题目内容 电视剧 分界线 里面有一个片段 男主为了向警察透露案件细节 且不暴露自己 于是将报刊上的字减下来 剪拼成匿名信 现在有一名举报人 希望借鉴这种手段 使用英文报刊完成举报操作 但为了增加文章的混淆度 只需满足每个单词中字母数量一致即
  • 取消springsecurity默认的登录验证

    取消springsecurity默认的登录验证 问题描述 解决方法一 方法二 问题描述 springboot 2 x 访问swagger ui html时 会自动跳转到springsecurity的login页 自定义过滤路径的拦截器无效
  • 详解FreeRTOS中的软件定时器

    软件定时器用于让某个任务定时执行 或者周期性执行 比如设定某个时间后执行某个函数 或者每隔一段时间执行某个函数 由软件定时器执行的函数称为软件定时器的回调函数 参考资料 Mastering the FreeRTOS Real Time Ke
  • 公司企业怎么做一个网站?

    怎么做一个网站对于一些实体的公司企业来说是个需要了解的问题 由于实体公司企业大部分情景下都是线下面谈业务 所以他们一开始并没有搭建自己的公司企业网站 而到了现在逐渐发展的阶段 就开始需要公司企业网站来开拓更多的客户资源或是提高公司企业的曝光
  • 这是一套基于THINKPHP6+SCUI+VUE2.6开发的CRM客户管理系统

    这是一套基于THINKPHP6 SCUI VUE2 6开发的CRM客户管理系统 演示 http v2 antsys cn 用户名admin 密码123456
  • 基于 webpack 5 实现自定义 loader

    前面的话 基于 webpack 5 创建自定义 同步 异步loader 在此基础上实现一个简易的渲染 markdown 的 loader 和 合成雪碧图的 loader 代码地址 自定义loader 准备工作 我们先创建一个 webpack
  • MacOS无法使用arduinoIDE解决方法

    1 当arduino ide版本过低时m1mac可能无法使用 出现可能是因为版本过低 Arduino 1 8 8 Mac OS X 开发板 Arduino Genuino Mega or Mega 2560 ATmega2560 Mega
  • 不能使用QtCreator debug Qt代码思路之一

    不能使用QtCreator debug Qt代码思路之一 在工程文件 pro中查找是否有 CONFIG release这样的配置 将它注释掉就可以开始debug了
  • ping www.baidu.com,显示name or service is not know

    相信许多网友都遇到过 前一天使用centos 还没有问题 第二天打开是 突然发现ping www baidu com 显示name or service is not know 大家可以打开windows任务管理器 找到服务 确保NAT正在
  • 类模板的特化

    你可以用模板实参来特化类模板 和函数模板的重载类似 通过特化类模板 你可以优化基于某种特定类型的实现 或者克服某种特定类型在实例化类模板时所出现的不足 另外 如果要特化一个类模板 你还要特化该类模板的所有成员函数 虽然也可以只特化某个成员函
  • Spring-@Value用法介绍

    Value在开发中最常使用的几个注解之一 通常用来获取配置文件中的属性 不过除了从配置文件中获取值 Value还支持使用默认值 表达式等方式为变量设置值 本文就针对 Value的使用进行分享 Value用法 Value中直接设置值 顾名思义
  • 【目标检测-YOLO】YOLOv5-v6.0-yolov5s网络架构详解(第一篇)

    1 准备工作 趁热打铁 上节分析了 v5 0 的 yolov5s 模型架构 本节顺便把 v6 0的图也画下 官方代码中贴心的给提供了 onnx 文件 如下图 但是 当我打开 onnx 的时候 我麻了 所以 还是需要自己生成下 onnx 文件
  • LIVE555研究之三:LIVE555基础

    LIVE555基础 LIVE555是为流媒体提供解决方案的跨平台C 开源项目 从今天起我们将正式开始深入LIVE555代码 一 各库简要介绍 LIVE555下包含LiveMedia UsageEnvironment BasicUsageEn
  • HTML——前端实时可视化开发工具

    前端实时可视化开发工具 liveStyle liveReload Broswer Sync 一 liveStyle 如图 liveStyle支持三种文件 需要安装两个插件 浏览器的插件 sublime编辑器中的livestyle插件 浏览器
  • 给定一个二叉树, 找到该树中两个指定节点p和q(数值唯一)的最近公共祖先

    递归思想 判断p和q是否分别根结点的左右两侧 如果在左右两侧那么直接返回根结点即可 不失一般性 假设p和q分别均在根结点的左侧 那么按照分治的思想 此时继续往左子树找即可 问题规模已经缩小 那么依旧还是上面的操作划分 故可以采用递归的思想
  • 力扣第48天--- 第739题、第496题

    力扣第48天 第739题 第496题 文章目录 一 第739题 每日温度 二 第496题 下一个更大元素 I 一 第739题 每日温度 单调栈里放的是下标 适用场景 对于数组中某一元素 寻找右边 左边第一个大于或者小于这个元素的位置 单调栈
  • flutter - 点击事件(二) - 给图片增加点击UI效果

    上一篇 介绍了如何便利的构造一个自己的点击控件 flutter 中 如果给图片外面套 InkWell 你会发现点击的逻辑生效了 但是 UI 上没反应 备注 图片来源 违反版权请联系我 删除 代码如下 import package flutt
  • 51单片机——串口通信

    51单片机 串口通信 串口通信 串口通信的原理 串口的配置 定时器的配置 c源代码 netty源代码 结果 本篇博客的最终效果是实现51单片机用串口发送Hello World netty监听串口读到Hello World后回发给51单片机