【51单片机快速入门指南】2.2:任意位/任意长度数码管显示数字、小数

目录

  • 源码
    • Tube.c
    • Tube.h
    • main.c
  • 效果
    • 8位数码管
      • 正整数
      • 负整数
      • 正小数
      • 负小数
    • 6位数码管
      • 正整数
      • 负整数
      • 正小数
      • 负小数
    • 4位数码管
      • 正整数
      • 负整数
      • 正小数
      • 负小数

普中51-单核-A2
STC89C52
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


源码

移植时主要只修改Tube_Num数量、位选函数Tube_Choose()和单个数码管写入函数Singe_Tube_Write()即可。

数码管基础知识见【51单片机快速入门指南】2.1:数码管显示数字、小数 (科学计数法)
stdint.h内容见【51单片机快速入门指南】一、基础知识和工程创建

Tube.c

#include <REGX52.H>
#include "intrins.h"
#include "stdint.h"
#include "Tube.h"#define Tube_Port P0#define Tube_Num  8sbit Tube_A0 = P2^2;
sbit Tube_A1 = P2^3;
sbit Tube_A2 = P2^4;//位选
void Tube_Choose(uint8_t num)
{Tube_A0 = (num & 1);Tube_A1 = (num & 2) >> 1;Tube_A2 = (num & 4) >> 2;
}//显示的延时 400us @11.0592MHz
void LED_Tube_Delay()
{unsigned char i;_nop_();i = 181;while (--i);
}//单个数码管写入数据
void Singe_Tube_Write(uint8_t Data)
{Tube_Port = Data;
}code uint8_t Error_Codes[]=
{Tube_Code_E,Tube_Code_r,Tube_Code_r,Tube_Code_o,Tube_Code_r
};int32_t Pow10(int32_t Pow)
{int32_t output = 1;while (Pow--)output *= 10;return output;
}code uint8_t Tube_Codes_0ToF[] =
{Tube_Code_0,Tube_Code_1,Tube_Code_2,Tube_Code_3,Tube_Code_4,Tube_Code_5,Tube_Code_6,Tube_Code_7,Tube_Code_8,Tube_Code_9,Tube_Code_A,Tube_Code_b,Tube_Code_C,Tube_Code_d,Tube_Code_E,Tube_Code_F
};//显示整数
void Display_Int(int32_t Num)
{int8_t i = 0;uint8_t DisplayNum = 0;char Tube_Double_Buffer[Tube_Num] = {0};uint8_t Sign_Flag = 0;if(Num >= Pow10(Tube_Num) - 1 || Num <= -(Pow10(Tube_Num - 1) - 1))									{for(i = Tube_Num - 1; i >= 0; --i){Singe_Tube_Write(Tube_Code_NULL);					//消隐Tube_Choose(i);if(Tube_Num - 1 - i < sizeof(Error_Codes))Singe_Tube_Write(Error_Codes[Tube_Num - 1 - i]);			//显示elseSinge_Tube_Write(Tube_Code_NULL);LED_Tube_Delay();}return;}else{if(Num < 0){Sign_Flag = 1;Num = -Num;}for(i = 0; i < Tube_Num; ++i){DisplayNum = Num % 10;if(Num == 0 && i != 0){if(Sign_Flag){Tube_Double_Buffer[i] = Tube_Code_Negative_Sign;	//负号Sign_Flag = 0;}elseTube_Double_Buffer[i] = Tube_Code_NULL;}elseTube_Double_Buffer[i] = Tube_Codes_0ToF[DisplayNum];Num /= 10;}for(i = 0; i < Tube_Num; ++i){Singe_Tube_Write(Tube_Code_NULL);					//消隐Tube_Choose(i);Singe_Tube_Write(Tube_Double_Buffer[i]);			//显示LED_Tube_Delay();}return;}
}//显示小数
void Display_Double(double Num)
{int8_t i = 0;int8_t j = 0;uint8_t DisplayNum = 0;int32_t Int; int8_t Int_Flag;double Double;char Tube_Double_Buffer[Tube_Num] = {0};if(Num >= Pow10(Tube_Num) - 1 || Num <= -(Pow10(Tube_Num - 1) - 1))									{for(i = Tube_Num - 1; i >= 0; --i){Singe_Tube_Write(Tube_Code_NULL);					//消隐Tube_Choose(i);if(Tube_Num - 1 - i < sizeof(Error_Codes))Singe_Tube_Write(Error_Codes[Tube_Num - 1 - i]);			//显示elseSinge_Tube_Write(Tube_Code_NULL);LED_Tube_Delay();}return;}else{if(Num < 0){Tube_Double_Buffer[Tube_Num - 1] = Tube_Code_Negative_Sign;	//负号Num = -Num;}Int = (int32_t)Num;Double = Num - Int;for (j = 0; Int >= Pow10(j); ++j);for(i = Tube_Num - 1 - (Tube_Double_Buffer[Tube_Num - 1] == Tube_Code_Negative_Sign), Int_Flag = 1; i >= 0; --i){	if(Int_Flag)if(Int)for(; j; --j, --i){Tube_Double_Buffer[i] = Tube_Codes_0ToF[Int / Pow10(j - 1)];Int %= Pow10(j - 1);if (j == 1){--j;Tube_Double_Buffer[i--] |= Tube_Code_Dot;Int_Flag = 0;break;}}else{Tube_Double_Buffer[i--] = Tube_Codes_0ToF[0] | Tube_Code_Dot;Int_Flag = 0;}Double *= 10;Tube_Double_Buffer[i] = (uint8_t)(Double + (i == 0) * 0.5);		//末位四舍五入Double -= (int)Tube_Double_Buffer[i];Tube_Double_Buffer[i] = Tube_Codes_0ToF[Tube_Double_Buffer[i]];}for(i = 0; i < Tube_Num; ++i){Singe_Tube_Write(Tube_Code_NULL);					//消隐Tube_Choose(i);Singe_Tube_Write(Tube_Double_Buffer[i]);			//显示LED_Tube_Delay();}return;}
}//显示数字
void Display_Num(double Num)
{if(Num == (int32_t)Num)Display_Int((int32_t)Num);elseDisplay_Double(Num);return;
}

Tube.h

#ifndef TUBE_H_
#define TUBE_H_#define Tube_Code_NULL 0x00#define Tube_Code_0 0x3f
#define Tube_Code_1 0x06
#define Tube_Code_2 0x5b
#define Tube_Code_3 0x4f
#define Tube_Code_4 0x66
#define Tube_Code_5 0x6d
#define Tube_Code_6 0x7d
#define Tube_Code_7 0x07
#define Tube_Code_8 0x7f
#define Tube_Code_9 0x6f#define Tube_Code_A 0x77
#define Tube_Code_b 0x7c
#define Tube_Code_C 0x39
#define Tube_Code_c 0x58
#define Tube_Code_d 0x5e
#define Tube_Code_E 0x79
#define Tube_Code_F 0x71
#define Tube_Code_G 0x3d
#define Tube_Code_H 0x76
#define Tube_Code_I 0x30
#define Tube_Code_i 0x10
#define Tube_Code_J 0x0e
#define Tube_Code_K	0x7a
#define Tube_Code_L 0x38
#define Tube_Code_M 0x55
#define Tube_Code_n	0x54
#define Tube_Code_o 0x5c
#define Tube_Code_P 0x73
#define Tube_Code_q 0x67
#define Tube_Code_r 0x50
#define Tube_Code_S 0x64
#define Tube_Code_t 0x78
#define Tube_Code_U	0x3e
#define Tube_Code_u 0x1c
#define Tube_Code_v 0x62
#define Tube_Code_W 0x6a
#define Tube_Code_X 0x36
#define Tube_Code_y 0x6e
#define Tube_Code_Z 0x49#define Tube_Code_Dot 0x80
#define Tube_Code_Negative_Sign 0x40void Display_Int(int32_t Num);
void Display_Double(double Num);
void Display_Num(double Num);#endif

main.c

#include <REGX52.H>
#include "intrins.h"
#include "stdint.h"
#include "Tube.h"void main(void)
{	while(1){Display_Num(-235);}		
}

效果

8位数码管

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

#define Tube_Port P0#define Tube_Num  8sbit Tube_A0 = P2^2;
sbit Tube_A1 = P2^3;
sbit Tube_A2 = P2^4;//位选
void Tube_Choose(uint8_t num)
{Tube_A0 = (num & 1);Tube_A1 = (num & 2) >> 1;Tube_A2 = (num & 4) >> 2;
}//显示的延时 400us @11.0592MHz
void LED_Tube_Delay()
{unsigned char i;_nop_();i = 181;while (--i);
}//单个数码管写入数据
void Singe_Tube_Write(uint8_t Data)
{Tube_Port = Data;
}

正整数

while(1)
{Display_Num(23333);
}

在这里插入图片描述

负整数

while(1)
{Display_Num(-123456);
}

在这里插入图片描述

正小数

while(1)
{Display_Num(1.23456);
}

在这里插入图片描述

负小数

while(1)
{Display_Num(-45.678987);
}		

在这里插入图片描述

6位数码管

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

#define Tube_Port P0#define Tube_Num  6sbit SEG_DLE = P2^6;
sbit SEG_WLE = P2^7;//位选
void Tube_Choose(uint8_t num)
{SEG_DLE = 0;SEG_WLE = 1;Tube_Port = ~(0x20 >> num);SEG_WLE = 0;
}//显示的延时 400us @11.0592MHz
void LED_Tube_Delay()
{unsigned char i;_nop_();i = 181;while (--i);
}void Singe_Tube_Write(uint8_t Data)
{SEG_DLE = 1;SEG_WLE = 0;Tube_Port = Data;SEG_DLE = 0;
}

正整数

while(1)
{Display_Num(23333);
}

在这里插入图片描述

负整数

while(1)
{Display_Num(-12);
}

在这里插入图片描述

正小数

while(1)
{Display_Num(1.23456);
}

在这里插入图片描述

负小数

while(1)
{Display_Num(-45.678987);
}		

在这里插入图片描述

4位数码管

在这里插入图片描述

#define Tube_Port P0#define Tube_Num  4sbit Tube_Y0 = P1^0;
sbit Tube_Y1 = P1^1;
sbit Tube_Y2 = P1^2;
sbit Tube_Y3 = P1^3;//位选
void Tube_Choose(uint8_t num)
{switch(num){case 0:Tube_Y0 = 1;Tube_Y1 = 0;Tube_Y2 = 0;Tube_Y3 = 0;break;case 1:Tube_Y0 = 0;Tube_Y1 = 1;Tube_Y2 = 0;Tube_Y3 = 0;break;case 2:Tube_Y0 = 0;Tube_Y1 = 0;Tube_Y2 = 1;Tube_Y3 = 0;break;case 3:Tube_Y0 = 0;Tube_Y1 = 0;Tube_Y2 = 0;Tube_Y3 = 1;break;}
}//显示的延时 1ms @12MHz
void LED_Tube_Delay()
{unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);
}void Singe_Tube_Write(uint8_t Data)
{Tube_Port = Data;
}

正整数

while(1)
{Display_Num(233);
}

在这里插入图片描述

负整数

while(1)
{Display_Num(-12);
}

在这里插入图片描述

正小数

while(1)
{Display_Num(1.23456);
}

在这里插入图片描述

负小数

while(1)
{Display_Num(-45.678987);
}		

在这里插入图片描述

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

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

相关文章

【51单片机快速入门指南】2.3:GPIO读取矩阵键盘 8个IO读16键

目录硬知识矩阵键盘介绍测试程序Key_Board.cKey_Board.hmain.c实验现象普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 选自《普中51单片机开发攻略_V1.2》 矩阵键盘介绍 独立按键与单片机连接时&#xff0c;每一个按键…

【51单片机快速入门指南】2.4:74HC595、LED点阵屏及其SPI控制

目录硬知识IO 口扩展方式-串转并74HC595 芯片介绍硬件设计测试源码HC74595.cHC74595.hmain.h实验现象SPI控制普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 选自《普中51单片机开发攻略_V1.2》 IO 口扩展方式-串转并 …

【51单片机快速入门指南】3:中断系统

目录硬知识中断概念中断系统中断结构中断优先级中断处理普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 选自《普中51单片机开发攻略_V1.2》、《STC89C52系列单片机器件手册》 中断概念 中断是为使单片机具有对外部或内…

正能量之项目经理的自我修养

正能量之项目经理的自我修养 作者&#xff1a;张子良 版权所有&#xff0c;转载请注明出处 引子 还记得曾经看过的《喜剧之王》么&#xff1f;还记的那曾经经典的台词么&#xff1a;“我不是死跑龙套的”&#xff0c;“人如果没有理想&#xff0c;和咸鱼又有什么区别呢&#xf…

利用D触发器和异或门实现两个IO解读电机编码器的计数值和方向

目录反转变正转正转变反转iPad Pro 2020 14.8.1 仿真软件&#xff1a;iCircuit 突发奇想&#xff0c;做个记录。应该可以用于诸如51单片机、Arduino或是电赛中可能用到的MSP430G2553这类外设十分稀缺的单片机上。一个想法&#xff0c;啊&#xff0c;不一定对。 黄色波形是编码…

TCP协议的三次握手和四次分手

HTTP连接 HTTP协议即超文本传送协议(Hypertext Transfer Protocol )&#xff0c;是Web联网的基础&#xff0c;也是手机联网常用的协议之一&#xff0c;HTTP协议是建立在TCP协议之上的一种应用。HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应&#xff0c;在请…

CountDownLatch线程同步辅助

2019独角兽企业重金招聘Python工程师标准>>> http://bughope.iteye.com/blog/2081935 在上一篇文章中写道用一个静态的变量保存线程的执行状态,并用时间等待的方法后来仔细考虑,其实是 线程不安全的.多个线程同时执行这个类时,这个静态变量的值就不能保证了. 用一个…

【51单片机快速入门指南】3.1:配置外部中断触发方式和中断优先级

目录源码EXTI.cEXTI.hmain.c实验现象普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 源码 stdint.h见【51单片机快速入门指南】1&#xff1a;基础知识和工程创建 中断知识见【51单片机快速入门指南】3&#xff1a;中断系统 将…

(转)工厂方法模式

转自&#xff1a;http://www.jellythink.com/archives/62 问题描述 之前讲到了C设计模式——简单工厂模式&#xff0c;由于简单工厂模式的局限性&#xff0c;比如&#xff1a;工厂现在能生产ProductA、ProductB和ProductC三种产品了&#xff0c;此时&#xff0c;需要增加生产Pr…

一种父线程阻塞等待子线程的有效方法

最近在做一个查询优化时&#xff0c;考虑到一次查询耗时较多&#xff0c;所以打算用多线程来做&#xff0c;之前是串行查询。比如一个用户查询触发50个线程&#xff0c;在只有一个用户的情况下&#xff0c;性能比串行查询确实提高了许多&#xff0c;但当多个用户同时触发查询的…

C语言利用循环队列实现滑动平均值滤波器,提高计算速度

目录源码Filter.cFilter.h使用效果普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 串口示波器&#xff1a;Vofa 1.3.10 网上查到的滑动平均值滤波器在计算平均值的时候还要再for累加一遍&#xff0c;这太浪费时间了&#xff0c…

Exchange Server 2013日记功能

9.6 日记9.6.1 日记功能为什么很重要首先&#xff0c;了解日记功能与存档功能之间的区别十分重要&#xff1a;首先&#xff0c;了解日记功能与存档功能之间的区别十分重要&#xff1a; “日记”可以记录组织中的所有通信&#xff08;包括电子邮件通信&#xff09;&#xff0c;以…

VB数据库经典实例总结(二)

大家先看一张似图非图的图、 我们先称它为“过程”也许有不对的地方&#xff0c;在我学数据库到这个阶段、到这个刚刚接触、初生牛犊不怕虎的阶段对它的理解是这样的、所有的都是这个过程、只是在这中间掺杂了一些知识点&#xff08;我们要掌握的&#xff09;针对有些个别的&am…

适用于单片机的FFT快速傅里叶变换算法,51单片机都能用

目录源码FFT.cFFT.h使用方法效果其他部分的代码main.c普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 算法来自FFT算法的使用说明与C语言版实现源码 —— 原作者&#xff1a;吉帅虎 速度更快的版本见C语言实现的FFT与IFFT源代码…

第9课 - 函数重载分析(下)

第9课 - 函数重载分析&#xff08;下&#xff09; 1. 重载与指针 1.1 下面的函数指针将保存哪个函数的地址&#xff1f; 1.2 函数重载遇上函数指针 将重载函数名赋值给函数指针时&#xff1a; &#xff08;1&#xff09;根据重载规则挑选与函数指针参数列表一致的候选者 &#…

常见窗函数的C语言实现及其形状,适用于单片机、DSP作FFT运算

目录源码WindowFunction.cWindowFunction.h使用形状三角窗巴特利特窗巴特利特-汉宁窗布莱克曼窗布莱克曼-哈里斯窗博曼窗切比雪夫窗平顶窗高斯窗海明窗汉宁窗纳托尔窗Parzen窗矩形窗&#xff08;模拟&#xff09;效果无窗汉宁窗平顶窗平台&#xff1a;Windows 10 20H2 Visual …

.net Json JavaScriptSerializer JsonHelper类

结合.net 的JavaScriptSerializer 类实现Json数据处理 调用1&#xff1a; Model.Users m BLL.UsersBLL.GetUserById(Convert.ToInt32(id));string result "";if (m ! null)result JsonHelper.ObjectToJSON(m);context.Response.Write(result); 调用2&#xff…

C语言实现的FFT与IFFT源代码,不依赖特定平台

目录源码FFT.cFFT.h使用方法初始化输入数据FFT 快速傅里叶变换解算FFT结果使用python绘制FFT波形IFFT 快速傅里叶逆变换解算IFFT结果Windows 10 20H2 Visual Studio 2015 Python 3.8.12 (default, Oct 12 2021, 03:01:40) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on …

在51单片机上使用递归的注意事项

目录问题应对措施原理普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 问题 在Keil C51中直接使用递归会报如下警告&#xff1a; recursive call to non-reentrant function 为了提高运行效率&#xff0c;C51采用静态分配局部变量…

C盘瘦身:QQ文件的清理及Group2文件夹

目录问题解决方法Windows 10 20H2 TIM 问题 最近C盘被撑爆了 使用SpaceSniffer一扫发现QQ的文件中有个Group2文件夹占了我17G 但使用QQ自带的个人文件夹清理却扫不到&#xff0c;据说直接删除会丢失近期所有群聊的聊天图片 解决方法 在这个地方找到了大神fsz1987给出的解…