源代码分析

article/2025/5/14 15:57:27

 

//
// 制作一个定时器,2位显示秒,2位显示分,用4个调节按钮调节
// 四个调节按钮为key0, key1, key2, key3分别为P3.2, P3.3, P3.4, P3.5
// 数码管用P0显示a,b,c,d,e,f,g,分别对应P0.0, P0.1, P0.2, P0.3, P0.4, P0.5, P0.6, P0.7
// 数码管用P2.0, P2.1, P2.2, P2.3控制,P2.0控制最左面的LED(即最高位)
//
#include  < reg52.h >
#define  char unsigned char
char  code dis_7[ 11 =   {0xC00xF90xA40xB00x990x920x820xF80x800x900xFF} ; // 共阳LED
char  data scan_con[ 4 =   {0xF70xFB0xFD0xFE } ; // 列扫描控制字
char  data timedata[ 4 =   {0x000x000x000x00} ; // 记时单位初值
char  data dis[ 6 =   {0x000x000x000x000x0a0x00} ; // 显示数据单元
char  data con1s  =   0x00 , con04s  =   0x00 , con  =   0x00 ;
sbit key0 
=  P3 ^ 2 ;
sbit key1 
=  P3 ^ 3 ;
sbit key2 
=  P3 ^ 4 ;
sbit key3 
=  P3 ^ 5 ;
//
void  clearmen( void );
void  scan( void );
void  keyscan( void );
void  delay1ms( int );
//
int  main( void )
{
    clearmen();
    
while(1)
    
{
        scan();
        keyscan();
    }

    
return 0;
}

//
void  clearmen( void )
{
    
int i;
    
for(i = 0; i < 4; i++)
    
{
        dis[i] 
= timedata[i];
    }

    TH0 
= 0x3C;//50ms定时初值
    TL0 = 0xB0;
    TH1 
= 0x3C;//50MS定时初值
    TL1 = 0xB0;
    TMOD 
= 0x11;//T0和T1由TRi控制开启/停止,对内部振荡器12分频计数,为16位计数
    ET0 = 1;
    ET1 
= 1;
    TR1 
= 1;
    TR0 
= 1;
    EA 
= 1;//打开中断总开关
}

//
void  scan( void )
{
    
char k;
    
for(k = 0; k < 4; k++)
    
{
        P0 
= dis_7[dis[k]];//dis[0] = 0x00; dis_7[0] = 0xC0;
                           
//dis[1] = 0x00; dis_7[0] = 0xC0;。。。。。。
        P2 = scan_con[k];  //scan_con[0] = 0xFE; scan_con[1] = 0xFD; scan_con[2] = 0xFB;
        delay1ms(1);
        P2 
= 0xFF;
    }

}

//
void  delay1ms( int  t)
{
    
int i, j;
    
for(i = 0; i < t; i++)
        
for(j = 0; j < 120; j++)
        ;
}

//
void  keyscan( void )
{
    
if(key0 == 0)
    
{
        TR0 
= 0;//关定时器T0,用于1s计时
        ET0 = 0;
        delay1ms(
10);
        
while(key0 == 0);
        con
++;
        
if(con >= 4)
            con 
= 0;
    }

    
if(key1 == 0)
    
{
        delay1ms(
10);
        
while(key1 == 0);
        timedata[con]
++;
        
if(con == 0||con == 2)
            
if(timedata[con] >= 10)
                timedata[con] 
= 0;
            
else ;
        
else if(con == 1||con == 3)
            
if(timedata[con] >= 6)
                timedata[con] 
= 0;
            
else ;
        
else ;
        dis[con] 
= timedata[con];
        dis[
4= 0x0A;
        }


    
if(key2 == 0)
    
{
        delay1ms(
10);
        
while(key2 == 0);
        timedata[con]
--;
        
if(con == 0||con == 2)
            
if(timedata[con] == 0)
                timedata[con] 
= 0x09;
            
else ;
        
else if(con == 1||con == 3)
            
if(timedata[con] == 0)
                timedata[con] 
= 0x05;
            
else ;
        
else ;
        dis[con] 
= timedata[con];
        
//dis[4] = 0x0A;
    }

    
if(key3 == 0)
    
{
         TR0 
= 1;//关定时器T0,用于1s计时
         ET0 = 1;
        delay1ms(
10);
        
while(key3 == 0);
    }

}

//
void  time_intt0( void ) interrupt  1
{
    ET0 
= 0;
    TR0 
= 0;
    TH0 
= 0x3C;//50MS
    TL0 = 0xB0;
    TR0 
= 1;
    con1s
++;
    
if(con1s == 20)//1S
    {
        con1s 
= 0x00;
        timedata[
0]++;
        
if(timedata[0>= 10)
        
{
            timedata[
0= 0;
            timedata[
1]++;
            
if(timedata[1>= 6)
            
{
                timedata[
1= 0;
                timedata[
2]++;
                
if(timedata[2>= 10)
                
{
                    timedata[
2= 0;
                    timedata[
3]++;
                    
if(timedata[3== 6)
                        
if(timedata[2== 0)
                        
{
                            timedata[
2= 0;
                            timedata[
3= 0;
                        }

                 }

              }

           }

        dis[
0= timedata[0];
        dis[
1= timedata[1];
        dis[
2= timedata[2];
        dis[
3= timedata[3];
    }

    ET0 
= 1;
}

//
void  time_intt1( void ) interrupt  3
{
    ET1 
= 0;
    TR1 
= 0;
    TH1 
= 0x3C;//50MS
    TL1 = 0xB0;
    TR1 
= 1;
    con04s
++;
    
if(con04s == 9)//0.45S
    {
        con04s 
= 0x00;
        dis[
5= dis[con];
        dis[con] 
= dis[4];
        dis[
4= dis[5];
    }

    ET1 
= 1;
}

//

 

这段代码不是我写的,出处是《51系列单片机——设计实例》(北航出版社)第八章,我略微做了一些改动。

 这段代码通过T0控制秒的增加和分的增加,T1控制数字闪烁。

我们开始分析,程序开始的第一个函数是main

 

int  main( void )
{
    clearmen();
    
while(1)
    
{
        scan();
        keyscan();
    }

    
return 0;
}

 

main函数调用的第一个函数是clearmen函数

void  clearmen( void )
{
    
int i;
    
for(i = 0; i < 4; i++)
    
{
        dis[i] 
= timedata[i];
    }

    TH0 
= 0x3C;//50ms定时初值
    TL0 = 0xB0;
    TH1 
= 0x3C;//50MS定时初值
    TL1 = 0xB0;
    TMOD 
= 0x11;//T0和T1由TRi控制开启/停止,对内部振荡器12分频计数,为16位计数
    ET0 = 1;
    ET1 
= 1;
    TR1 
= 1;
    TR0 
= 1;
    EA 
= 1;//打开中断总开关
}

 

首先是一个for循环是用timedata数组的前4位给dis数组的4个元素初始化,我们看前面对timedata数组的初始化,如下,我们发现这个初始化让dis[i] = 0 (i = 0, 1, 2, 3)

char  code dis_7[ 11 =   {0xC00xF90xA40xB00x990x920x820xF80x800x900xFF} ; // 共阳LED
char  data scan_con[ 4 =   {0xF70xFB0xFD0xFE } ; // 列扫描控制字
char  data timedata[ 4 =   {0x000x000x000x00} ; // 记时单位初值
char  data dis[ 6 =   {0x000x000x000x000x0a0x00} ; // 显示数据单元

如下代码设置计数器工作方式和初值

TH0  =   0x3C ; // 50ms定时初值
TL0  =   0xB0 ;
TH1 
=   0x3C ; // 50MS定时初值
TL1  =   0xB0 ;
TMOD 
=   0x11 ; // T0和T1由TRi控制开启/停止,对内部振荡器12分频计数,为16位计数

如下代码开启计数器和中断

ET0  =   1 ; // 开启T0中断
ET1  =   1 ; // 开启T1中断
TR1  =   1 ; // 开启T1计数器
TR0  =   1 ; // 开启T0计数器
EA  =   1 ; // 打开中断总开关

clearmen函数执行结束,进入while死循环,接下来的函数是scan函数,scan函数中用一个for循环来给P0和P2赋值(注意:这里可不是初始化了,因为这个死循环一直不停执行,P0和P2的值是变化的。)我们看第一次P0和P2的值是多少?

k = 0时,dis[0] = 0; dis_7[dis[k]] = 0xC0; P0 = 0xC0;scan_con[0] = 0xF7; P2 = 0xF7;延时

k = 1时,dis[1] = 0; dis_7[dis[k]] = 0xC0; P0 = 0xC0;scan_con[1] = 0xFB; P2 = 0xFB;延时

k = 2时,dis[2] = 0; dis_7[dis[k]] = 0xC0; P0 = 0xC0;scan_con[2] = 0xFD; P2 = 0xFD;延时

k = 3时,dis[3] = 0; dis_7[dis[k]] = 0xC0; P0 = 0xC0;scan_con[3] = 0xFE; P2 = 0xFE;延时

while(1)是一个死循环,所以一开始没有超过1S时显示为四个0。

void  scan( void )
{
    
char k;
    
for(k = 0; k < 4; k++)
    
{
        P0 
= dis_7[dis[k]];//dis[0] = 0x00; dis_7[0] = 0xC0;
                                    
//dis[1] = 0x00; dis_7[0] = 0xC0;。。。。。。
        P2 = scan_con[k];  //scan_con[0] = 0xFE; scan_con[1] = 0xFD; scan_con[2] = 0xFB;
        delay1ms(1);
        P2 
= 0xFF;
    }

}

假设我们暂时不碰那几个调节键,那么keyscan函数暂时是无效的,我们留作后面分析。

死循环经过约50MS时,T0和T1出现了一个中断,我们先分析T1中断。如下图:关闭T1中断,关闭T1计时器,重新赋初值,开启T1计时器,con04s加1,中断9次以后(即0.45S)闪烁一次,并且让con04s =0x00(注:通过交换dis[con]和dis[4]的值,此时con = 0, 因为dis[4]的值为0x0A,而while(1)死循环中的scan函数P0 = dis_7[dis[k]],而dis_7[0x0A] = 0xFF为全灭。即)

void  time_intt1( void ) interrupt  3
{
    ET1 
= 0;
    TR1 
= 0;
    TH1 
= 0x3C;//50MS
    TL1 = 0xB0;
    TR1 
= 1;
    con04s
++;
    
if(con04s == 9)//0.45S
    {
        con04s 
= 0x00;
        dis[
5= dis[con];
        dis[con] 
= dis[4];
        dis[
4= dis[5];
    }

    ET1 
= 1;
}

 


http://chatgpt.dhexx.cn/article/23vRvGac.shtml

相关文章

IntelliJ IDEA 智能代码分析

IntelliJ IDEA 智能代码分析 # IntelliJ IDEA 会分析你的代码,在项目中查找文件和语言之间的关联。并使用这些信息,向你提供深度的代码帮助,快速导航,以及错误分析和重构。 1. IDEA的智能完成功能 // 按Ctrl+Shift+Space可以触发 // 通过Ctrl+Shift+Space快捷键组合,I…

Understand: 静态代码分析神器

一直以来&#xff0c;我以为Source Insight的代码分析已经是业界最强、最专业。今天试用了一下Scitools的Understand&#xff0c;导入代码后直接可以生成图形化分析结果&#xff0c;包括模块间调用&#xff0c;函数调用流程等&#xff0c;确实比较震撼。 文章目录 1. 设置2. 导…

RTMPdump 源代码分析 1: main()函数

RTMPdump(libRTMP) 源代码分析系列文章&#xff1a; RTMPdump 源代码分析 1&#xff1a; main()函数 RTMPDump (libRTMP) 源代码分析2&#xff1a;解析RTMP地址——RTMP_ParseURL() RTMPdump (libRTMP) 源代码分析3&#xff1a; AMF编码 RTMPdump (libRTMP) 源代码分析4&am…

JM代码分析(一)

JM代码分析&#xff08;一&#xff09; 入门视频采集与处理&#xff08;学会分析YUV数据&#xff09;核心编码函数研究码流控制RC去块滤波核心全局变量运动矢量的写码流从码流中提取NALU结构体00000(IDR)buf2img_basic宏块模式编码端写码流编码器&#xff1a;解码器&#xff1a…

代码分析:

爬虫组件分析 目录概述需求&#xff1a; 设计思路实现思路分析1.URL管理 DataTable 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for change,chall…

推荐一款源代码统计分析、开发工作量估算、测试缺陷预测的开发工具 —— 代码统计分析工具(SourceCounter)

目录 一、软件简介 二、主要功能 三、更新日志 四、关键字 一、软件简介 代码统计分析工具 4.0&#xff0c;支持 30多种代码格式。能够统计包括&#xff1a;代码行数、注释、空行、文件大小等数据。另外&#xff0c;还支持对软件开发项目的各个开发阶段的工数、成本、质量…

恶意代码分析——基础技术篇

文章目录 恶意代码分析目的恶意代码分析方法恶意代码种类恶意代码静态分析环境在线反病毒引擎获取哈希值&#xff08;certutil-hanshfile path MD5&#xff09;查找字符串hive string ida火绒剑加壳&查壳文件加壳使用PEiD检测加壳 导入导出函数获取资源信息 常见的DLL程序恶…

Understand(代码分析工具)的安装与使用教程

前言 虽然自己一直都在CSDN上面学习相关知识和查找需要的各种资源&#xff0c;但或许是因为自己实在不知道自己的博客该写什么内容&#xff0c;于是博客的更新速度一慢再慢&#xff0c;进而停更一年左右&#xff0c;在这一点上&#xff0c;我认为自己应该作出批评与反省。 而…

如何看懂源代码--(分析源代码方法)

我们在写程序时&#xff0c;有不少时间都是在看别人的代码。 例如看小组的代码&#xff0c;看小组整合的守则&#xff0c;若一开始没规划怎么看&#xff0c; 就会“看得想哭 ” 不管是参考也好&#xff0c;从开源抓下来研究也好&#xff0c;为了了解箇中含意&#xff0c;在有限…

一文了解全面静态代码分析

在开发具有安全性、可靠性和合规性的软件时&#xff0c;全面静态代码分析是一种有效的方法。在这里&#xff0c;我们将就静态分析而言&#xff0c;讨论全面静态代码分析的不同之处&#xff0c;阐述全面静态代码分析的重要性&#xff0c;以及如何进行全面静态代码分析。 什么是全…

代码分析工具 - SonarQube

1. 常见代码质量分析工具 SonarQube&#xff1a;可以分析27多种不同编程语言中的代码&#xff0c;并帮助您提高性能和检测安全漏洞。它由SonarSource的团队开发&#xff0c;对社区免费开源。SonarQube可以添加到您的CI/CD管道中&#xff0c;或者与您选择的代码库托管平台集成&a…

《编码 - 代码分析》代码结构分析

1 代码结构分析概述 在编写代码时&#xff0c;要求要结构清晰、接口简单。如果代码结构过于复杂&#xff0c;会带来很多问题&#xff1a;代码很难被理解&#xff0c;不方便编写测试用例&#xff0c;容易隐藏错误&#xff0c;出现问题难以定位&#xff0c;修改代码容易产生新的…

利用宏让ERStudio生成代码文件

Embarcadero ERStudio 是一个数据模型工具&#xff0c;用起来很方便。在ERStudio里建完数据模型后&#xff0c;可以利用宏来帮助生成对应的实体类文件以及对应的简单的数据访问类文件。为了实现这一目的&#xff0c;需要自己写脚本&#xff0c;支持的语言为 VB&#xff08;以前…

Erstudio8.0怎么用?Erstudio8.0汉化版详细使用教程

Erstudio8.0使用教程 打开ERstudio,点击新建出现如图对话框&#xff1a; 选择第一个&#xff0c;表示创建一个新的关系型 数据库模型 这里提一点数据库模型分为relational(关系)和dimensional(多维) 两种在这里主要以关系型数据库为主来介绍模型的创建过程。 第二和第三项均是重…

ERStudio如何显示entity的tableName(表名的英文)和defaultColumnName(英文字段名)

转换为物理模型就可以了 物理模型中会优先显示tableName和defaultColumnName 这个mysql选择自己使用的数据库即可&#xff0c; ** 温馨提示&#xff1a;只想单纯看一下英文名而且不会转物理模型的话可以参考我的这个步骤&#xff0c;专业转化物理模型的话&#xff0c;建议另…

【SpringBoot】4. ERStudio初使用

1. 逻辑结构 &#xff08;1&#xff09;创建文件 &#xff08;2&#xff09;建立实体对象entity &#xff08;3&#xff09;编辑实体对象 &#xff08;4&#xff09;添加属性 &#xff08;5&#xff09;图表显示选项 &#xff08;6&#xff09;实体之间建立联系 &#xff08;7…

如何使用ERStudio 生成comment

在ER使用中&#xff0c;在生成sql过程中&#xff0c;如何批量生成字段描述&#xff0c;如何批量添加Owner&#xff0c;请看下文&#xff1a; 1、ER生成字段描述 2、ER生成描述添加Owner 使用的ER版本是8.0&#xff0c;英文版本&#xff0c;在操作过程中&#xff0c;有些配置细节…

使用ERStudio6创建数据表ER图并导出数据表的SQL(DDL)语句

1.创建数据表实体 打开ERStudio软件&#xff0c;其界面如下&#xff1a; 点击File菜单的NEW或则使用快捷键“CtrlN”着按钮 来新建一个ER图文件&#xff0c;按下OK按钮即可打开一个空白的ER图文件 其后缀是.DM1类型的。新建一个ER文件后&#xff0c;ERStudio的工具栏内的许多按…

ER/Studio知识汇总

一、关系 网上找了一下&#xff0c;大部分说得不太清楚&#xff0c;我在这里举上个例子。注意&#xff0c;这里的关系是逻辑上的&#xff0c;并非表结构也要如此。 1. 标识关系identifying relationship 意思&#xff1a;子实体的主键包含父实体的外键&#xff08;可能成为复合…

【NodeJS】20 koa 企业级Cms内容管理系统-XMind功能分析、ERStudio设计数据库ER图

一、 什么是 CMS CMS 是"Content Management System“的缩写&#xff0c;意为"内容管理系统”。 内容管理系统是企业信息化建设和电子政务的新宠&#xff0c;也是一个相对较新的市场。对于内容管理&#xff0c;业界还没有一个统一的定义&#xff0c;不同的机构有不同…