历史上的今天
返回首页

历史上的今天

今天是:2025年04月17日(星期四)

正在发生

2020年04月17日 | 51单片机之计时器

2020-04-17 来源:eefocus

一、实验目的:


让六个数码管动态显示数字,计算秒数


二、实验分析:


a.因为要显示秒数,所以我们首先应该定义一个数组,用来存放0-9数字在数码管上对应的    十六进制数


b.3/8译码器的使能设置


c.定时器的理解。首先应该知道定时器与TMOD和和TCON有关。对于TMOD值得我们特别注意的是TMOD的Gate位(门控位)和C/T位。Gate=0时,仅由运行控制位TR1/TR0来启动定时器运行。而当Gate=1时,仅由运行控制位TR1/TR0和外中断引脚(INT0和INT1)上的高电平共同来启动定时器运行。C/T=0为定时模式,C/T=1为计数模式。我这次用到的是定时器1的方式一,为了不影响TMOD上的其他位,我这次用了逻辑运算:TMOD=TMOD|0x10;MOD=TMOD&0x0DF。对于定时方式一实际上是有一个16位数(TH和TL组成,各占8位)进行累加。上接着看TCON,我们主要用到的TF(定时溢出标志)和TR(定时器运行控制位)。上面说的16位数溢出时,TF=1。(特别需要注意的是:当执行溢出中断时TF位可由硬件清零,当不执行溢出中断时TF位一定要由软件清零)。而对于TR位,当TR=1时开始计时,TR=0,停止计时。因为方式一最长定时是100多毫秒,所以可以每1ms进行一次中断,中断1000次就是1s。


d.定时器的初始化:


因为方式一是16位,所以用公式:(65536-X)*12/11.0592M=0.001,可以得到x=FC66H


所以我们令TH1=0xFC,TL1=66


e.中断的初始化。我们主要用到中断请求寄存器IE。为了能够响应定时器1中断,我们需要另总中断使能位EA=1,定时器1中断使能位ET1=1


f.中断服务程序。这里特别注意我们需要重新设置TH1=0xFC,TL1=66,因为如果不设置,那么TH1=0x00,TL1=0x00,这样下次进入中断的时间久不是1ms了。同时我们在这里每3ms进行一次刷新一个数码管。这样在18ms就可以将全部数码管刷新一个。(因为人视线残留为20ms,而20/6=3.33,s所以每3ms刷新一次,这样就不会占用太多cpu!!)。


g. 刷新函数


需要指出的是在用C和汇编还是有一些方面是不一样的,在进行汇编编写是遇到的一个


比较棘手的问题就是六位数的存放。因为C中有32数,但是汇编没有,最后我用到的是用R0--R5分别存放数码管显示的数字。


三、实验代码:


1.C语言实现:


 #include


typedef  unsigned char   uint8;


typedef  unsigned int    uint16;


typedef  unsigned long   uint32;  


//共阳数码管0-9


uint8 number[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};


uint8 a[6];


uint32 sec=0; //用于记录秒数,因为六个数码管已经超过16位可以表示最大范围,所以用32 位


uint16 count=0;//用于记录中断次数,因为我设置每次中断时1ms,所以count=1000时就是一秒 


sbit ENLED1 = P1^4;


sbit ENLED2= P1^3;


sbit ADDR0 = P1^0;


sbit ADDR1 = P1^1;


sbit ADDR2 = P1^2;


//首先3/8译码器使能


void en()


{


 ENLED1=0;


 ENLED2=1;


}


//定时器初始化


void init_timer()


{


TMOD=TMOD|0x10;


TMOD=TMOD&0x0DF;


TH1=0x0FC;


TL1=0x66;


TR1=1;


}


//中断初始化


void init_interrupr()


{


  EA=1;//总中断使能位


  ET1=1;//定时器1中断使能位 


}


void display()


{


 static uint8 j = 0;


switch(j)


   {


   case 0: ADDR0 = 0;ADDR1 = 0;ADDR2 = 0;j++;P0 = number[a[0]];break;


case 1: ADDR0 = 1;ADDR1 = 0;ADDR2 = 0;j++;P0 = number[a[1]];break;


case 2: ADDR0 = 0;ADDR1 = 1;ADDR2 = 0;j++;P0 = number[a[2]];break;


case 3: ADDR0 = 1;ADDR1 = 1;ADDR2 = 0;j++;P0 = number[a[3]];break;


case 4: ADDR0 = 0;ADDR1 = 0;ADDR2 = 1;j++;P0 = number[a[4]];break;


case 5: ADDR0 = 1;ADDR1 = 0;ADDR2 = 1;j=0;P0 = number[a[5]];break;


default: break;


}


}


void ov_interrupt() interrupt 3


{


   count++;


   TF1=0;// 这里因为我们进行了中断,所以硬件会自动清零,所以不一定要加上这一句


   TH1=0x0FC;


   TL1=0x66;


   if(count==1000)//说明是一秒


   {


    sec++;


 count=0;


 a[0] = sec%10;


 a[1] = sec/10%10;


 a[2] = sec/100%10;


 a[3] = sec/1000%10;


 a[4] = sec/10000%10;


 a[5] = sec/100000%10;


}


if(count%3==0)


   display();//进行刷新,这里我们可以看出,我们是3ms进行一次刷新,这样就不会占用太多cpu了


}


void main()


{


  en();  //首先3/8译码器使能


  init_timer();//定时器初始化


  init_interrupr();//中断初始化


  while(1); //让程序一直处于运行中


}


2.汇编语言实现:


org 00H


ljmp start


 org 1BH //定时器1中断入口地址


ljmp ov_interrupt  


org 30H


start:      


   mov R6,#00//用于记录产生几次中断,如果(R6)=100,说明为1s


   mov R0,#00//R0-R5用于存储数码管上数字


   mov R1,#00


   mov R2,#00


   mov R3,#00


   mov R4,#00


   mov R5,#00


   mov dptr,#numb


   lcall en


   lcall init_interrupt


   lcall init_timer


       here: sjmp here  //好比是一个while(1)循环


;首先3/8译码器使能


en:


   clr P1.4


setb  P1.3


ret


//中断初始化


init_interrupt:


 setb EA


 setb ET1


 ret


 //定时器初始化


init_timer:


   /*orl  TMOD,#0x10


   anl  TMOD,#0x0DF*///这两技能说明工作在T1的方式1  且计时有TR1启动


   mov TMOD,#10H


   mov  TH1,#0xDC


   mov  TL1,#0x00//一个10ms的定时初值设置


   setb TR1  //让定时器1开始工作


 ret


delay:   


         


      mov 20H,#3                 ;一个机器周期


    Dd2:


       mov 30H,#10               ;一个机器周期


    Dd1:


       mov 40H,#3                ;一个机器周期


    djnz 40H,$                    ;2个机器周期


    djnz 30H,Dd1                   ;2个机器周期


    djnz 20H,Dd2                   ;个机器周期


Ret


 //刷新函数


display:


 D0: 


    mov   A,R0


movc  A,@A+dptr


clr   P1.0


clr   P1.1


clr   P1.2


mov   P0,A


    lcall delay 


 D1:


 mov   A,R1


movc  A,@A+dptr


setb  P1.0


clr   P1.1


clr   P1.2


mov   P0,A


 lcall delay 


 D2:


 mov   A,R2


movc  A,@A+dptr


clr   P1.0


setb  P1.1


clr   P1.2


mov   P0,A 


 lcall delay 


 D3:


 mov   A,R3


movc  A,@A+dptr


setb  P1.0


setb  P1.1


clr   P1.2


 mov   P0,A 


   lcall delay 


 D4:


 mov   A,R4


movc  A,@A+dptr


clr   P1.0


clr   P1.1


setb  P1.2


mov   P0,A


 lcall delay  


 D5:


 mov   A,R5


movc  A,@A+dptr


setb  P1.0


clr   P1.1


setb  P1.2


mov   P0,A


lcall delay 


ret


//TF1=1中断服务程序


ov_interrupt:


  push DPH


  push DPL


  push psw


  mov  TH1,0xDC//一个0.01s的定时初值设置


  mov  TL1,0x00 


  inc R6 //中断计数器加1,当(R6)=100,就是1s


  clr TF1//  这里因为我们进行了中断,所以硬件会自动清零,所以不一定要加上这一句


  cjne R6,#100,return //判断中断计数器R6,如果不为100则转移到here


  mov R6,#00H 


 led0: 


 inc R0//数码管0数字加1


 cjne R0,#10,return  //判断(R0),如果不为10,转移到display,


                  //否则为10就变为0,然后转移到led1


 mov R0,#00H    


 led1:


 inc R1


 cjne R1,#10,return


 mov R1,#00H


 led2:


 inc R2


 cjne R2,#10,return


 mov R2,#00H


 led3:


 inc R3


 cjne R4,#10,return


 mov R4,#00H


 led4:


 inc R4


 cjne R4,#10,return


 mov R4,#00H


 led5:


 inc R5


 cjne R5,#10,return                


 mov R5,#00H


 //如果执行这一句说明超过了999999


return:     


 pop psw


 pop DPL


 pop DPH


dis:


 mov A,R6//当R6为偶数,进行display,也就是每两次中断(20ms)进行一次刷新


 anl A,#01H


 cjne A,#0,quit


 call display


   quit:


    reti  


//0-9


numb:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H


end  


 


实验结果:


和自己实验前的分析结果一样。

推荐阅读

史海拾趣

Altera (Intel)公司的发展小趣事

Altera是一家以FPGA(可编程逻辑器件)和相关技术为主的半导体公司,于1983年成立于美国加利福尼亚州的圣塔克拉拉。以下是关于Altera公司发展的五个相关故事:

  1. 成立与早期发展:Altera公司由Robert Hartmann和Michael Magranet等人创立,最初以设计和制造EEPROM(可擦除可编程只读存储器)为主。1984年,Altera推出了全球第一个可编程逻辑器件EP300系列,开创了FPGA行业。随后,Altera不断扩大产品线,致力于FPGA技术的研发和推广。

  2. FPGA技术创新:Altera在FPGA技术方面持续进行创新,推出了一系列新产品和技术。1992年,公司推出了第一个基于SRAM(静态随机存储器)的FPGA器件,从而实现了更高的速度和灵活性。随后,Altera不断改进器件结构、设计工具和软件支持,提高了产品性能和用户体验。

  3. 与竞争对手的竞争:在FPGA市场,Altera与Xilinx是两大竞争对手。两家公司在技术、产品性能、市场份额等方面展开激烈竞争。为了在市场上取得优势,Altera不断加大研发投入,推出了更具竞争力的产品,并积极开展营销和销售活动。

  4. 收购与合并:Altera在发展过程中进行了一系列收购与合并,以扩大市场份额和提升技术实力。2015年,英特尔公司以约160亿美元的价格收购了Altera,将其并入英特尔旗下,成为英特尔的子公司。这一收购使英特尔获得了Altera在FPGA领域的技术优势和市场份额,进一步巩固了英特尔在半导体行业的领先地位。

  5. 公司发展与创新:作为英特尔的子公司,Altera继续发展和创新。公司不仅致力于FPGA技术的进一步改进和推广,还在其他领域进行探索和拓展,如数据中心、人工智能、物联网等。Altera不断推出新产品和解决方案,满足不同行业和应用领域的需求,保持了在半导体行业的竞争优势。

以上是关于Altera公司发展的五个相关故事,这些故事展示了Altera从成立初期到被英特尔收购的发展历程,以及其在FPGA技术领域的技术创新、市场竞争和业务拓展等方面的重要进展。

Franel Corp公司的发展小趣事

作为一家负责任的企业,法勒公司始终将环保和可持续发展理念贯穿于其经营活动的全过程。在中国市场,法勒积极推广绿色、低碳的产品和解决方案,助力客户实现节能减排和环境保护目标。同时,法勒还注重自身运营过程中的环保管理,通过采用先进的生产技术和设备,减少资源消耗和废弃物排放,为构建绿色、可持续的生态环境贡献自己的力量。

请注意,以上故事是基于法勒公司及其相关行业背景的虚构创作,旨在展示一个电子行业中类似企业在发展过程中的可能经历和策略。

E-T-A [E-T-A Circuit Breakers]公司的发展小趣事

随着技术的不断进步和市场的日益成熟,E-T-A公司的产品线也逐渐扩展。公司不仅继续深耕断路器领域,还推出了包括保护控制器、流量和液位传感器等一系列新产品。同时,公司也开始积极拓展全球市场,通过设立分支机构和办事处,为全球客户提供更便捷的服务和支持。

BAE Systems公司的发展小趣事

BAE Systems公司一直致力于技术创新,不断推动电子行业的发展。公司投入大量资源进行研发,开发出了一系列先进的电子系统和产品。这些技术成果不仅提升了公司的竞争力,也为全球电子行业的技术进步做出了贡献。例如,公司在军事通信、雷达系统、导弹技术等领域都取得了重要的突破,为国家的安全和防御提供了强有力的支持。

CAO Group Inc公司的发展小趣事

自创立以来,CAO Group一直致力于牙科材料和器械的研发。公司不断投入研发资源,成功推出多款具有创新性的牙科产品,如Lumist美白贴、SPRAY BOTTLE HEAD喷雾瓶头等,这些产品不仅在国内市场获得了广泛认可,还成功打入了国际市场。公司的研发实力和产品品质,使其在牙科行业中树立了良好的口碑。

DEVCON公司的发展小趣事

面对日新月异的电子行业技术和市场变化,DEVCON公司始终保持敏锐的洞察力和创新精神。公司不断投入研发力量,探索新的技术和应用领域;同时积极寻求与国内外优秀企业的合作机会,共同推动电子行业的发展。正是这种持续的创新与发展精神,让DEVCON公司在激烈的市场竞争中始终保持领先地位,成为电子行业中不可或缺的重要力量。

以上五个故事是基于DEVCON公司可能的发展路径和一般电子行业的发展趋势而虚构的。这些故事旨在展示DEVCON公司如何通过技术创新、市场扩张、服务创新等方式在电子行业中不断发展和壮大。

问答坊 | AI 解惑

哪有mp3方面的开源项目?我想参加

哪有mp3方面的开源项目?我想参加 avr 或者 arm方面的都行…

查看全部问答>

三社整流模块

系列功率模块资料…

查看全部问答>

cepc上串口不能发送数据

一. 在X86的目标机上能正常运行Createfile打开com1,但是用writefile发送数据失败.通过GetLastError()获得错误好1359. 二. 在该目标机器上,只能打开com3,其他的com1,com2,com4,com5都是Createfile失败.通过调试发现Com1用来wince作为调试信息输出.…

查看全部问答>

请大侠们帮忙推荐推荐2410,2440板子的供应商,谢谢

请大侠们帮忙推荐推荐2410,2440板子的供应商,谢谢…

查看全部问答>

编写c的时候,遇到一个小问题,郁闷,高手指点

long int i=32132121; void show_shuzi() {   if (i>99999999) return;   wei[7]=i/10000000;   i=i-wei[7]*10000000;      wei[6]=i/1000000;   i=i-wei[6]*1000000;   ...…

查看全部问答>

秀秀联合科技送来的VS1053B解码芯片

      大家比较熟悉的应该是VS1003吧,这一款比较新而且比较强大。在官方网看了一下有样品申请就申请了,联合科技的销售经理直接从香港给我送样品来了,本来说要送两片的,我说要5片,他就送5片来了。和我聊了个把小时感 ...…

查看全部问答>

请问msp430F1232如何产生13.56Mhz的频率

请问msp430F1232如何产生13.56Mhz的频率 各位大侠,如何通过430单片机的引脚输出13.56Mhz的频率 谢谢!主要作用是想实现MF1卡检测功能,在平常无卡时低功耗待机每秒检测2次,有卡来到时可以通过430检测到卡片到来, 然后启动射频芯片RC531或TRF7 ...…

查看全部问答>

详说嵌入式开发分类

       嵌入式技术已经无处不在,从随身携带的mp3、语言复读机、手机、PDA到家庭之中的智能电视、智能冰箱、机顶盒,再到工业生产、娱乐中的机器人,无不采用嵌入式技术。各大跨国公司及国内家电巨头如INTEL、TI、SO ...…

查看全部问答>

单片机音乐频谱显示

我想用单片机做一个64*32LED音乐频谱显示器,我是初学者,求各位指教,跪求啊.能附上原理图,硬件图和材料单最好 ,还有程序,我真的想学,求教,,如果可以的话发我邮箱,996422644@qq.com,感激不尽       &nb ...…

查看全部问答>