单片机c语言编程实例大全

作者&投稿:冉腾 (若有异议请与网页底部的电邮联系)
单片机c语言实例?~

基于MCS-51系列单片机AT89S51的八路抢答器

基于MCS-51系列单片机AT89S51的八路抢答器

前言

随着现代电子电路的快速发展,以及电子行业对现有电子工程技术的不断需求,特别是对实际操作实践的电子人才的需求越来越多,所以加强学生动手能力、重视实践应该是电子发展需求的必然趋向。实践动手能力的培养是一种综合能力,这种能力当然是在一定难度的前提下完成的,通过一定数量的实践才能逐步形成的。因此在培养实践能力的同时,要通过实践来不断的发现问题和解决问题的途径和方法,从而提高实践能力。

近年来,随着单片机档次的不断提高,功能的不断完善,其应用日趋成熟、应用领域日趋扩大,特别是工业测控、尖端武器和日用家电等领域更是因为有了单片机而生辉增色。单片机应用技术已成为一项新的工程应用技术。本次实习设计的题目为基于单片机的抢答器。
在本次的课程设计中我主要负责了该系统的印制电路板PCB的制作

一、方案论证

方案一:系统各部分采用中小规模集成数字电路,用机械开关按钮作为控制开关,完成抢答输入信号的触发。该方案的特点是中小规模集成电路应用技术成熟,性能可靠,能方便地完成选手抢答的基本功能,但是由于系统功能要求较高,所以电路连接集成电路相对较多,而且过于复杂,并且制作过程工序比较烦琐,使用不太方便。
方案二:该系统采用MCS-51系列单片机AT89S51作为控制核心,该系统可以完成运算控制、信号识别以及显示功能的实现。由于用了单片机,使其技术比较成熟,应用起来方便、简单并且单片机周围的辅助电路也比较少,便于控制和实现。整个系统具有极其灵活的可编程性,能方便地对系统进行功能的扩张和更改性。 CS-51单片机特点如下:
1> 可靠性好:单片机按照工业控制要求设计,抵抗工业噪声干扰优于一般的CPU ,程序指令和数据都可以烧写在ROM许多信号通道都在同一芯片,因此可靠性高。
2> 易扩充:单片机有一般电脑所必须的器件,如三态双向总线,串并行的输入及输出引脚,可扩充为各种规模的微电脑系统
3> 控制功能强:单片机指令除了输入输出指令,逻辑判断指令外还有更丰富的条件分支跳跃指令。原理框图如1-1所示;

图1-1
方案比较及其选用依据,显然方案二比方案一简单的多,不但从性能上优于方案一,而且在使用上及其功能的实现上都较方案一简洁,并且由于单片机具有优越的高集成电路性,使其工作速度更快、效率更高。另外AT89S51单片机采用12MHz的晶振,提高了信号的测量精度,并且使该系统可以通过软件改进来扩张功能。而方案一采用了中小规模集成电路,有其复杂的电路性能,从而可能会使信号的输入输出产生延时及不必要的误差。依此依据选择方案二比较适合。

二、原理分析
1. 本电路采用单片机AT89C51作为控制芯片,单片机的P0口外接八个发光二极管,每个发光二极管分别作为八位选手的信号指示灯。并在各个外接电路上并接开关按键,按键另一端接地。发光二极管采用共阳极接法,由于P0口为高电平呈输入状态,当有按键按下时,P0口呈低电平与按键对应的发光二极管满足点亮条件点亮。在程序编程上采用查询,查询P0口P0。0到P0。7的八个端口呈低电平,即查询是哪个选手先按键,然后将选手号码的字节数据送至串行口输出并在数码管上显现出来。
2. 蜂鸣器是利用三极管处于开关状态是的导通与截止工作,在三极管导通时蜂鸣器工作,三极管截止时蜂鸣器不工作。三极管采用8550 PNP型基极接于P1。2口置其低电平时三极管导通,置其高电平时三极管截止。
3. 数码管采用共阳极七段显示,其内部发光二极管为共阳极接高电平,当对应发光二极管一端为低电平时发光二极管点亮,显示的数字或字符由送入的字节数据控制,字节数据的输出采用串形口工作模式0,8位串行字节数据的输出通过RXD端口送出,TXD端用于送出同步移位脉冲,作为外接器件的同步移位信号。数据的发送是在TI=0的情况下,由一写发送缓冲器的指令开始CPU执行完该指令,串行口即将8位数据从RXD端送出,同时TXD端发出同步移位脉冲。8位数据发送完毕后由硬件置位TI=1,通过查询TI位来确定是否发送完一组数据,TI=1表示发送缓冲器已空,当要发送下一组数据时用软件使TI清零,然后即可发送下一组数据。
4. 软件设计分析首先在程序的开始为选手设置了一段违规程序,该程序的作用是为了防止选手在主持人没有按下抢答键时,有的选手已经提前抢答了,本次抢答为无效抢答,并有报警和记录下该位选手的选号,做违规处理,如果选手超出了在规定的提前抢答次数,则该选手将被取消以后的抢答资格。如果在主持按下抢答键时再抢答,该次抢答被视为有效抢答,在主持按下回答问题的键时选手就可以在规定的时间内回答问题了

图1-2
选手查询程序:
ORG 0000H
START:CLR A
MOV A,#0FFH
MOV P0,A
LOP:JNB P2。4,LP
JNB P0。0,SA1
JNB P0。1,SA2
JNB P0。2,SA3
JNB P0。3,SA4
JNB P0。4,SA5
JNB P0。5,SA6
JNB P0。6,SA7
JNB P0。7,SA8
SJMP LOP
SA1:AJMP SB1
SA2:AJMP SB2
SA3:AJMP SB3
SA4:AJMP SB4
SA5:AJMP SB5
SA6:AJMP SB6
SA7:AJMP SB7
SA8:AJMP SB8
LP:MOV R0,#9
LOP1:LCALL LED
LCALL DEL
JNB P0。0,SIP1
JNB P0。1,SIP2
JNB P0。2,SIP3
JNB P0。3,SIP4
JNB P0。4,SIP5
JNB P0。5,SIP6
JNB P0。6,SIP7
JNB P0。7,SIP8
DEC R0
CJNE R0,#0,LOP1
MOV R0,#0
LCALL LED
LCALL DEL
SJMP LOP
SIP1:AJMP DIP1
SIP2:AJMP DIP2
SIP3:AJMP DIP3
SIP4:AJMP DIP4
SIP5:AJMP DIP5
SIP6:AJMP DIP6
SIP7:AJMP DIP7
SIP8:AJMP DIP8
SB1:MOV R2,#1
LCALL LED1
LCALL DE
SJMP LP1
SB2:MOV R2,#2
LCALL LED1
LCALL DE
SJMP LP1
SB3:MOV R2,#3
LCALL LED1
LCALL DE
SJMP LP1
SB4:MOV R2,#4
LCALL LED1
LCALL DE
SJMP LP1
SB5:MOV R2,#5
LCALL LED1
LCALL DE
SJMP LP1
SB6:MOV R2,#6
LCALL LED1

LCALL DE
SJMP LP1
SB7:MOV R2,#7
LCALL LED1
LCALL DE
SJMP LP1
SB8:MOV R2,#8
LCALL LED1
LCALL DE
SJMP LP1
LP1:JNB P2。4,LOP2
SJMP LP1
DIP1:MOV R2,#1
LCALL LED1
LCALL DE
SJMP LH1
DIP2:MOV R2,#2
LCALL LED1
LCALL DE
SJMP LH1
DIP3:MOV R2,#3
LCALL LED1
LCALL DE
SJMP LH1
DIP4:MOV R2,#4
LCALL LED1
LCALL DE
SJMP LH1
DIP5:MOV R2,#5
LCALL LED1
LCALL DE
SJMP LH1
DIP6:MOV R2,#6
LCALL LED1
LCALL DE
SJMP LH1
DIP7:MOV R2,#7
LCALL LED1
LCALL DE
SJMP LH1
DIP8:MOV R2,#8
LCALL LED1
LCALL DE
SJMP LH1
LH1:JNB P2。4,LOOP
SJMP LH1
LOP2:MOV A,#11H
MOV SBUF,A
JNB TI,$
CLR TI
LCALL DEL
AJMP LOP

串行输出程序:
该部分程序的设计利用了单片机的串行模式0输出,该输出方式占用IO口少。可以省去许多IO口作为功能的扩展使用。在该模式下,我们采用了输出查询的方式,就是要借助发送标志TI,当程序执行到发送标志位时,查询其标志位TI的值,只要TI的值是0程序就继续查询,知道查询到TI为1时才结束,然后在进入下一组数据的发送。由于串行输出时送进去的数都是十进制数,以致计算机不能识别,所以还要把送进去的十进制数转化成而进制数,这样才能输出。因此在输出程序前必须有拆字程序,把原来送进去的十进制数转化成二进制数,然后在输出并通过数码管显示出来。但是如果在显示选手选号与显示选手回答问题所用的到计同用一段串行输出程序时就会造成程序的混乱,所以在此处设计了两段初始值不同的显示程序,从而可能增加了程序的烦琐化。

LED1:MOV A,R2
MOV B,#10
DIV AB
MOV R1,A
MOV R3,B
MOV A,R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
MOV A,R3
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
RET。
LED:MOV A,R0
MOV B,#10
DIV AB
MOV R1,A
MOV R3,B
MOV A,R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
MOV A,R3
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
RET
DE:CLR P1。2
LCALL DEL01
SETB P1。2
LCALL DEL01
RET
TAB:DB 11H,0D7H,32H,92H,0D4H,98H,18H,0D3H,10H,90H
RET
END
倒计时程序
该程序为选手回答问题时的30秒倒计时程序,其中前25秒为正常的倒计时,在后5秒倒计时时伴随有报警声,用于提示选手回答问题的剩余时间。如果该选手在正常的倒计时内没有完成问题的回答,那么倒计时将被清零。

LOOP:MOV R0,#30
LPP:LCALL LED
LCALL DEL
JNB P2。4,LOP2
DEC R0
CJNE R0,#5,LPP
MOV R0,#5
LPP1:JNB P2。4,LOP2
LCALL LED
LCALL DE
DEC R0
CJNE R0,#0,LPP1
MOV R0,#0
LCALL LED
LCALL DEL
LJMP START
延时程序
该系统设计了两段延时程序,一段1秒延时,是为了30秒倒计时调用和程序中一秒延时所用;另一段为0。5秒延时,用于报警。程序的设计中报警时间为一秒,但是由于在硬件的设计时只设计了一个按键,这样就会造成连续按键时会使所设定的报警声不断的响,这是设计中不允许的,所以在软件编程时设计了一个0。5秒的延时,被报警时所调用,这样就使报警声能很清楚地区分出来了

DEL:MOV R6,#20 DEL01:MOV R6,#10
DEL1:MOV R5,#100 DEL11:MOV R5,#100
DEL2:MOV R4,#250 DEL21:MOV R4,#250
DJNZ R4,$ DJNZ R4,$
DJNZ R5,DEL2 DJNZ R5,DEL21
DJNZ R6,DEL1 DJNZ R6,DEL11
RET RET

报警程序
该段程序主要是用于本系统中的所有报警使用,报警时间延时为1秒钟。
DE:CLR P1。2
LCALL DEL01
SETB P1。2
LCALL DEL01
RET

三、制作过程

五、参考文献

曾峰,巩海洪,曾波,电子工业出版社,印刷电路板(PCB)设计与制作 2005.8
梅海凤,王艳秋,张军,汪毓铎,清华大学出版社 单片机原理与接口技术 2004.2
北京交通大学出版社


第二个文献:基于51单片机八路抢答器设计程序及电路图
基于51单片机八路抢答器设计程序及电路图
说明:本人的这个设计改进后解决了前一个版本中1号抢答优先的问题,并增加了锦囊的设置,当参赛选手在回答问题时要求使用锦囊,则主持人按下抢答开始键,计时重新开始。
;八路抢答器电路请看下图是用ps仿真的,已经测试成功

;============================================================
;================单片机八路抢答器程序 =====================
;================ 51hei =======================
;================ 2008 年 5月 =======================
;============================================================
OK EQU 20H;抢答开始标志位
RING EQU 22H;响铃标志位
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP INT0SUB
ORG 000BH
AJMP T0INT
ORG 0013H
AJMP INT1SUB
ORG 001BH
AJMP T1INT
ORG 0040H
MAIN: MOV R1,#30;初设抢答时间为30s
MOV R2,#60;初设答题时间为60s
MOV TMOD,#11H;设置未定时器/模式1
MOV TH0,#0F0H
MOV TL0,#0FFH;越高发声频率越高,越尖
MOV TH1,#3CH
MOV TL1,#0B0H;50ms为一次溢出中断
SETB EA
SETB ET0
SETB ET1
SETB EX0
SETB EX1;允许四个中断,T0/T1/INT0/INT1
CLR OK
CLR RING
SETB TR1
SETB TR0;一开始就运行定时器,以开始显示FFF.如果想重新计数,重置TH1/TL1就可以了
;=====查询程序=====
START: MOV R5,#0BH
MOV R4,#0BH
MOV R3,#0BH
ACALL DISPLAY;未开始抢答时候显示FFF
JB P3.0,NEXT;ddddddd
ACALL DELAY
JB P3.0,NEXT;去抖动,如果"开始键"按下就向下执行,否者跳到非法抢答查询
ACALL BARK;按键发声
MOV A,R1
MOV R6,A;送R1->R6,因为R1中保存了抢答时间
SETB OK;抢答标志位,用于COUNT只程序中判断是否查询抢答
MOV R7,#01H ;读抢答键数据信号标志,这里表示只读一次有用信号
MOV R3,#0AH;抢答只显示计时,灭号数
AJMP COUNT;进入倒计时程序,"查询有效抢答的程序"在COUNT里面
NEXT: JNB P1.0,FALSE1
JNB P1.1,FALSE2
JNB P1.2,FALSE3
JNB P1.3,FALSE4
JNB P1.4,FALSE5
JNB P1.5,FALSE6
JNB P1.6,FALSE7
JNB P1.7,FALSE8
AJMP START
;=====非法抢答处理程序=====
FALSE1: MOV R3,#01H
AJMP ERROR
FALSE2: MOV R3,#02H
AJMP ERROR
FALSE3: MOV R3,#03H
AJMP ERROR
FALSE4: MOV R3,#04H
AJMP ERROR
FALSE5: MOV R3,#05H
AJMP ERROR
FALSE6: MOV R3,#06H
AJMP ERROR
FALSE7: MOV R3,#07H
AJMP ERROR
FALSE8: MOV R3,#08H
AJMP ERROR

;=====INT0(抢答时间R1调整程序)=====
INT0SUB:MOV A,R1
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL DISPLAY;先在两个时间LED上显示R1
JNB P3.4,INC0;P3.4为+1s键,如按下跳到INCO
JNB P3.5,DEC0;P3.5为-1s键,如按下跳到DECO
JNB P3.1,BACK0;P3.1为确定键,如按下跳到BACKO
AJMP INT0SUB
INC0: MOV A,R1
CJNE A,#63H,ADD0;如果不是99,R2加1,如果加到99,R1就置0,重新加起。
MOV R1,#00H
ACALL DELAY1
AJMP INT0SUB
ADD0: INC R1
ACALL DELAY1
AJMP INT0SUB
DEC0: MOV A,R1
JZ SETR1;如果R1为0, R1就置99,
DEC R1
ACALL DELAY1
AJMP INT0SUB
SETR1: MOV R1,#63H
ACALL DELAY1
AJMP INT0SUB
BACK0: RETI
;=====INT1(回答时间R2调整程序)=====
INT1SUB:MOV A,R2
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL DISPLAY
JNB P3.4,INC1
JNB P3.5,DEC1
JNB P3.1,BACK1
AJMP INT1SUB
INC1: MOV A,R2
CJNE A,#63H,ADD1
MOV R2,#00H
ACALL DELAY1
AJMP INT1SUB
ADD1: INC R2
ACALL DELAY1
AJMP INT1SUB
DEC1: MOV A,R2
JZ SETR2
DEC R2
ACALL DELAY1
AJMP INT1SUB
SETR2: MOV R2,#63H
ACALL DELAY1
AJMP INT1SUB
BACK1: RETI
;=====倒计时程序(抢答倒计时和回答倒计时都跳到改程序)=====
REPEAT:MOV A,R2 ;使用锦囊时重新计时
MOV R6,A
CLR RING
COUNT: MOV R0,#00H;重置定时器中断次数
MOV TH1,#3CH
MOV TL1,#0B0H;重置定时器
RECOUNT:MOV A,R6;R6保存了倒计时的时间,之前先将抢答时间或回答时间给R6
MOV B,#0AH
DIV AB;除十分出个位/十位
MOV 30H,A;十位存于(30H)
MOV 31H,B;个位存于(31H)
MOV R5,30H;取十位
MOV R4,31H;取个位
MOV A,R6
SUBB A,#07H
JNC LARGER;大于5s跳到LARGER,小于等于5s会提醒
MOV A,R0
CJNE A,#0AH,FULL;1s中0.5s向下运行
CLR RING
AJMP CHECK
FULL: CJNE A,#14H,CHECK;下面是1s的情况,响并显示号数并清R0,重新计
SETB RING
MOV A,R6
JZ QUIT;计时完毕
MOV R0,#00H
DEC R6;一秒标志减1
AJMP CHECK
LARGER: MOV A,R0
CJNE A,#14H,CHECK;如果1s向下运行,否者跳到查"停/显示"
DEC R6;计时一秒R6自动减1
MOV R0,#00H
CHECK: JNB P3.1,QUIT;如按下停止键退出
JNB OK,CHECKK ;只在回答倒计时才有效
AJMP NEXTT
CHECKK:JNB P3.0,REPEAT ;判断是否使用锦囊
NEXTT: ACALL DISPLAY
JB OK,ACCOUT;如果是抢答倒计时,如是则查询抢答,否者跳过查询继续倒数(这里起到锁抢答作用)
AJMP RECOUNT
ACCOUT:
MOV A,36H
JNB ACC.0,TRUE1
JNB ACC.1,TRUE2
JNB ACC.2,TRUE3
JNB ACC.3,TRUE4
JNB ACC.4,TRUE5
JNB ACC.5,TRUE6
JNB ACC.6,TZ1
JNB ACC.7,TZ2
AJMP RECOUNT
TZ1:JMP TRUE7
TZ2:JMP TRUE8
QUIT: CLR OK;如果按下了"停止键"执行的程序
CLR RING
AJMP START
;=====正常抢答处理程序=====
TRUE1: ACALL BARK
MOV A,R2
MOV R6,A;抢答时间R2送R6
MOV R3,#01H
CLR OK;因为答题的计时不再查询抢答,所以就锁了抢答
AJMP COUNT
TRUE2:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#02H
CLR OK
AJMP COUNT
TRUE3:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#03H
CLR OK
AJMP COUNT
TRUE4:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#04H
CLR OK
AJMP COUNT
TRUE5:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#05H
CLR OK
AJMP COUNT
TRUE6: ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#06H
CLR OK
AJMP COUNT
TRUE7:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#07H
CLR OK
AJMP COUNT
TRUE8:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#08H
CLR OK
AJMP COUNT
;=====犯规抢答程序=====
ERROR: MOV R0,#00H
MOV TH1,#3CH
MOV TL1,#0B0H
MOV 34H,R3;犯规号数暂存与(34H)
HERE: MOV A,R0
CJNE A,#06H,FLASH;0.3s向下运行->灭并停响
CLR RING
MOV R3,#0AH
MOV R4,#0AH
MOV R5,#0AH;三灯全灭
AJMP CHECK1
FLASH: CJNE A,#0CH,CHECK1;下面是0.8s的情况,响并显示号数并清R0,重新计
SETB RING
MOV R0,#00H
MOV R3,34H;取回号数
MOV R5,#0BH
MOV R4,#0BH;显示FF和号数
AJMP CHECK1
CHECK1: JNB P3.1,QUIT1
ACALL DISPLAY
AJMP HERE
QUIT1: CLR RING
CLR OK
AJMP START
;=====显示程序=====
DISPLAY:MOV DPTR,#DAT1;查表显示程序,利用P0口做段选码口输出/P2低三位做位选码输出,
MOV A,R3
MOVC A,@A+DPTR
MOV P2,#0feH
MOV P0,A
ACALL DELAY2
MOV DPTR,#DAT2
MOV A,R5
MOVC A,@A+DPTR
MOV P2,#0fdH
MOV P0,A
ACALL DELAY2
MOV A,R4
MOVC A,@A+DPTR
MOV P2,#0fbH
MOV P0,A
ACALL DELAY2
RET
DAT1:DB 00h,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,00H,71H
;"灭","1","2","3","4","5","6","7","8","9","灭","F"
DAT2:DB 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,00H,71H
;第一个为零,其他与上相同,因为十位如果为零显示熄灭
;====加减时间延时(起到不会按下就加N个数)======
DELAY1: MOV 35H,#08H
LOOP0: ACALL DISPLAY
DJNZ 35H,LOOP0
RET
;=====延时4236个机器周期(去抖动用到)=====
DELAY: MOV 32H,#12H
LOOP: MOV 33H,#0AFH
LOOP1: DJNZ 33H,LOOP1
DJNZ 32H,LOOP
RET
;=====延时4236个机器周期(显示用到)=====
DELAY2: MOV 32H,#43H
LOOP3: MOV 33H,#1EH
MOV A,R7 ;每隔60~70个机器周期读一次P1口,全为1时为无效数据,继续读,有一个不为1时,转到正常抢答处理
JNZ AAAA1 ;没读到有效数据时继续转到AAAA1
LOOP2: DJNZ 33H,LOOP2
DJNZ 32H,LOOP3
RET
;=====读抢答按键数据口程序=====
;由于在读抢答数据口的时候,单片机首先进入倒计时程序,再调用显示程序,最后才检测按键口
;然而在检测按键口时动态扫描要调用三次(4ms)延时程序.这样就会导致读数据口出现滞后,造成1号优先最高.8号最低.
;故采用在延时子程序中加了读数据口程序.保证了灵敏度和可靠性
AAAA1: MOV A,P1
CJNE A,#0FFH,AA1 ;当不全为1时的数据为有效数据
AA0: MOV 36H,A ;将有效数据送到36H暂存
AJMP LOOP2
AA1: DEC R7
AJMP AA0

;=====发声程序=====
BARK: SETB RING
ACALL DELAY1
ACALL DELAY1
CLR RING;按键发声
RET
;=====TO溢出中断(响铃程序)=====
T0INT: MOV TH0,#0ECH
MOV TL0,#0FFH
JNB RING,OUT;
CPL P3.6;RING标志位为1时候P3.6口不短取反使喇叭发出一定频率的声音
OUT: RETI
;=====T1溢出中断(计时程序)=====
T1INT: MOV TH1,#3CH
MOV TL1,#0B0H
INC R0
RETI
END



仅供参考。

// 51单片机C语言编程,这个时钟+秒表可以参考一下。

#include
#define uchar unsigned char
#define uint unsigned int
sbit qingling=P1^0; //清零
sbit tiaofen=P1^1; //调分
sbit tiaoshi=P1^2; //调时
sbit sounder=P1^7; //naozhong
uint a,b;
uchar hour,minu,sec, //时钟
hour0,minu0,sec0,//秒表
hour1,minu1,sec1;
h1,h2,m1,m2,s1,s2,//显示位
k,s;//状态转换标志
uchar code select[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar code table[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/*****************函数声明***********************/
void keyscan();
void init();
void delay(uchar z);
void display(uchar,uchar,uchar);
void sounde();
/*****************主函数*************************/
void main()
{
init();
while(1)
{
while(TR1)
{
keyscan(); //扫描函数
while(s==1) //s是状态标志,当s=0时,闹钟取消。s=1时,设定闹钟时间(也是通过调时,调分函数);
{ //s=2时,闹钟工作,时间与设定时刻一致时,闹钟响(一分钟后自动关闭,可手动关闭)。再次切换,s=0.
keyscan(); //s状态切换(0-》1-》2-》0)通过外部中断1实现。
display(hour1,minu1,sec1); //闹钟时刻显示
}
display(hour0,minu0,sec0);//时钟表显示
while(k) /*k是秒表状态(0-》1-》2-》0)通过外部中断0实现。0秒表关;1秒表从零计时;2秒表停,显示计时时间*/
{
display(hour,minu,sec); //秒表显示
}
}
}
}
/*****************初始化函数***********************/
void init()
{
a=0;
b=0;
k=0;
s=0;
hour0=0;
minu0=0;
sec0=0;
hour=0;
minu=0;
sec=0;
hour1=0;
minu1=0;
sec1=0;
TMOD=0x11; //定时器0,1工作于方式1;赋初值
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
EX0=1; //秒表中断
EX1=1; //闹钟设定中断
ET0=1;
ET1=1;
IT0=1; //边沿触发方式
IT1=1;
PX0=1;
PX1=1;
TR0=0; //初始,秒表不工作
TR1=1; //时钟一开始工作
}
/*****************定时器0中断*************/
void timer0_int() interrupt 1 //秒表
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
a++;
if(a==2)
{
a=0;
sec++;
if(sec==100)
{
sec=0; //毫秒级
minu++;
if(minu==60)
{
minu=0; //秒
hour++;
if(hour==60) //分
{
hour=0;
}
}
}
}
}
/*************外部中断0中断函数************/
void ex0_int() interrupt 0
{
k++;
if(k==3)
k=0;
if(k==1)
{
TR0=~TR0;
if(TR0==1)
{
hour=0;
minu=0;
sec=0;
}
}
if(k==2)
{
TR0=~TR0;
}
}
/*************外部中断1中断函数************/
void ex1_int() interrupt 2
{
s++;
if(s==3)
s=0;
}
/*************定时器1中断****************/
void timer1_int() interrupt 3 //控制时钟工作
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(s==2)
{
if(hour1==hour0 && minu0==minu1)
sounde();
}
b++;
if(b==20)
{
b=0;
sec0++;
if(sec0==60)
{
sec0=0;
minu0++;
if(minu0==60)
{
minu0=0;
hour0++;
if(hour0==24)
hour0=0;
}
}
}
}
/*************键盘扫描****************/
void keyscan()
{
if(s==1)
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec1=0;
minu1=0;
hour1=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu1++;
if(minu1==60)
{
minu1=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour1++;
if(hour1==24)
{
hour1=0;
}
while(!tiaoshi);
}
}
else //调整时钟时间
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec0=0;
minu0=0;
hour0=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu0++;
if(minu0==60)
{
minu0=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour0++;
if(hour0==24)
{
hour0=0;
}
while(!tiaoshi);
}
}
}
/*************显示函数****************/
void display(uchar hour,uchar minu,uchar sec)
{
h1=hour/10;
h2=hour%10;
m1=minu/10;
m2=minu%10;
s1=sec/10;
s2=sec%10;
P0=0xff;
P2=table[h1];
P0=select[7];
delay(5);
P0=0xff;
P2=table[h2];
P0=select[6];
delay(5);
P0=0xff;
P2=0x40;;
P0=select[5];
delay(5);
P0=0xff;
P2=table[m1];
P0=select[4];
delay(5);
P0=0xff;
P2=table[m2];
P0=select[3];
delay(5);
P0=0xff;
P2=0x40;
P0=select[2];
delay(5);
P0=0xff;
P2=table[s1];
P0=select[1];
delay(5);
P0=0xff;
P2=table[s2];
P0=select[0];
delay(5);
}
/*************闹钟函数****************/
void sounde()
{
sounder=~sounder;
}
/*************延时函数****************/
void delay(uchar z)
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}


各位大侠30岁想学STM32编程来的及吗
来得及呀,如果你学过51单 片机,或者会C语言 学习STM32单 片机并不难,但主要是静下心来,仔细看视频和文字教程,多编程,多实验 最好心中先有个目标,想用STM32单片机来干什么,整个机器人、 整个MP3 、 或者整个手机?开始都不知道怎么下手,但学到一定程度,你发现有可能实现,某一方面有...

《单片机C语言程序设计实训100例——基于8051+Proteus仿真》 第03...
单片机c语言编程100个实例目录1 函数的使用和熟悉 实例3:用单片机控制第一个灯亮 实例4:用单片机控制一个灯闪烁:认识单片机的工作频率 实例5:将 P1口状态分别送入P0、P2、P3口:认识I\/O口的引脚功能 实例6:使用P3口流水点亮8位LED 实例7:通过对P3口地址的操作流水点亮8位LED 实例8:用不同...

51单片机及其C语言程序开发实例的目录
上篇 单片机设计基础第1章 绪论第2章 51单片机基础知识第3章 51单片机C程序设计基础第4章 单片机系统资源扩展第5章 51单片机的最小系统中篇 基于51单片机的模块设计第6章 键盘和数码管第7章 液晶显示模块第8章 A\/D转换器第9章 D\/A转换器第10章 I2C总线接口设计第11章 语音IC及应用第...

c语言中的switch语句,使用时应注意哪些?
c语言中的switch语句,使用时应注意哪些? Switch语句编程规范总结: 【规则1】每个case 语句的结尾不要...1、用 abstract 来修饰一个类,那么这个类就是抽象类;抽象类绝对不能被实例化,即$abc = new 抽象...3、制砂机起动前,先用手转动转子,检查一下齿爪、锤片及转子运转是否灵活可靠,壳内有无碰撞现象,转子...

C语言编写STC12C5A60S2芯片用4个按键控制四个灯的亮灭
include“reg52.h”#include“delay.h”\/\/ 定义按键 KEY_0~KEY_6 对应P1^0~P1^6sbit KEY_0 = P1^0;sbit KEY_1 = P1^1;sbit KEY_4 = P1^4;sbit KEY_5 = P1^5;sbit KEY_6 = P1^6;\/\/ 定义LED _7~LED_3 对应P2^7~P2^3sbit LED_7 = P2^7;sbit LED_ 6= P2^6;sbit...

用C语言编写一个在八个数码管上轮流显示1-8的程序
我这个程序是在PROTUES仿真上做的 你可以根据程序自己画电路图 很简单的 这里用到了两片74HC573 芯片 显示0---F#include<reg51.h>#include<intrins.h>...更多关于c语言的知识 > 正在求助 换一换 回答问题,赢新手礼包 苦等1分钟: 防胀气奶瓶哪个牌子好,最值得入手的防胀气奶瓶介绍 回答 苦等15分钟: ...

冰箱 微波炉 电话机 内的程序也是通过编程语言写出来的吗?
这些电器内部的控制新片都是单片机芯片,程序是由相应的编程语言写的,按照芯片不同,编程语言不同,主要是由相对应的汇编和c语言进行编程的如8051系列单片机,arm系列,等

请问8位与32位的单片机在编程上有什么不同,需要注意些什么!
用C语言编程的话,没什么不同 不管是8位的32位的,硬件结构不同,功能也会相差很大,主要区别就 体现在特殊功能寄存器上,用 C语言操作单片机,可以不进行内存管理,但离不开对特殊功能寄存器的操作 即使都是8位单 片机,特殊功能寄存器也相差很大 至于通用的数学运算,利用C语言的库函数,编程时认为...

小弟想学习编程不知道看什么书
编程,要有激情,要有想象力,不局限于书本上的知识点,大胆实验,尝试把已经学习的话知识点组合成新的知识点,就拿C语言的链表来说,几乎所有的C语言入门书都把链表作为单独的一个知识点,如果说所有的书都取消链表这个知识点,当你学完指针、结构体、再告诉你malloc函数的用法,你能想到可以组合成链表这有趣的知识点么...

Linux C语言网络编程问题!
unsigned int dir(char * server) { int sck;\/\/套接字变量 struct sockaddr_in serv_adr; \/\/远程主机的地址 struct hostent *host; \/\/指向远程主机的指针 unsigned char databuf[FILEBUF_SIZE]; \/\/数据 int bytes = 0, bytesread = 0; \/\/字节数,读取到的字节数 host = gethostbyname...

开阳县18844143650: 单片机C语言程序设计实训100例 -- 基于AVR+PROTEUS仿真 -
慈种麦特: 他给你的源程序告诉你用什么运行环境了么!我用的是AVRstudio6.0.打开一个文件的时候,有一个选择单片机的型号.在那里面选中你所用的单片机.之后打开扩展名为.C的文件!如果你的时项目文件,那就直接打开那个项目就可以了!编译之后生成的.hex文件,,用PROTEUS加载就可以进行仿真了!

开阳县18844143650: 单片机C语言程序设计实训100例的介绍 -
慈种麦特: 本书为北京航空航天大学出版社出版,作者为彭伟.本书基于AVR Studio+WinAVR(GCC)组合环境和Proteus硬件仿真平台,精心安排了100个AVR单片机C程序设计案例.全书提供了所有寨例完整的C语言源程序,各案例设计了难易适中的实训目标.本书适合用作大专院校学生学匀实践AVR单片机C语言程序设计技术的参考书,也可用作电子工程技术人员、单片机技术爱好者的学习参考书.

开阳县18844143650: 51单片机用C语言编写
慈种麦特: #include<reg51.h> sbit a = P1^2; //定义单片机对蜂鸣器的输出端口 sbit key = P3^2; //定义单片机对按键的端口 S19 void delay_short() //短延时函数 大约100us 用于设置蜂鸣器的频率 { unsigned int i; for(i=0;i<100;i++); } void delay_long() ...

开阳县18844143650: 单片机C语言程序
慈种麦特:用两组循环: while(1) { for(a=0;a<3;a++) { ; } for(a=0;a<3;a++) { ; } } //注意左右移如果LED不这,要把P0,P2口的数据赋值给变量后再送输出口. #include<reg51.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int void ...

开阳县18844143650: 常用的用C语言编写的单片机应用程序有哪些啊,希望知道的朋友告诉我一下,谢啦
慈种麦特: 常用的?多了去了,从最简单的流水灯开始、然后是数码管的静态和动态显示、蜂鸣器、键盘(单个按键还有矩阵键盘)、LCD的显示(1602字符型液晶和点阵图形式液晶12864,还有12232等)、红外、步进电机、继电器、串口等.芯片有DS1302、DS18B20、DAC0832、ADC0809、AT24C02、ULN2003等.程序就多了,随便应用这些东西就是一个程序了.

开阳县18844143650: 基于51单片机的c语言程序 -
慈种麦特: #include <reg51.h> void delayms(unsigned char ms) { unsigned int i; i=1200; while(ms--) { while(i--) ; } } void main() { if(KEY1) LED1=1; else LED1=0;// if(!KEY2) { delayms(10); if(!KEY2) { LED2=!LED2; } while(!KEY2 ) ; } }

开阳县18844143650: 下面的用C语言编写的单片机程序 -
慈种麦特: #include<reg51.h>#include<intrins.h> sbit K1=P2^0; void delayms(unsigned int x) {unsigned int t; for(x;x>0;x--) for(t=3000;t>0;t--); } void main() { unsigned int j; j = 0x01; while(1) { P0 = j; while(K1 == 1); delayms(38); if(K1 == 0) {while(K1 == 0); j = _crol_(j, 1); } } }试试看.

开阳县18844143650: 单片机编程(C语言)
慈种麦特: P2口是8位口吧, 十六进制FE是 1111 1110. P2=0XFE的意思就是把信号1111 1110(1为高电平,0为低电平)送到P2口.P2口外接LED 后LCD灯可以点亮.

开阳县18844143650: 用C语言编写单片机程序 -
慈种麦特: #include sbit csb_SAT= P1^0; //定义超声波发生脚 void delay(void) //延时25微秒,12T芯片用12M误差 0us { unsigned char a; for(a=11;a>0;a--); } void csb_fs(int dat) {while(dat--){csb_SAT=1;delay();csb_SAT=0;delay();}} //发射 void main() { ...

开阳县18844143650: c语言程序设计实例 -
慈种麦特: 给你一个,我自己编的: #include "stdio.h" int _judge(int x) {if(x%400==0)return(1);else if(x%4==0&&x%100!=0)return(1);else return(0); }int _fun(int year,int month,int day) {int i,sum=0,a[12]={31,29,31,30,31,30,31,31,30,31,30,31};if(_...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网