【51单片机】七段数码管显示实验+详细讲解


前言

继上次仿真实验——【51单片机】矩阵键盘线反转法实验仿真之后,尽管也对点阵LED进行了学习,但是,点阵LED的显示效果不佳(仿真时的色彩、明亮程度等),加上大多数时候我们在计算器上看到的是七段数码管,所以在学习了学校课程之后,我也进行了尝试。这次主要是记录七段数码管的使用方法,在此之后,我考虑把键盘扫描(线反转法)、七段数码管、80C51结合起来,把整个计算器的功能完善,也算是完成一个小项目。

因为我认为光学理论只是很容易忘记,且容易磨灭兴趣,所以在学习过程中以做一个计算器为目标,循序渐进地学习,缺什么知识就补充什么知识,就像前几次所作的一样:
【51单片机】矩阵键盘线反转法实验仿真
【51单片机】点阵LED的显示实验
【51单片机】矩阵键盘逐行扫描法仿真实验+超详细Proteus仿真和Keil操作步骤
下面是这次七段数码管的学习记录。

一、兵马未动,粮草先行——认识七段数码管

1、关于显示器

我们常见的显示器一般分为LED、LCD和CRT,当然除此之外还有其他种类的显示器。其中:

  • LED是发光二极管,核心原理是半导体的电光转化,在电光转化过程中发热很少,相对白炽灯更节能,目前常用作照明工具;
  • LCD是液晶显示器,核心原理是液晶(介于液体和晶体的一种物质)的各向异性使特定区域透光、部分区域不透光来呈现画面;
  • CRT是阴极射线管,常用在示波器和老式电视机上,核心原理是控制电子束的偏转角来控制电子打在荧光屏上的不同位置,使之出现我们想要的图案。

2、七段数码管

今天要说的就是LED中的一员——七段数码管。七段数码管也叫七段LED显示器,是由数个LED组成的阵列,并封装在一个标准的外壳内。
在这里插入图片描述

如图,七段数码管通常有七段,但现在为了表示小数,加入了小数点,所以其实变成了名字叫七段数码管的八段数码管。图上a、b、c、d、e、f、g、dp则是每段的名字。cs管脚类似于片选信号。
我们只需要点亮特定的管脚就能形成一个数字或者字母。

3、七段数码管的结构

在这里插入图片描述
如图是七段数码管的内部结构,将图中的二极管按特定阵列排布就得到了常见的数码管。

  • 共阴极:顾名思义,这是将二极管的阴极连接到同一条导线上,只要某路地阳极变为高电平,该路LED就会被点亮。
  • 共阳极:二极管地阳极连接到一条到线上并连接电源。当某路阴极变为低电平,该路地LED就会亮起。

4、数码管显示方法

七段数码管显示也有两种方式,分别是静态显示和动态显示

  • 静态显示:在静态显示系统中,每一位显示器都应该有各自地锁存器、译码器和驱动器锁存器,如果软件译码,译码器也可以省略。锁存器用来所存待显示数字的BCD码,所以每次显示输出后都能保持不变。但是占用的位数很多,每一位需要8根数据线。
  • 动态显示:在动态显示系统中,微处理器要定时地向各个显示器进行扫描,只要扫描速率足够快,由于视觉暂留现象就会给人以恒定显示的表现。动态显示可以减少硬件的使用,但是需要微处理器一直为它工作。

二、数码管显示程序

1、静态显示

静态显示用到的元件有:74LS273(锁存器)×4、80C51、7SEG-MPX1-CA(七段数码管)×4、RESPACK-8(电阻)、GROUND、POWER和BUTTON
连接线路如图:
在这里插入图片描述

静态显示的代码如下:

#include <reg51.h>

unsigned int d[4]={0xA4,0xC0,0xA4,0xf9};//共阳极的数码管显示的数字,一次是2、0、2、1
unsigned int cs[4]={0x0E,0x0D,0x0B,0x07};//片选,低电平时,锁存器打开,可以写入数据。高电平时锁存
void main(void)
 { 
   int i;
	EA=1;//开中断
	EX0=1;//开外部中断0
	INT0=1;//下降沿触发INT0中断
	for(i=0;i<4;i++){
		P2=cs[i];//打开一个锁存器
		P0=d[i];//向该锁存器写入数据
	}
	P2=0xff;//所有锁存器锁存CLK置高电平
 }
 
 void int0() interrupt 0{//终端服务程序
	P2=cs[0];
	 P0=0x8E;
}

效果

在这里插入图片描述

2.动态显示

动态显示用到的元件有:8051、7SEG-MPX4-CA(4位七段数码管)、RESPACK-8(电阻)、GROUND、POWER和BUTTON
接线如图:
在这里插入图片描述

动态显示的代码如下:

#include <reg51.h>

unsigned int d[4]={0x5B,0x3f,0x5B,0x06};//共阴极的数码管,输出为静态时的反码,由与所用的七段数码管内部不同所致。
unsigned int cs[4]={0x0E,0x0D,0x0B,0x07};//与静态不同,4位7段数码管的片选信号不由锁存器决定,自带的片选管脚功能为高电平选中
void delay(int n){//延时程序
	int i;
	int j;
	for(i=0;i<n;i++)
		for(j=0;j<120;j++);
}
void main(void)
 { 
	int i;
	EA=1;
	EX0=1;
	INT0=1;
	while(1){//因为是动态扫描,所以必须不停地扫描
		for(i=0;i<4;i++){
			P2=cs[i];
			P0=d[i];
			delay(10);
		}
	}
 }
 void int0() interrupt 0{
	P2=cs[0];
	 P0=0x71;
}

效果

在这里插入图片描述


总结

以上就是两种类型的七段数码管(共阴极和共阳极)的两种不同的显示方式(静态和动态)。这里对七段数码管的学习,我会用到计算器的制作中,加以巩固。也希望和小伙伴们一起学习,有时间我也会多多分享学习的知识,记录学习过程。

<think>好的,我现在需要解决用户在TensorFlow或Keras中使用LSTM时遇到的符号张量转换为numpy数组的错误。用户提到的错误信息是“NotImplementedError: Cannot convert a symbolic Tensor (lstm_2/strided_slice:0) to a numpy array”,这通常发生在尝试将符号张量传递给需要numpy数组的操作时。 首先,我应该回顾用户提供的引用内容。引用[1]到[4]都提到了这个错误,其中原因可能包括numpy版本过高、TensorFlow版本问题,或者在代码中错误地将TensorFlow张量与numpy数组混合使用。例如,引用[4]指出numpy版本过高可能导致此问题,降级到1.19.x或更低版本可以解决。而引用[2]和[3]则提到在TensorFlow 2.x中,某些操作可能不兼容,需要检查代码中是否有将符号张量转换为numpy数组的地方。 接下来,我需要逐步分析可能的原因和解决方法。首先检查numpy的版本是否过高。如果用户使用的是numpy 1.20或更高版本,确实可能出现兼容性问题,尤其是在TensorFlow 1.x的环境中。解决方案是降级numpy,比如安装1.19.5版本。同时,用户应确保TensorFlow和Keras的版本兼容。例如,在TensorFlow 2.x中,可能需要调整代码以避免直接操作符号张量。 另一个可能的原因是在模型构建或自定义层中,错误地在TensorFlow计算图中使用了numpy函数。例如,在Lambda层或自定义损失函数中调用np.array或np函数,这会导致符号张量被转换为numpy数组,从而引发错误。需要检查所有自定义代码,确保仅使用TensorFlow操作,如tf.shape、tf.reduce_mean等。 此外,数据预处理阶段也可能存在问题。如果在数据生成器或输入管道中将TensorFlow张量转换为numpy数组,也可能触发此错误。需要确保数据输入流程使用tf.data.Dataset等TensorFlow原生方法,避免在预处理步骤中混合使用numpy和TensorFlow操作。 最后,如果用户使用的是TensorFlow 1.x,可能需要启用eager execution来避免符号张量的问题。不过,在TensorFlow 2.x中,默认启用eager execution,但若代码是为TF1.x设计的,可能需要调整代码结构或使用兼容性模块。 总结可能的解决步骤:检查并降级numpy版本,确保TensorFlow和Keras版本兼容,检查自定义代码中的numpy使用,改用TensorFlow操作,检查数据输入流程,避免混合使用两种库的函数,必要时启用eager execution或升级到TensorFlow 2.x。</think>### 解决LSTM中符号张量转换为numpy数组的错误 在TensorFlow或Keras中使用LSTM时,若出现`NotImplementedError: Cannot convert a symbolic Tensor (lstm/strided_slice:0) to a numpy array`错误,通常是因为代码中尝试将符号张量(TensorFlow计算图的一部分)传递给需要numpy数组的操作。以下是逐步解决方法: --- #### **1. 检查numpy版本** **原因**:高版本numpy(如1.20+)与TensorFlow 1.x或早期2.x版本存在兼容性问题[^4]。 **解决**: - 降级numpy至兼容版本(如1.19.5): ```bash pip install numpy==1.19.5 ``` - 确认TensorFlow和Keras版本是否匹配(例如TensorFlow 1.14 + Keras 2.2.4)[^3]。 --- #### **2. 避免混合TensorFlow与numpy操作** **原因**:在模型构建阶段(如Lambda层、自定义损失函数)错误地使用numpy函数处理张量。 **示例错误代码**: ```python # 错误:在Lambda层中使用np.reshape x = Lambda(lambda x: np.reshape(x, (-1, 10)))(input) ``` **解决**:改用TensorFlow原生函数(如`tf.reshape`)[^2]: ```python x = Lambda(lambda x: tf.reshape(x, (-1, 10)))(input) ``` --- #### **3. 检查数据输入流程** **原因**:在数据生成器中将张量转换为numpy数组。 **解决**: - 使用`tf.data.Dataset`替代自定义生成器: ```python dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32) ``` - 确保预处理函数仅使用`tf.*`操作。 --- #### **4. 升级TensorFlow 2.x并启用Eager Execution** **原因**:TensorFlow 1.x默认使用静态计算图,符号张量无法直接转换为numpy数组。 **解决**: - 升级到TensorFlow 2.x(默认启用Eager Execution): ```bash pip install --upgrade tensorflow ``` - 若需兼容旧代码,在TensorFlow 2.x中禁用计算图模式: ```python tf.config.run_functions_eagerly(True) ``` --- #### **5. 验证代码中的张量操作** **关键检查点**: - 自定义层中的`call()`方法是否仅使用TensorFlow运算。 - 损失函数或指标中避免使用`.numpy()`或np函数。 - 模型构建完成后,不要在中途将中间层输出转换为numpy数组。 --- #### **示例修正代码** ```python import tensorflow as tf # 使用TensorFlow操作定义模型 model = tf.keras.Sequential([ tf.keras.layers.LSTM(64, return_sequences=True, input_shape=(10, 1)), tf.keras.layers.Lambda(lambda x: tf.reshape(x, (-1, 64))), # 使用tf.reshape而非np.reshape tf.keras.layers.Dense(10) ]) model.compile(optimizer='adam', loss='mse') model.fit(dataset, epochs=10) # 使用tf.data.Dataset输入 ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武的阶乘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值