51单片机实现数码管显示小数

  • 要求
  • 1 Proteus 面向编程的模型搭建
  • 2 代码实现
    • 2.1. 实现数码管刷新
    • 2.2 对小数进行分解的函数
  • 3 测试用例
  • 4 仿真结果

要求

要求1:根据整数部分位数,动态调整小数部分精度,小数部分最大精确到小数点后4位(32位float型能保证的最大精度!),比如:总共5个位,可以显示

示例数据 小数精度 整数范围
5.4321 0.0001 0~9
54.321 0.001 00~99
543.21 0.01 000~999
5432.1 0.1 0000~9999

要求2:能正确显示0.0和0.0001;

要求3:数要干净利落!不能有前缀和后缀0:比如3.14,不要加前缀000003.14,也不要加后缀 3.1400000;

测试数据集:{0.0001, 0, 0.0,
3.545, 3.124, 3.325, 4.1236,
99.9876, 43.125, 54. 4321,
0.1234, 54321.0}

1 Proteus 面向编程的模型搭建


2 代码实现

2.1. 实现数码管刷新

/** @brief 使用数码管显示float数据* @param num: 待显示的float数* @param figure: 这个小数的总位数,比如3.14 总共3位;123.42 总共5位* @note * 只能保证到小数点后4位的准确,受限于硬件和Keil,不能够使用double(64-bit)存储数据* Keil C51 里面double和float都是 32-bit 的**/
void LED_7SEG_Display_74HC245_Float(float num, uint8_t figure)
{uint8_t de_num[NUM_DISPLAY]; // 占据内存实体空间uint8_t i;uint8_t pos_data = 0x7f; // from low bituint8_t seg_data = seg_code_cc[19]; // blanking// float 能保证小数点后4位精度num += 0.00005;if(figure > NUM_DISPLAY){ // limiting the figure valuefigure = NUM_DISPLAY;}decomposeFloat(num, de_num, figure);for(i = 0; i < figure; i++){// blanking 消除上次干扰P1 = seg_code_cc[19];// position selectionP3 = pos_data;pos_data = (pos_data >> 1 | 0x80);// segment selectionseg_data = de_num[figure - i - 1];P1 = seg_data;delay_ms(2);}
}

2.2 对小数进行分解的函数

#define NUM_DISPLAY 8 // 定义数码管数量
/** @brief 对float数据进行分解,生成段码数组* @param f: 待显示的float数* @param decompose: 将浮点数分解后的数码管“段码”数组* @param whole_figure: 总共的位数* @note * 只能保证到小数点后4位的准确,受限于硬件,不能够使用double(64-bit)存储数据* * 分解后的结果,保存到数组decompose中,比如3.1415,对每个数"3.", "1", "4", "1", "5",生成段码,* 从左到右存放到decompose[0..4]里面**/
static uint8_t decomposeFloat(float f, uint8_t *decompose, uint8_t whole_figure)
{uint8_t i = 0;uint32_t int_part = (uint32_t)f;uint8_t cnt_int_pos = 0; // 用于统计整数部分的位数uint8_t cnt_float_pos = 0; // 用于统计小数部分的位数uint8_t int_part_helper[8]; // 倒序的整数部分分解后的单元/**** (1)分解整数部分 ****/if(int_part == 0){// 对 0.xxxx 进行特殊处理decompose[i] = seg_code_cc[0]; //decompose[0] 直接存放0的段码cnt_int_pos = 1;i++;}else{// >= 1.xxxx 正常处理while(int_part){// 得到的是倒序的int_part_helper[i] = seg_code_cc[int_part % 10];int_part = int_part / 10;i++;}cnt_int_pos = i; // 统计出来整数的位数// 倒着赋值给分解数组for(i = 0; i < cnt_int_pos; i++){decompose[i] = int_part_helper[(cnt_int_pos - 1) - i];}}/**** (2)安放小数点 ****/decompose[i-1] |= seg_code_cc[17]; // 给整数部分最后1位上面,添加小数点/**** (3)分解小数部分 ****/cnt_float_pos = whole_figure - i; // 统计小数部分的位数for(i = 0; i < cnt_float_pos; i++){ // 移位小数部分,得到整数f *= 10;}int_part = (uint32_t)f;for(i = 0; i < cnt_float_pos; i++){ // 小数部分分解decompose[whole_figure - i - 1] = seg_code_cc[int_part % 10];int_part /= 10;}return cnt_float_pos; // 返回小数部分的位数
}

3 测试用例

int main(void)
{uint16_t i;/* Configure the system clock *//* Initialize all configured peripherals *//* Infinite loop */while(1) {for(i = 0; i < 40; i++){LED_7SEG_Display_74HC245_Float(0.0001, 5);}for(i = 0; i < 400; i++){LED_7SEG_Display_74HC245_Float(0, 2);}for(i = 0; i < 200; i++){LED_7SEG_Display_74HC245_Float(0.0, 2);}for(i = 0; i < 100; i++){LED_7SEG_Display_74HC245_Float(3.545, 4);}for(i = 0; i < 100; i++){LED_7SEG_Display_74HC245_Float(3.124, 4);}for(i = 0; i < 100; i++){LED_7SEG_Display_74HC245_Float(3.325, 4);}for(i = 0; i < 40; i++){LED_7SEG_Display_74HC245_Float(4.1236, 5);}for(i = 0; i < 60; i++){LED_7SEG_Display_74HC245_Float(99.9876, 6);}for(i = 0; i < 100; i++){LED_7SEG_Display_74HC245_Float(43.125, 5);}for(i = 0; i < 50; i++){LED_7SEG_Display_74HC245_Float(54.4321, 6);}for(i = 0; i < 60; i++){LED_7SEG_Display_74HC245_Float(0.1234, 5);}for(i = 0; i < 60; i++){LED_7SEG_Display_74HC245_Float(54321.0, 6);}};//    return 0;
}

4 仿真结果

51单片机实现数码管显示小数相关推荐

  1. 51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真

    51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真 本实验通过51单片机读取DS18B20温度传感器的温度,然后通过数码管显示,并通过串口,将读取到的温度数据发送出去. 本案例需要使 ...

  2. 51单片机七段数码管显示时钟无按键控制—①—74HC595版

    参考链接: 51单片机七段数码管显示时钟加按键控制-③-74HC595版 51单片机七段数码管显示时钟加按键控制-②-74HC595版 文章目录 一.实验内容: 二.实验分析: 三.仿真图: 四.源代 ...

  3. 51单片机控制数码管显示

    前言 今天学习51单片机的数码管模块 我的学习板上面的数码管是4为一体由12个引脚控制的模块. 今天就编程控制它显示我们想要的输出. 数码管本质上是由8个LED拼接而成的,他们分别叫做a,b,c,d, ...

  4. 普中51单片机按键-数码管显示

    基于普中单片机按键-数码管显示 简介 1.硬件部分 普中单片机开发板 数码管 独立按键 2.软件部分 keil软件 硬件部分 普中单片机开发板 数码管 独立按键 (这些都是开发板的最基本的配置) 软件 ...

  5. 基于51单片机的数码管显示方案

    这一次给大家带来的项目是课堂作业级别的51单片机数码管显示,本次的项目着重于讲解原理,让大家明白单片机的io对于外界设备的控制是如何进行的. 共阳极和共阴极数码管的差异 (1)驱动方法的差异.一个数码 ...

  6. 51单片机 静态数码管显示

    本章博客讲述使用51单片机编写程序静态数码管显示 1.新建工程,选择芯片型号,这里注意--为了防止出现在插入头文件reg时出现某些引脚不定义的情况 可尝试切换为AT89C52型号的芯片,插入头文件即为 ...

  7. 51单片机动态数码管显示自己学号

    实验题目:使用51单片机实现动态数码管显示自己8位学号,例如20220018 在此原理图又分两种连接方式: 第一种是8位数码管接38译码器来减少端口使用. 第二种是,没有端口要求接好就可以那就是,把位 ...

  8. 51单片机动态数码管显示时间+protues仿真

    项目场景: 纯小白 第一次写文章 写的不好请见谅 做51单片机数码管显示时间实验的时候protues 仿真出现了问题 问题描述 做51单片机数码管显示时间实验的时候protues 仿真出现了问题 仿真 ...

  9. 基于51单片机密码锁数码管显示步进电机开锁设计

    视频演示地址:https://www.bilibili.com/video/BV1Eg411G7JW/ 该设计是由AT89C51单片机为主控芯片数码管显示 开机后输入密码正确步进电机转半圈错误蜂鸣器报 ...

最新文章

  1. Pip install: ImportError: cannot import name IncompleteRead
  2. RMAN_学习笔记1_RMAN Structure概述和体系结构
  3. 更多的结构化命令(第十三章)
  4. 《LeetCode力扣练习》第12题 C语言版 (做出来就行,别问我效率。。。。)
  5. 数据库 ACCESS与SQL SERVER 2000分页SQL语句 分析
  6. TCP 滑动窗口简述
  7. IOS使用MessageUI Framework 发送短信息
  8. Java黑皮书课后题第5章:5.10(找出能被5和6整除的数)编写程序,显示从100到1000之间所有能被5和6整除的数,每行显示10个。数字之间用一个空格字符隔开
  9. c语言样本,C语言样本教案 第二章
  10. 每个程序员都可能犯过的10个错误
  11. mysql内部损坏_mysql表损坏故障案例
  12. fetch ajax cros,由 Fetch 跨域 看 CORS
  13. 计算机怎么切换到音乐,电脑怎么换开关机背景音乐?电脑换开关机背景音乐的方法...
  14. cuSPARSE库:(十四)求解稀疏三角形线性系统(solution of sparse triangular linear systems)
  15. Box2DWeb_03之Shape
  16. 苹果Mac经典办公套件:Microsoft 365 支持辅助功能,高效工作
  17. JavaScript 技术篇 - js读取Excel文档里的内容实例演示,js如何读取excel指定单元格的内容,js将excel的内容转化为json字符串方法
  18. iOS AppStore 转让APP
  19. 可中心可边缘,云计算“罗马大路”需要什么样的超融合新基建?
  20. 测试手机ram速度软件,8GB RAM极限是什么?我们拿两款手机测试了一下

热门文章

  1. 老吕架构-2022~2021年文章索引
  2. NB模组选型及整体方案注意事项
  3. 谷歌浏览器开始测试第三方Cookie拦截
  4. jQuery小案例之通过鼠标按键改变盒子颜色
  5. vue 条件判断绑定内联样式
  6. 桌面应用使用谷歌浏览器内核CEF
  7. 代码review的心得
  8. Java Regex Pattern Matcher
  9. 【机器学习】机器学习基石-林轩田-2-Learning to Answer Yes_No
  10. ORB-SLAM2源码笔记(1)——框架结构