嵌入式软件--51单片机 DAY 2

2024-09-03 06:28

本文主要是介绍嵌入式软件--51单片机 DAY 2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、数码管

1.数码管概况

2.设计

(1)硬件设计

我们可以通过阴极控制显示的位置,通过阳极控制显示的内容。两个数码管共有8个阴极引脚和16和阳极引脚,如果所有引脚都直接接入MCU,会造成MCU引脚的极大浪费。

为了节省MCU的引脚,我们可以将两个数码管的阳极接在一起。

如此我们就有了8个阴极,8个阳极16个引脚。我们只需通过8个GPIO引脚就能控制这8位数码管的显示内容了。

既然是八位,我们很快想到了38译码器,通过三位二进制数字的输入控制八种结果。

由于51单片高电平的驱动能力很微弱,不足以点亮数码管,因此可以使用74HC245N作为驱动芯片,该芯片的用法如下。

有了74HC245之后,51单片引脚的输出就只用作信号,而驱动数码管的电流则由74HC245的电源提供。

(2)软件设计

为了实现当前需求,需要考虑两点,分别是显示位置和显示内容。确定显示位置称为数码管的位选,确定显示内容称为数码管的段选。

1》位选

P12  P13  P14控制显示位置,连接数码管阴极,如果为0低电平就能导通显示。故控制位选。

P13接到了A0,P14接到了A1,P15接到了A2。

例:如果p15-p13输入为000,那么与y0相连的1号数码显示。

如果001,第二位显示

010,第三位显示

011,第四位显示

100,第五位显示

······

2》段选

根据原理图可知,数码的段选通过单片机的P00~P07这7个引脚控制,具体的对应关系如下。

阳极连接。如果不点亮,给0即可。想显示,给1即可。

以上显示,代表着数字0,即给ABCDEF一个高电平1,G给0不亮,DP给0代表小数点不亮。

所以段选,P07(高位)--P01:0 0 1 1 1 1 1 1

那么可以给寄存器P0一个值0x3F.

通过p00-p07显示数码管的内容。通过让ABCDEFG、DP的亮灭,显示数字。

如此可以得到映射关系表:

3》代码实现

要求:静态显示,在任意位置,显示任意数字。

位选决定位置。根据位选的数位,决定P13~P15的取值。

段选,0~9的数字显示通过P00-P07控制。数字0要让ABCDEF亮起,如此编码就为:00111111

十六进制0x3F。数字2即为0x5B.

如果让数字在第一个位置亮起,P15~P13:0 0 0

段选好说,将数字编码2赋值于P0,2对应十六进制0X5B,即可通过控制数码管显示对应的数字。

位选需要动动脑筋,switch能够做到,但没有效率。我们用position形参,传递的是第几位。假设P1是定义的八位变量,P1=10 101 010,我们要在第4位显示数字,那么P15-P13:011   position:0000 0011,现在要做的就是将position的末三位赋值到P1的中三位,并不影响P1其他数位上的数字。

所以考虑怎样给到P1的中三位。

        P1:10 101 010

position:0000 0 011

为了更好的观察规律,先将position左移三位。

        P1:10 101 010

position:00 011 000

将P1的中三位置0,在与position做或运算。那么先让P1中三位置零,就与上11000111,其他几位都是1,1与任何数相与都是原来的数。

那么调整下方法:让position左移三位,让P1&11000111,在P1与position作或运算。

position<<=3;

P1&=11000111;//P1&=0xC7

p1|=position;

代码表示为:

#include <STC89C5xRC.H>
#define SMG_EN P36        // 数码管总开关
#define LED_EN P34        // LED灯总开关
typedef unsigned char u8; // 给无符号字符类型取别名,代表无符号8位
static u8 s_digit_codes[10] = {0x3F, // 00x06, // 10x5B, // 20x4F, // 30x66, // 40x6D, // 50x7D, // 60x07, // 70x7F, // 80x6F  // 9
};//编码数组
//定义函数
void DigitalTube_DisplaySingle(u8 position, u8 num_code)//一个参数位选:P13/P14/P15,一个参数段选
{P1 &= 0xC7;//按位与运算position <<= 3;P1 |= position;P0 = num_code;//数字编码赋予P0
}
void main()
{// 打开数码管总开关SMG_EN = 0;// 关闭LED灯总开关LED_EN = 0;DigitalTube_DisplaySingle(0, s_digit_codes[2]);//让数字显示在位选0第一个位置,显示内容为2while (1) {};
}

烧录以上代码到51核心板内,数码管第一个位置显示2就完成了。

4》变量声明

在C89标准中,所有声明的变量必须在作用域的最前边声明。C99就没有这个约束了。注意一下即可!

二、数码管动态显示

1.要求

我们先搞整数的显示。

2.设计

8位数码管同一时刻只能显示一个位置,通过高速的循环显示可以做到以上效果。

(1)思路

(2)代码实现

我们首先要定义一个显存数组。

#include <STC89C5xRC.H>
#define SMG_EN P36        // 数码管总开关
#define LED_EN P34        // LED灯总开关
typedef unsigned char u8; // 给无符号字符类型取别名,代表无符号8位
typedef unsigned long u32;
static u8 s_digit_codes[10] = {0x3F, // 00x06, // 10x5B, // 20x4F, // 30x66, // 40x6D, // 50x7D, // 60x07, // 70x7F, // 80x6F  // 9
};//编码数组
//定义显存数组
u8 buffer[8];
//定义函数
void DigitalTube_DisplaySingle(u8 position, u8 num_code)//一个参数位选:P13/P14/P15,一个参数段选
{P0=0x00;P1 &= 0xC7;//按位与运算position <<= 3;P1 |= position;P0 = num_code;//数字编码赋予P0
}
//设置显存数组,待展示数字
void DigitalTube_DisplayNum(u32 num)
{u8 i;for(i=0;i<8;i++){
buffer[i]=0x00;}if (num==0){buffer[7]=s_digit_codes[0];return;}i=7;while (num>0){buffer[i]=s_digit_codes[num%10];num/=10;i--;}}
//动态扫描
void DigitalTube_Refresh()
{
u8 i;
for ( i = 0; i < 8; i++)
{DigitalTube_DisplaySingle(i,buffer[i]);
}}
void main()
{// 打开数码管总开关SMG_EN = 0;// 关闭LED灯总开关LED_EN = 0;DigitalTube_DisplayNum(12345);while (1) {DigitalTube_Refresh();};
}

上图的效果就实现了。

三、模块化编程

1.命名规范

变量命名

函数命名

文件命名

2.代码分层规范

(1)目录

(2)驱动层

所有与芯片直接交互的自身硬件代码,例如GPIO开关、硬件UART/ADC的驱动、计时器等。

目录:Dri/

前缀:Dri_

(3)接口层

位于驱动层之上,通过标准接口驱动的外部硬件代码,没有外部硬件设备,可以不用这一层。

目录:Int/

前缀:Int_

(4)中间层

提供更高级的服务,如操作系统、文件系统、通信协议栈等。

简单项目用不到这一层。

目录:Mid/

前缀:Mid_

(5)应用层

包含应用程序的主要逻辑。实现与上层交互,不直接访问这一层。

目录:App/

前缀:App_

这篇关于嵌入式软件--51单片机 DAY 2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1132281

相关文章

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

Linux基础入门 --9 DAY

文本处理工具之神vim         vi和vim简介 一、vi编辑器 vi是Unix及类Unix系统(如Linux)下最基本的文本编辑器,全称为“visual interface”,即视觉界面。尽管其名称中包含“visual”,但vi编辑器实际上工作在字符模式下,并不提供图形界面。vi编辑器以其强大的功能和灵活性著称,是Linux系统中不可或缺的工具之一。 vi编辑器具有三种主要的工作模

day-50 求出最长好子序列 I

思路 二维dp,dp[i][h]表示nums[i] 结尾,且有不超过 h 个下标满足条件的最长好子序列的长度(0<=h<=k),二维数组dp初始值全为1 解题过程 状态转换方程: 1.nums[i]==nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h]+1) 2.nums[i]!=nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h-1

[Day 73] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

AI在健康管理中的應用實例 1. 引言 隨著健康管理需求的提升,人工智能(AI)在該領域的應用越來越普遍。AI可以幫助醫療機構提升效率、精準診斷疾病、個性化治療方案,以及進行健康數據分析,從而改善病患的健康狀況。這篇文章將探討AI如何應用於健康管理,並通過具體代碼示例說明其技術實現。 2. AI在健康管理中的主要應用場景 個性化健康建議:通過分析用戶的健康數據,如飲食、運動、睡眠等,AI可

Vue day-03

目录 Vue常用特性 一.响应更新 1. 1 v-for更新监测 1.2 v-for就地更新 1.3 什么是虚拟DOM 1.4 diff算法更新虚拟DOM 总结:key值的作用和注意点: 二.过滤器 2.1 vue过滤器-定义使用 2.2 vue过滤器-传参和多过滤器 三. 计算属性(computed) 3.1 计算属性-定义使用 3.2 计算属性-缓存 3.3 计算属

代码训练营 Day26 | 47.排序II | 51. N-皇后 |

47.排序II 1.跟46题一样只不过加一个树层去重 class Solution(object):def backtracking(self,nums,path,result,used):# recursion stopif len(path) == len(nums):# collect our setresult.append(path[:])return for i in range(

用Python实现时间序列模型实战——Day 14: 向量自回归模型 (VAR) 与向量误差修正模型 (VECM)

一、学习内容 1. 向量自回归模型 (VAR) 的基本概念与应用 向量自回归模型 (VAR) 是多元时间序列分析中的一种模型,用于捕捉多个变量之间的相互依赖关系。与单变量自回归模型不同,VAR 模型将多个时间序列作为向量输入,同时对这些变量进行回归分析。 VAR 模型的一般形式为: 其中: ​ 是时间  的变量向量。 是常数向量。​ 是每个时间滞后的回归系数矩阵。​ 是误差项向量,假

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品