范例
当前位置:首页 > 其他范文 > 范例 > 列表页

at89s51单片机c语言程序范例

小草范文网  发布于:2016-12-18  分类: 范例 手机版

篇一:AT89S51单片机C语言程序范例

第四章实验及实践课题

1. 闪烁灯

1. 实验任务

如图4.1.1所示:在P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为0.2秒。

2. 电路原理图

图4.1.1

3. 系统板上硬件连线

把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上。

4. 程序设计内容

(1). 延时程序的设计方法

作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:

如图4.1.1所示的石英晶体为12MHz,因此,1个机器周期为1微秒

机器周期

2个 2个 2个 微秒

2 2+2×248=20× 2×248 (498 MOV R6,#20 MOV R7,#248 DJNZ R7,$ D1:

DJNZ R6,D12个2×20=10002

因此,上面的延时程序时间为10.002ms。

由以上可知,当R6=10、R7=248时,延时5ms,R6=20、R7=248时,延时10ms,以此为基本的计时单位。如本实验要求0.2秒=200ms,10ms×R5=200ms,则R5=20,延时子程序如下:

DELAY:

D1:

D2:

MOV R5,#20 MOV R6,#20 MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1

RET

(2). 输出控制

如图1所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平,即P1.0=0时,发光二极管L1亮;我们可以使用SETB P1.0指令使P1.0端口输出高电平,使用CLR P1.0指令使P1.0端口输出低电平。

5.

程序框图 如图4.1.2所示

图4.1.2

6.

START:

DELAY: 汇编源程序 ORG 0 CLR P1.0 LCALL DELAY SETB P1.0 LCALL DELAY LJMP START MOV R5,#20;延时子程序,延时0.2秒

D1:MOV R6,#20

D2:MOV R7,#248

DJNZ R7,$

DJNZ R6,D2

DJNZ R5,D1

RET

END

7. C语言源程序

#include <AT89X51.H>

sbit L1=P1^0;

void delay02s(void) //延时0.2秒子程序

{

unsigned char i,j,k;

for(i=20;i>0;i--)

for(j=20;j>0;j--)

for(k=248;k>0;k--);

}

void main(void)

{

while(1)

{

L1=0;

delay02s();

L1=1;

delay02s();

}

}

2.

1. 实验任务 模拟开关灯

如图4.2.1所示,监视开关K1(接在P3.0端口上),用发光二极管L1(接在单片机P1.0端口上)显示开关状态,如果开关合上,L1亮,开关打开,L1熄灭。

2. 电路原理图

图4.2.1

3. 系统板上硬件连线

区域中的L1端口上; (1). 把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”

(2). 把“单片机系统”区域中的P3.0端口用导线连接到“四路拨动开关”区域中的

K1端口上;

4. 程序设计内容

(1). 开关状态的检测过程

单片机对开关状态的检测相对于单片机来说,是从单片机的P3.0端口输入信号,而输入的信号只有高电平和低电平两种,当拨开开关K1拨上去,即输入高电平,相当开关断开,当拨动开关K1拨下去,即输入低

at89s51单片机c语言程序范例

电平,相当开关闭合。单片机可以采用JB BIT,REL或者是JNB BIT,REL指令来完成对开关状态的检测即可。

(2). 输出控制

如图3所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平,即P1.0=0时,

发光二极管L1亮;我们可以使用SETB P1.0指令使P1.0端口输出高电平,使用CLR P1.0指令使P1.0端口输出低电平。

5. 程序框图

图4.2.2

6. 汇编源程序

START:

LIG:

ORG 00H JB P3.0,LIG CLR P1.0 SJMP START SETB P1.0 SJMP START END

7. C语言源程序

#include <AT89X51.H>

sbit K1=P3^0;

sbit L1=P1^0;

void main(void)

{

while(1)

{

if(K1==0)

{

L1=0;

}

else

{

L1=1;

}

}

} //灯亮 //灯灭

篇二:AT89C51单片机液晶显示程序(c语言编写)

仿真图接线方式

C语言程序

#include<reg51.h>

#include<intrins.h>

sbit rs=P2^0;

sbit rw=P2^1;

sbit ep=P2^2;

unsigned char code dis1[]={""}; unsigned char code dis2[]={"0571-85956028"}; void delay(unsigned char ms)

{

unsigned char i;

while(ms--)

{for(i=0;i<250;i++)

{_nop_(); _nop_();_nop_();_nop_(); }

}

}

bit lcd_bz()

{bit result;

rs=0;

rw=1;

ep=1;

_nop_();

_nop_();

_nop_();

_nop_();

result=(bit)(P0&0x80);ep=0;

return result;

}

void lcd_wcmd(unsigned char cmd) { while(lcd_bz());

rs=0;

rw=0;

ep=0;

_nop_();

_nop_();

P0=cmd;

_nop_();

_nop_();

_nop_();

_nop_();

ep=1;

_nop_();

_nop_();

_nop_();

_nop_();

ep=0;

}

void lcd_pos(unsigned char pos) { lcd_wcmd(pos|0x80); }

void lcd_wdat(unsigned char dat) { while(lcd_bz());

rs=1;

rw=0;

ep=0;

P0=dat;

_nop_();

_nop_();

_nop_();

_nop_();

ep=1;

_nop_();

_nop_();

_nop_();

_nop_();

ep=0;

}

void lcd_init()

{ lcd_wcmd(0x38); delay(1);

lcd_wcmd(0x0c); delay(1);

lcd_wcmd(0x06); delay(1);

lcd_wcmd(0x01); delay(1);

}

void main(void)

{ unsigned char i; lcd_init();

delay(10);

lcd_pos(0x01); i=0;

while(dis1[i]!='\0') {lcd_wdat(dis1[i]);i++;

}

lcd_pos(0x42); i=0;

while(dis2[i]!='\0'){lcd_wdat(dis2[i]); i++;

}

while(1); }

篇三:51单片机汇编语言及C语言经典实例

51单片机汇编语言及C语言经典实例

实验及课程设计

51单片机汇编语言及C语言经典实例

一、闪烁灯

如图1 所示为一简单单片机系统原理图:在 P1.0 端口上接一个发光二极管 L1,使 L1 在不停地一亮一灭,一亮一灭的时间间隔为 0.2 秒。 延时程序的设计方法,作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为 0.2 秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程

序是如何设计呢?下面具体介绍其原理:如图 4.1.1 所示的石英晶体为 12MHz,因此,1 个机器周期为 1 微秒,机器周期 微秒如图 1 所示,当 P1.0 端口输出高电平,即 P1.0=1 时,根据发光二极管的单向导电性可知,这时发光二极管 L1 熄灭;当 P1.0 端口输出低电平,即 P1.0=0 时,发光二极管 L1 亮;我们可以使用 SETB P1.0 指令使 P1.0端口输出高电平,使用 CLR P1.0 指令使 P1.0 端口输出低电平。

C 语言源程序

#include <AT89X51.H> sbit L1=P1^0;

void delay02s(void) //延时 0.2 秒子程序 {

unsigned char i,j,k; for(i=20;i>0;i--) for(j=20;j>0;j--)

for(k=248;k>0;k--); }

void main(void) {

while(1) { L1=0;

delay02s(); L1=1;

delay02s(); }

汇编源程序 ORG 0

START: CLR P1.0 LCALL DELAY SETB P1.0

LCALL DELAY LJMP START

DELAY: MOV R5,#20 ;延时子程序,延时 0.2 秒

D1: MOV R6,#20

D2: MOV R7,#248

DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1

RET 图1 单片机原理图 END

图2 程序设计流程图

二、多路开关状态指示

如图 3 所示,AT89S51 单片机的 P1.0-P1.3 接四个发光二极管 L1-L4,

P1.4-P1.7 接了四个开关 K1-K4,编程将开关的状态反映到发光二极管上。

(开关闭合,对应的灯亮,开关断开,对应的灯灭)。

对于开关状态检测,相对单片机来说,是输入关系,我们可轮流检测每个开关状

态,根据每个开关的状态让相应的发光二极管指示,可以采用 JB P1.X,REL

或 JNB P1.X,REL 指令来完成;也可以一次性检测四路开关状态,然后让其指

示,可以采用 MOV A,P1 指令一次把 P1 端口的状态全部读入,然后取高 4 位的状态来指示。

方法1(汇编源程序) ORG 00H

START: MOV A,P1 ANL A,#0F0H RR A RR A RR A RR A

ORL A,#0F0H MOV P1,A SJMP START END

方法1(C语言程序) #INClude <AT89X51.H> unsigned char temp; 图4 程序流程图

void main(void) {

while(1) {

temp=P1>>4; temp=temp | 0xf0; P1=temp; } }

方法2(汇编源程序) ORG 00H

START: JB P1.4,NEXT1

CLR P1.0 SJMP NEX1 NEXT1: SETB P1.0 图3 单片机原理图 NEX1: JB P1.5,NEXT2 CLR P1.1 SJMP NEX2

NEXT2: SETB P1.1 NEX2: JB P1.6,NEXT3 CLR P1.2 SJMP NEX3

NEXT3: SETB P1.2 NEX3: JB P1.7,NEXT4 CLR P1.3 SJMP NEX4

NEXT4: SETB P1.3 NEX4: SJMP START END

方法2(C 语言源程序) #INClude <AT89X51.H>

void main(void) {

while(1) {

if(P1_4==0) {

P1_0=0; } Else {

P1_0=1; }

if(P1_5==0) {

P1_1=0;

} else {

P1_1=1; }

DJNZ R5,$ DJNZ R4,D1

图6 程序流程图DJNZ R3,DELAY

R RET

T ABLE: DB 0FEH,0FDH,0FBH,0F7H

if(P1_6==0) {

P1_2=0; } else {

P1_2=1; }

if(P1_7==0) {

P1_3=0; } else

图5 单片机原理图三、广告灯的设计

利用取表的方法,使端口左移 2 次,右移 2 次,闪烁 P1 做单一灯的变化:2 次 (延时的时间 0.2 秒)。

利用 MOV DPTR,#DATA16 的指令来使数据指针寄存器指到表的开 头。

利用器的值再加上 MOVC A ,DPTR @A+的DPTR 的指令,根据累加值,就可以使程序计数器 PC 指到表格内所要取出的数据。因此,只要把控制码建成一个表,而利用 MOVC A,@A+DPTR 做取码的操作, 就可方便地处理一些复杂的控制动作,取表过程如下图所示: 汇编源程序 ORG 0

START: MOV DPTR,#TABLE LOOP: CLR A

MOVC A,@A+DPTR CJNE A,#01H,LOOP1 JMP START

LOOP1: MOV P1,A MOV R3,#20 LCALL DELAY INC DPTR JMP LOOP

DELAY: MOV R4,#20 D1: MOV R5,#248

DB 0EFH,0DFH,0BFH,07FH DB 0FEH,0FDH,0FBH,0F7H DB 0EFH,0DFH,0BFH,07FH DB 07FH,0BFH,0DFH,0EFH DB 0F7H,0FBH,0FDH,0FEH DB 07FH,0BFH,0DFH,0EFH DB 0F7H,0FBH,0FDH,0FEH DB 00H, 0FFH,00H, 0FFH DB 01H END

C 语言源程序

#INClude <AT89X51.H> unsigned char code

table[]={0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f, 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x7f,0xbf,0xdf,0xef, 0xf7,0xfb,0xfd,0xfe,0x00,0xff,0x00,0xff,0x01}; unsigned char i; void delay(void) {

unsigned char m,n,s; for(m=20;m>0;m--) for(n=20;n>0;n--) for(s=248;s>0;s--); }

void main(void) {

while(1) {

if(table[i]!=0x01) {

P1=table[i]; i++; delay(); } else { i=0; }

}

}

C 语言源程序

#include <AT89X51.H> unsigned char code

table[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char Second; void delay1s(void) {

unsigned char i,j,k; for(k=100;k>0;k--) for(i=20;i>0;i--) for(j=248;j>0;j--); }

void main(void) {

Second=0;

P0=table[Second/10]; P2=table[Second%10]; while(1) {

delay1s(); Second++; if(Second==60) {

Second=0; }

P0=table[Second/10]; P2=table[Second%10]; } }

四、 00-59 秒计时器

如下图8所示,在 AT89S51 单片机的 P0 和 P2 端口分别接有两个共阴数码管,P0 口驱动显示秒的时间的十位,而 P2 口驱动显示秒的时间的个位。在设计过程中我们用一个存储单元作为秒计数单元,当一秒钟到来时,就让秒计数单元加 1,当秒计数达到 60 时,就自动返回到 0,重新秒计数。

对于秒计数单元中的数据要把它十位数和个位数分开,方法仍采用对 10 整除和对 10 求余。 汇编源程序

Second EQU 30H ORG 0000H

START: MOV Second, #00H NEXT: MOV A, Second MOV B,#10 DIV AB

MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A MOV A,B

MOVC A,@A+DPTR MOV P2,A

LCALL DELY1S INC Second MOV A,Second CJNE A,#60,NEXT LJMP START

图7 程序流程图 DELY1S: MOV R5,#100

D2: MOV R6,#20 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 DJNZ R5,D2 RET

TABLE: DB

3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH END

图8 单片机原理图

本文已影响