51单片机实现数码管显示小数
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单片机实现数码管显示小数相关推荐
- 51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真
51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真 本实验通过51单片机读取DS18B20温度传感器的温度,然后通过数码管显示,并通过串口,将读取到的温度数据发送出去. 本案例需要使 ...
- 51单片机七段数码管显示时钟无按键控制—①—74HC595版
参考链接: 51单片机七段数码管显示时钟加按键控制-③-74HC595版 51单片机七段数码管显示时钟加按键控制-②-74HC595版 文章目录 一.实验内容: 二.实验分析: 三.仿真图: 四.源代 ...
- 51单片机控制数码管显示
前言 今天学习51单片机的数码管模块 我的学习板上面的数码管是4为一体由12个引脚控制的模块. 今天就编程控制它显示我们想要的输出. 数码管本质上是由8个LED拼接而成的,他们分别叫做a,b,c,d, ...
- 普中51单片机按键-数码管显示
基于普中单片机按键-数码管显示 简介 1.硬件部分 普中单片机开发板 数码管 独立按键 2.软件部分 keil软件 硬件部分 普中单片机开发板 数码管 独立按键 (这些都是开发板的最基本的配置) 软件 ...
- 基于51单片机的数码管显示方案
这一次给大家带来的项目是课堂作业级别的51单片机数码管显示,本次的项目着重于讲解原理,让大家明白单片机的io对于外界设备的控制是如何进行的. 共阳极和共阴极数码管的差异 (1)驱动方法的差异.一个数码 ...
- 51单片机 静态数码管显示
本章博客讲述使用51单片机编写程序静态数码管显示 1.新建工程,选择芯片型号,这里注意--为了防止出现在插入头文件reg时出现某些引脚不定义的情况 可尝试切换为AT89C52型号的芯片,插入头文件即为 ...
- 51单片机动态数码管显示自己学号
实验题目:使用51单片机实现动态数码管显示自己8位学号,例如20220018 在此原理图又分两种连接方式: 第一种是8位数码管接38译码器来减少端口使用. 第二种是,没有端口要求接好就可以那就是,把位 ...
- 51单片机动态数码管显示时间+protues仿真
项目场景: 纯小白 第一次写文章 写的不好请见谅 做51单片机数码管显示时间实验的时候protues 仿真出现了问题 问题描述 做51单片机数码管显示时间实验的时候protues 仿真出现了问题 仿真 ...
- 基于51单片机密码锁数码管显示步进电机开锁设计
视频演示地址:https://www.bilibili.com/video/BV1Eg411G7JW/ 该设计是由AT89C51单片机为主控芯片数码管显示 开机后输入密码正确步进电机转半圈错误蜂鸣器报 ...
最新文章
- Pip install: ImportError: cannot import name IncompleteRead
- RMAN_学习笔记1_RMAN Structure概述和体系结构
- 更多的结构化命令(第十三章)
- 《LeetCode力扣练习》第12题 C语言版 (做出来就行,别问我效率。。。。)
- 数据库 ACCESS与SQL SERVER 2000分页SQL语句 分析
- TCP 滑动窗口简述
- IOS使用MessageUI Framework 发送短信息
- Java黑皮书课后题第5章:5.10(找出能被5和6整除的数)编写程序,显示从100到1000之间所有能被5和6整除的数,每行显示10个。数字之间用一个空格字符隔开
- c语言样本,C语言样本教案 第二章
- 每个程序员都可能犯过的10个错误
- mysql内部损坏_mysql表损坏故障案例
- fetch ajax cros,由 Fetch 跨域 看 CORS
- 计算机怎么切换到音乐,电脑怎么换开关机背景音乐?电脑换开关机背景音乐的方法...
- cuSPARSE库:(十四)求解稀疏三角形线性系统(solution of sparse triangular linear systems)
- Box2DWeb_03之Shape
- 苹果Mac经典办公套件:Microsoft 365 支持辅助功能,高效工作
- JavaScript 技术篇 - js读取Excel文档里的内容实例演示,js如何读取excel指定单元格的内容,js将excel的内容转化为json字符串方法
- iOS AppStore 转让APP
- 可中心可边缘,云计算“罗马大路”需要什么样的超融合新基建?
- 测试手机ram速度软件,8GB RAM极限是什么?我们拿两款手机测试了一下