PROTUES单片机实验

更新时间:2024-03-29 19:35:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

按钮控制LED——51单片机的Proteus

实验

实验原理

51单片机的一个I/O口接按钮,再通过另一个I/O口控制LED的亮、灭。

主要器件以及电路图

单片机——AT89C51,上拉电阻——pullup,按钮button,发光二极管——LED。

按钮控制LED汇编程序源码

ORG 0 START: MOV P1,#0

;LED不亮

MOV P0,#0FFH ;P0口准备读数 ST1: JB P0.0,$ JNB P0.0,$

;等待按钮抬起 ;等待按钮按下

;以上两句使得只有按一下按钮才可能执行下面的语句 CPL P1.0 SJMP ST1 END

;LED状态改变 ;返回

流水灯——51单片机的Proteus实验

实验原理

通过个51单片机的一个I/O口送不同的数字,实现8个LED的流水灯。本实验为移动一个不亮的LED。通过修改送给I/O口送的数字可以实现不同方式的流水灯。

主要器件以及电路图

单片机——AT89C51,8排电阻——RX8,发光二极管——LED。

流水灯汇编程序源码

org 0

start:

delay:

sjmp start org 30h mov P1,#1 mov P1,#2 mov P1,#4 mov P1,#8 mov P1,#10h mov P1,#20h mov P1,#40h mov P1,#80h sjmp start nop nop nop nop ret end

;P1.0为1,不亮 ;P1.1为1,不亮 ;以下原理同上

数码显示管——51单片机的Proteus实

实验原理

51单片机的一个I/O口接4个开关,再通过另一个I/O口控制7段数码显示管显示想要的数字。

主要器件以及电路图

单片机——AT89C51,共地的7段数码显示管——7SEG-COM-AN-GRN,开关——SW-SPST。

汇编程序源码

汇编后139字节。

org 0 sjmp START org 30h

START: mov P1,#0FFh st1: mov P2,#0FFh mov A,P2 anl A,#0Fh acall SEG7 mov P1,A

;LED不亮

;准备读数(开关状态) ;读数

;取低四位

;调用显示码子程序

;将得到的显示码送数显管显示

SEG7: ret

sjmp st1 inc A

movc A,@A+pc

;循环

;该子程序实现将数字转换为显示码

DB 0c0h,0F9h,0a4h,0b0h DB 99h,92h,82h,0F8h DB 80h,90h,88h,83h DB 0c6h,0a1h,86h,8eh end

C语言程序源码

用C语言写了一下实现同样功能的程序,编译后1.39K,代码如下:

#include int main(){ P1 = 0xff; while(1){ P2 = 0xff; ACC = P2; ACC &= 0xf; switch(ACC){ case 0: P1 = 0xc0; break; case 1: P1 = 0xf9; break; case 2: P1 = 0xa4; break; case 3: P1 = 0xb0; break; case 4: P1 = 0x99; break; case 5: P1 = 0x92; break; case 6: P1 = 0x82; break; case 7: P1 = 0xf8; break; case 8: P1 = 0x80; break; case 9: P1 = 0x90; break; case 10: P1 = 0x88; break; case 11: P1 = 0x83; break; case 12: P1 = 0xc6; break; case 13: P1 = 0xa1; break; case 14: P1 = 0x86; break; case 15: P1 = 0x8e; break; } }

}

while(1);

用数组实现,更大(1.51K),代码如下:

#include int main(){ int ledNum[16] =

{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; P1 = 0xff; while(1){ P2 = 0xff; ACC = P2; ACC &= 0xf; P1 = ledNum[ACC]; } while(1); }

蜂鸣器——51单片机的Proteus实验

实验原理

51单片机的一个I/O口接7个按钮,再通过另一个I/O口控制蜂鸣器发出声音。

主要器件以及电路图

单片机——AT89C51,蜂鸣器——speaker,按钮button。

汇编程序源码

晶振12M,已在Proteus下测试,听起来声音差不多。

ORG 0 SJMP START DLY: MOV R2,#20 ;延时程序 D1: MOV R3,#248 DJNZ R3,$ DJNZ R2,D1 RET ORG 30H START: MOV TMOD,#1 ;定时器0方式1 MOV P3,#0FFH ;P3准备读数 JNB P3.0,DODO ACALL DLY JNB P3.1,RERE ACALL DLY JNB P3.2,MIMI

ACALL DLY JNB P3.3,FAFA ACALL DLY JNB P3.4,SOSO ACALL DLY JNB P3.5,LALA ACALL DLY JNB P3.6,XIXI ACALL DLY JNB P3.7,DO2DO2 ACALL DLY SJMP START DODO: LJMP DO RERE: LJMP RE MIMI: LJMP MI FAFA: LJMP FA SOSO: LJMP SO LALA: LJMP LA XIXI: LJMP XI DO2DO2: LJMP DO2 DO: MOV TH0,#0FBH MOV TL0,#44H SETB TR0 JNB TF0,$ CLR TF0 CPL P2.7 JNB P3.0,DO CLR TF0 SJMP START RE: MOV TH0,#0FBH MOV TL0,#88H SETB TR0 JNB TF0,$

;开启定时器

;等待定时到 ;清除中断 ;喇叭

MI: FA: SO: LA:

CLR TF0 CPL P2.7 JNB P3.1,RE CLR TF0 SJMP START MOV TH0,#0FBH MOV TL0,#0CCH SETB TR0 JNB TF0,$ CLR TF0 CPL P2.7 JNB P3.2,MI CLR TF0 SJMP START MOV TH0,#0FCH MOV TL0,#00H SETB TR0 JNB TF0,$ CLR TF0 CPL P2.7 JNB P3.3,FA CLR TF0 LJMP START MOV TH0,#0FCH MOV TL0,#44H SETB TR0 JNB TF0,$ CLR TF0 CPL P2.7 JNB P3.4,SO CLR TF0 LJMP START MOV TH0,#0FCH MOV TL0,#88H SETB TR0 JNB TF0,$ CLR TF0 CPL P2.7 JNB P3.5,LA

XI:

DO2:

CLR TF0 LJMP START MOV TH0,#0FCH MOV TL0,#0CCH SETB TR0 JNB TF0,$ CLR TF0 CPL P2.7 JNB P3.6,XI CLR TF0 LJMP START MOV TH0,#0FDH MOV TL0,#00H SETB TR0 JNB TF0,$ CLR TF0 CPL P2.7

JNB P3.7,DO2 CLR TF0 LJMP START END

附上蜂鸣器发声的简单程序

1.汇编

ORG 0

START: CPL P2.7 ;蜂鸣器 LCALL DELAY LJMP START DELAY: MOV R7,#0FFH DJNZ R7, $ RET END 2.C语言

#include

void delay(unsigned int z);//声明延时函数 sbit beep=P2^7; void main()数 { while(1){ beep=0;//蜂鸣器响 delay(1);//调用1ms延时 beep=1;//蜂鸣器不响 delay(1);//调用1ms延时 } }

void delay(unsigned int z)//1ms延时,通过z值改变延时 { unsigned int x; for(;z>0;z--) for(x=110;x>0;x--); }

蜂鸣器演奏祝你平安——51单片机的

Proteus实验

实验原理

51单片机的一个I/O口控制speaker发声,演唱祝你平安歌曲。

主要器件以及电路图

单片机——AT89C51,蜂鸣器——speaker。

汇编程序源码

晶振12M,已在Proteus下测试,好像有点失真。程序是从网上照的,感觉不是很对劲,删除了一部分之后还是没有变化。部分注释是我后加上去的。

;------------------------------------ ; 蜂鸣器演奏--祝你平安

; 功能:蜂鸣器-蜂鸣器奏乐-祝你平安 ;------------------------------------ SPK bit P2.7 ;以后SPK就是speaker了 ORG 0000H LJMP START ORG 000BH INC 20H ;T0中断服务,中断计数器加1 MOV TH0,#0D8H

MOV TL0,#0EFH ;12M晶振,形成10毫秒中断 RETI START:

MOV TH0,#0D8H MOV TL0,#0EFH MOV TMOD,#01H MOV IE,#82H ;10000010B——开T0中断 MUSIC0: NOP

MOV DPTR,#DAT ;表头地址送DPTR MOV 20H,#00H ;中断计数器清0 MUSIC1: NOP

CLR A MOVC A,@A+DPTR ;查表取代码 JZ END0 ;是00H,则结束 CJNE A,#0FFH,MUSIC5 ;只要A不等于FF,一直执行MUSIC5 LJMP MUSIC3 ;当A到FF的时候,执行MUSIC3 MUSIC5: NOP

MOV R6,A ;代码送R6 INC DPTR

MOVC A,@A+DPTR ;取节拍代码送R7 MOV R7,A SETB TR0 ;启动计数 MUSIC2: NOP

CPL SPK MOV A,R6 ;按R6(代码)延时 MOV R3,A ; LCALL DEL ;利用代码(R6)来调用延时 CJNE A,20H,MUSIC2 ;中断计数器(20H)=R7否?不等,则继续循环

MOV 20H,#00H ;等于,则取下一代码 INC DPTR LJMP MUSIC1 MUSIC3: NOP

CLR TR0 ;休止100毫秒 MOV R2,#0DH MUSIC4: NOP

MOV R3,#0FFH LCALL DEL

DJNZ R2,MUSIC4 INC DPTR LJMP MUSIC1 END0:

NOP

MOV R2,#64H ;歌曲结束,延时1秒后继续 MUSIC6:

MOV R3,#00H LCALL DEL

DJNZ R2,MUSIC6 LJMP MUSIC0 DEL: ;DEL子程序利用R3来延时一定时

间 NOP DEL3:

MOV R4,#02H DEL4:

NOP

DJNZ R4,DEL4 NOP

DJNZ R3,DEL3 RET NOP

DAT: ;祝你平安

db 26h,20h,20h,20h,20h,20h,26h,10h,20h,10h,20h,80h,26h,20h,30h,20h db 30h,20h,39h,10h,30h,10h,30h,80h,26h,20h,20h,20h,20h,20h,1ch,20h db 20h,80h,2bh,20h,26h,20h,20h,20h,2bh,10h,26h,10h,2bh,80h,26h,20h db 30h,20h,30h,20h,39h,10h,26h,10h,26h,60h,40h,10h,39h,10h,26h,20h db 30h,20h,30h,20h,39h,10h,26h,10h,26h,80h,26h,20h,2bh,10h,2bh,10h db 2bh,20h,30h,10h,39h,10h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,20h db 20h,10h,20h,10h,2bh,10h,26h,30h,30h,80h,18h,20h,18h,20h,26h,20h db 20h,20h,20h,40h,26h,20h,2bh,20h,30h,20h,30h,20h,1ch,20h,20h,20h db 20h,80h,1ch,20h,1ch,20h,1ch,20h,30h,20h,30h,60h,39h,10h,30h,10h db 20h,20h,2bh,10h,26h,10h,2bh,10h,26h,10h,26h,10h,2bh,10h,2bh,80h db 18h,20h,18h,20h,26h,20h,20h,20h,20h,60h,26h,10h,2bh,20h,30h,20h db 30h,20h,1ch,20h,20h,20h,20h,80h,26h,20h,30h,10h,30h,10h,30h,20h db 39h,20h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,10h,40h,10h,20h,10h db 20h,10h,2bh,10h,26h,30h,30h,80h,00H END ;程序结束

蜂鸣器演奏兰花草——51单片机的

Proteus实验

实验原理

51单片机的一个I/O口控制speaker发声,演奏兰花草。

主要器件以及电路图

单片机——AT89C51,蜂鸣器——speaker。

汇编程序源码

SPK EQU P2.7 ORG 0 LJMP START ORG 0030H 存放 START:

MOV R3,#00H NEXT:

MOV A,R3

MOV DPTR,#TABLE MOVC A,@A+DPTR JZ START MOV R7,A INC R3 MOV A,R3 MOVC A,@A+DPTR MOV R2,A ACALL SONG INC R3 SJMP NEXT ;歌曲播放子程序 SONG:

MOV A,R2 RL A JNZ KEEP

;位定义

;伪指令,指定程序从0030H开始

;R3清零(作为查表偏移)

;查表

;如果A是0就重来

;R7是查表的来的代码字节 ;读下一个代码字节

;取出节拍 ;左移节拍

;如果节拍为0就让它等于1

MOV A,#01H KEEP:

MOV R2,A REPEAT:

ACALL EIGHTH DJNZ R2,REPEAT RET

;产生1/8拍延时子程序 EIGHTH:

MOV A,R7 ;查表取出廷时参数,保存到R4 MOV DPTR,#DELAY_T MOVC A,@A+DPTR MOV R4,A MOV A,R7 ;查表取出1/8拍周期数,保存到R5

MOV DPTR,#S_PARA MOVC A,@A+DPTR MOV R5,A NEXTCYC:

ACALL SOUND

DJNZ R5,NEXTCYC RET

;=== 发声子程序 === SOUND:

SETB SPK

ACALL SDELAY CLR SPK

ACALL SDELAY RET ;延时子程序 SDELAY:

MOV A,R4 ; 廷时值在R4内 MOV R0,A XL2:

MOV R1,#03H DL1:

NOP

DJNZ R1,DL1 DJNZ R0,XL2 RET ;1/8拍周期表 S_PARA: DS 1DH

DB 15H,16H,00

DB 19H,00H,1CH,00H,1FH,21H,00H,25H DB 00H,29H,2CH,00H,31H,34H,37H,00H DB 3EH,41H,00H,49H,00H,52H,57H,00H DB 62H

;延时参数表 DELAY_T: DS 1DH

DB 7EH,77H,00H

DB 6AH,00H,5EH,00H,54H,4FH,00H,46H DB 00H,3FH,3BH,00H,35H,32H,2FH,00H DB 2AH,27H,00H,23H,00H,1FH,1DH,0C0H DB 1AH ;歌曲表 TABLE:

DW 2202H,2902H,2902H,2902H,2906H,2702H ;我从山中来 DW 2502H,2702H,2502H,2402H,2208H ;带着兰花草

DW 2E02H,2E02H,2E02H,2E02H,2E06H,2C02H ;种在小园中 DW 2902H,2C02H,2D02H,2A02H,2908H ;祈祷花开早

DW 2902H,2E02H,2E02H,2C02H,2906H,2702H ;一日看三回 DW 2502H,2702H,2502H,2402H,2206H,1D02H ;看得花时过 DW 1D02H,2502H,2502H,2402H,2206H,2902H ;兰花却依然 DW 2702H,2502H,2402H,2002H,2208H ;苞也无一个 DW 0000H END

蜂鸣器演奏老鼠爱大米——51单片机的

Proteus实验

实验原理

51单片机的一个I/O口控制speaker发声,演奏老鼠爱大米。

主要器件以及电路图

单片机——AT89C51,蜂鸣器——speaker。

C语言程序源码

C语言的程序代码更好读一些,相比较前面两个汇编的蜂鸣器程序,这个程序比较好理解。

/* 蜂鸣器--蜂鸣器奏乐-老鼠爱大米*/ #include

#define uint unsigned int #define uchar unsigned char #define ulong unsigned long sbit beep=P2^7; //蜂鸣器输出引脚

uchar th0_f; //中断装载T0高8位 uchar tl0_f; //T0低8位

uchar code freq[36*2]={ //音阶码表 0xf7,0xd8, //440hz , 1 //0 0xf8,0x50, //466hz , 1# //1 0xf8,0xbc, //494hz , 2 //2

0xf9,0x26, //524hz , 2# //3 0xf9,0x85, //554hz , 3 //4 0xf9,0xe5, //588hz , 4 //5 0xfa,0x3d, //622hz , 4# //6 0xfa,0x92, //660hz , 5 //7 0xfa,0xdd, //698hz , 5# //8 0xfb,0x29, //740hz , 6 //9 0xfb,0x70, //784hz , 6# //10 0xfb,0xb0, //830hz , 7 //11 0xfb,0xef, //880hz , 1 //12 0xfc,0x29, //932hz , 1# //13 0xfc,0x62, //988hz , 2 //14 0xfc,0x95, //1046hz, 2# //15 0xfc,0xc7, //1108hz, 3 //16 0xfc,0xf5, //1174hz, 4 //17 0xfd,0x20, //1244hz, 4# //18 0xfd,0x4c, //1318hz, 5 //19 0xfd,0x72, //1396hz, 5# //20 0xfd,0x97, //1480hz, 6 //21 0xfd,0xbb, //1568hz, 6# //22 0xfd,0xdc, //1662hz, 7 //23 0xfd,0xfb, //1769hz, `1 //24 0xfe,0x18, //1864hz, `1# //25 0xfe,0x34, //1976hz, `2 //26 0xfe,0x4e, //2092hz, `2# //27

0xfe,0x67, //2218hz, `3 //28 0xfe,0x7d, //2350hz, `4 //29 0xfe,0x94, //2488hz, `4# //30 0xfe,0xa8, //2639hz, `5 //31 0xfe,0xbc, //2794hz, `5# //32 0xfe,0xcf, //2960hz, `6 //33 0xfe,0xe0, //3136hz, `6# //34 0xfe,0xf1, //3322hz, `7 //35 };

uchar code diaodata[30]={ //音调代码 0x10,0x0e,0x0c,0x10,0x0e,0x0c, 0x10,0x0e,0x10,0x0c,0x10,0x15, 0x13,0x10,0x13,0x15,0x15,0x13, 0x15,0x13,0x10,0x0e,0x0c,0x0e, 0x0e,0x10,0x0e,0x0c,0x0e,0x00};

uchar code jiedata[30]={ //音长代码 0x04,0x04,0x08,0x06,0x02,0x08, 0x04,0x04,0x04,0x04,0x02,0x06, 0x08,0x02,0x02,0x04,0x04,0x04, 0x04,0x08,0x02,0x02,0x04,0x04, 0x02,0x02,0x04,0x04,0x0c,0x00};

void timer0() interrupt 1 //用于产生音符的T0中断服务程序

{

TH0=th0_f; TL0=tl0_f;

beep=~beep; //取反beep引脚,发声 }

void main(void) {

uchar i,j,k=0; uint n;

TMOD=0X01; //T0方式1 TR0=0; //关闭T0(不发声) ET0=1; //允许T0中断 EA=1; //允许总中断 while(1) {

TR0=1; //开T0

for(i=0;diaodata[i]!=0;i++) {

th0_f=freq[diaodata[i]*2]; tl0_f=freq[diaodata[i]*2+1]; for(j=0;j<20000;n++); TR0=0;

for(n=0;n<256;n++); //音符之间的短暂延时 TR0=1;

//(jiedata*20000)

} TR0=0; } }

ADC0808模数转换——51单片机的

Proteus实验

实验原理

51单片机的一个I/O口接ADC0808获得电压经过模数转换后的数据,再通过另一个I/O口控制数码管显示得到的数字。

主要器件以及电路图

单片机——AT89C51,ADC0808,数码显示管*4——7SEG-MPX4-CA-BLUE。

汇编程序源码

org 0

ljmp START org 100H START: mov DPTR,#0FE00H mov P2,0 LOOP: clr P3.4 ;关闭LED1 clr P3.5 ;关闭LED2 clr P3.6 ;关闭LED3 setb P2.0 ;开启0808 mov R6,#0FFH ;等待转换 djnz R6,$ clr P2.0 setb p2.1 ;给0808读信号 movx A,@DPTR ;读

SEG7: DB DB DLY: D1:

nop

clr p2.1 mov B,#100 div AB

lcall SEG7 setb P3.4 clr P3.5 clr P3.6 mov P1,A lcall DLY mov A,B mov B,#10 div AB

lcall SEG7 clr P3.4 clr P3.6 setb P3.5 mov P1,A lcall DLY mov A,B lcall SEG7 clr P3.4 clr P3.5 setb P3.6 mov P1,A lcall DLY sjmp LOOP

;清除0808读信号

;取数字段码 ;开LED1 ;关LED2 ;关LED3 ;送数

;关LED1 ;关LED3

;关LED1 ;关LED3

inc A

movc A,@A+PC RET

0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H 80H,90h,88H,83H,0C6H,0A1H,86h,8EH mov R7,#2 mov R6,#249 DJNZ R6,$ DJNZ R7,D1 RET END

开关控制流水灯2——51单片机的

Proteus实验

实验原理

51单片机的一个I/O口接四个开关,每个开关控制流水灯的不同方面,再通过另一个I/O口控制8个LED的亮、灭,从而实现流水灯。

其中:开关一控制流水灯是否有翻转;开关二控制流动方向;开关三控制是否改变数字;开关四控制流动时间。

主要器件以及电路图

单片机——AT89C51,发光二极管——LED。

C语言程序源码

#include

typedef unsigned int uint;

sbit P0_0 = P0^0; sbit P0_1 = P0^1; sbit P0_2 = P0^2; sbit P0_3 = P0^3; uint delayT = 10000; void delay(){ int i; for(i=0;i

int main(){ int i; uint leds[8] = {254,253,251,247,239,223,191,127};//只有一个灯亮 while(1){ P0 = 0xff; //是否取反 if(P0_0 == 0){ for(i=0;i<8;i++){ leds[i] = -leds[i]; } } if(P0_2 == 0){ //控制是否数字加一 for(i=0;i<8;i++){ leds[i] = leds[i] + 1; } } if(P0_1 == 1){ //下面的循环正常循环 for(i=0;i<8;i++){ P1 = leds[i]; delay(); } } if(P0_1 == 0){ //反循环 for(i=7;i>=0;i--){ P1 = leds[i]; delay(); } }

}

}

if(P0_3 == 1){ //控制流动时间 delayT = 60000; }

else{ delayT = 10000; }

8951+1602显示字符——51单片机的

Proteus实验

本文转载自小波电子工作室。

C语言源程序

//******** 小波电子工作室 All rights reserved****** //******** 个人主页:http://hi.http://www.wodefanwen.com//niejinbo ** //******** 文 件 名: lcd_0712.c ************** //******** 功能概要: LCD液晶显示字符 *********** //******** MCU: STC89C52 晶振:11.0592Mhz *********** //******** 设 计 者: 聂金波 ************ //******** 完成日期: 2008-07-12 ************ //******** 当前版本: 0712_1 ************ //******** 改进说明: 暂无 ************ //**********头文件区************ #include #include #include #include

//*********宏定义方便使用******* #define uchar unsigned char #define uint unsigned int

//*********定义变量区*********** sbit dula=P2^6; //数码管段选 sbit wela=P2^7; //数码管位选

sbit lcden=P3^4; //LCD使能信号

sbit lcdrs=P3^5; //LCD数据/命令选择信号 uchar code tab_nie[]=\

uchar code tab_index[]=\www.niejinbo.cn\

//*********函数声明区*********** void lcd_dis(); //lcd显示函数 void lcd_init(); //LCD初始化函数 void write_com(uchar); //写命令函数 void write_data(uchar); //写数据函数 void delay(uint); //延时函数

//*********主函数开始***********

void main() {

lcd_dis(); while(1); }

//*********lcd显示函数开始****** void lcd_dis() {

uchar n; lcd_init(); write_com(1);

write_com(0x80+4); //设置光标位置 for(n=0;n<9;n++) {

write_data(tab_nie[n]); delay(2);

}

write_com(0x80+0x40); // 设置光标位置 for(n=0;n<15;n++) {

write_data(tab_index[n]); delay(2); } }

//*********LCD初始化函数开始**** void lcd_init() {

dula=0;

wela=0; // 关闭数码管显示

lcden=0;

write_com(0x38); //设置显示模式:16X2,5X7,8位数据接口

write_com(0x0f); //开显示,显示光标,光标闪烁

write_com(0x06); //读写一个字符后,地址指针及光标加一,且光标加一整屏显示不移动 write_com(0x80); //设置光标指针 }

//*********写命令函数开始******* void write_com(uchar com) {

lcdrs=0; //低电平写命令 P0=com; //写入命令 delay(3); //延时约3ms lcden=1; //LCD使能端置高电平 delay(5); //延时约5ms lcden=0; //LCD使能端拉低电平 }

//*********写数据函数开始******* void write_data(uchar dat) {

lcdrs=1; //低电平写数据 P0=dat; //写入命令 delay(3); //延时约3ms lcden=1; //LCD使能端置高电平 delay(5); //延时约5ms lcden=0; //LCD使能端拉低电平 }

//*********延时函数开始********* void delay(uint k) {

uint i,j;

for(i=k;i>0;i--) for(j=110;j>0;j--); }

Proteus 仿真图

LCD1602显示程序头文件——51单片

机的Proteus实验

本文转载自小波电子工作室。

C语言源代码

/*

*************************************************************************************

摘 要: LCD1602显示程序头文件,到时在主程序里包含这个头文件后, 就可以直接调用里面的函数了 版 本: V1.0 完成日期: 2008.5.5 作 者: ZHOUSFE

*************************************************************************************

修改日期:

版 本:

************************************************************************************* */

#i nclude \

#define uchar unsigned char

#define uint unsigned int #define Port P0 //数据端口

/*定义端口*********************************************************/ sbit Rs = P1^0; sbit Rw = P1^1; sbit En = P1^2;

/*定义LCD控制字*****************************************************/ //清屏及光标归位

#define LCD_CLEAR 0x01 // 清屏

#define LCD_HOMING 0x02 // 光标返回左上角 //显示开关控制指令

#define LCD_SCREEN_ON 0x0C //显示开 #define LCD_SCREEN_OFF 0x08 //显示关 #define LCD_CURSOR_ON 0x0A //显示光标 #define LCD_CURSOR_OFF 0x08 //无光标 #define LCD_C_FLASH_ON 0x09 //光标闪动 #define LCD_C_FLASH_OFF 0x08 //光标不闪动 //进入模式设置指令

#define LCD_AC_UP 0x06 //新数据后光标右移 #define LCD_AC_DOWN 0x04 //新数据后光标左移 #define LCD_S_MOVE_ON 0x05 // 画面可平移

#define LCD_S_MOVE_OFF 0x04 //画面不可平移 //设定显示屏或光标移动方向指令

#define LCD_C_LEFT 0x10 //光标左移1格,且AC值减1 #define LCD_C_RIGHT 0x11 //光标右移1格,且AC值加1

#define LCD_CHAR_LEFT 0x18 //显示器上字符全部左移一格,但光标不动 #define LCD_CHAR_RIGHT 0x1C //显示器上字符全部右移一格,但光标不动

uchar code number[10]={\

/*所有函数声明*********************************************************/ void LCD_init(void);

void LCD_wdata(uchar wdata);

void LCD_wcommand(uchar lcd_cmd,busy_f); void LCD_gotoxy(uchar x,uchar y); void Disp_char(uchar *str);

void Disp_number(unsigned int num); uchar Rstatus(void); uchar LCD_rdata(void);

/*

******************************************************************** 函数名称:LCD_wcommand()

功能描述:LCD写指令

入口参数:uchar lcd_cmd:命令字,uchar busy_f:忙检测标志位 返回值:无

******************************************************************** */

void LCD_wcommand(uchar lcd_cmd,busy_f) {

if (busy_f) Rstatus(); //不忙才执行下个程序 Port = lcd_cmd; Rs = 0; Rw = 0; En = 0; En = 0; En = 1;

}

/********************************************************************* 函数名称:LCD_wdata() 功能描述:LCD写数据

入口参数:uchar wdata:所写数据

返回值:无

*********************************************************************/ void LCD_wdata(uchar wdata) {

Rstatus(); Port = wdata; Rs = 1; Rw = 0;

En = 0; //若晶振速度太高可以在这后加小的延时 En = 0; //延时 En = 1;

}

/********************************************************************* 函数名称:LCD_rdata() 功能描述:LCD读数据 入口参数:无

返回值:所读数据

*********************************************************************/ uchar LCD_rdata(void) { Rs = 1; Rw = 1; En = 0; En = 0; En = 1;

return Port;

}

/********************************************************************* 函数名称:Rstatus() 功能描述:LCD读忙状态

入口参数:无

返回值:若忙,则等待,不忙则返回Port

*********************************************************************/ uchar Rstatus(void) {

Port = 0xFF; Rs = 0; Rw = 1; En = 0; En = 0; En = 1;

while (Port & 0x80); //检测忙信号,不忙则退出等待 return(Port); }

/********************************************************************* 函数名称:LCD_init()

功能描述:LCD初始化 入口参数:无 返回值:无

*********************************************************************/ void LCD_init(void) {

Port = 0;

LCD_wcommand(0x38,0); //三次显示模式设置,不检测忙信号 delay_ms(3);

LCD_wcommand(0x38,0); delay_ms(3);

LCD_wcommand(0x38,0); delay_ms(3);

LCD_wcommand(0x38,1); //显示模式设置(0X38双行(5*7),0X34单行(5*10)),0X30单行(5*7);开始要求

每次检测忙信号

LCD_wcommand(0x08,1); //关闭显示 LCD_wcommand(0x01,1); //显示清屏

LCD_wcommand(0x06,1); // 显示光标移动设置 LCD_wcommand(0x0C,1); // 显示开及光标设置 }

/********************************************************************* 函数名称:LCD_gotoxy()

功能描述:定位到(x,y)位置

入口参数:x为行(0~1),y为列(0~15) 返回值:无

*********************************************************************/ void LCD_gotoxy(uchar x, uchar y) {

x &= 0x1; //限制x不能大于1,y不能大于15 y &= 0xF;

if(!x) LCD_wcommand(0x80|y,1); else LCD_wcommand(0xC0|y,1); }

/********************************************************************* 函数名称:Disp_char()

功能描述:显示字符或字符串 入口参数:字符或字符串 返回值:无

**********************************************************************/ void Disp_char(uchar *str) {

while(*str!='\\0') {

LCD_wdata(*str); str++; } }

/********************************************************************* 函数名称:Disp_number()

功能描述:显示四数字

入口参数:num:显示的数字 n:数字位数 返回值:无

************************************************************************/ void Disp_number(uint num,uchar n) {

uchar a; //个位 uchar b; //十位 uchar c; //百位 uchar d; //千位 // uchar e; //万位 switch(n)

{

case 1:LCD_wdata(num); break;

case 2:b=num/10; a=num;

LCD_wdata(number[a]); LCD_wdata(number[b]); break;

case 3:c=num/100; b=num0/10;

a=num;

LCD_wdata(number[a]); LCD_wdata(number[b]); LCD_wdata(number[c]); break;

case 4:d=num/1000; c=num00/100; b=num000/10; a=num;

LCD_wdata(number[a]); LCD_wdata(number[b]); LCD_wdata(number[c]); LCD_wdata(number[d]); break; }

8951+1602数字钟——51单片机的

Proteus实验

本文转载自小波电子工作室。

C语言源代码

//******** 小波电子工作室 All rights reserved****** //******** 个人主页:http://hi.http://www.wodefanwen.com//niejinbo** //******** 文 件 名: lcd_0712_1.c ************ //******** 功能概要: LCD液晶显示时间 *********** //******** MCU: STC89C52 晶振:11.0592Mhz *********** //******** 设 计 者: 聂金波 ************

//******** 完成日期: 2008-07-12 ************ //******** 当前版本: 0712_2 ************

//******** 改进说明: 增加调时、报时、闹钟 *******

//**********头文件区************ #include #include

#include #include

//*********宏定义方便使用******* #define uchar unsigned char #define uint unsigned int

//*********定义变量区*********** sbit dula=P2^6; //数码管段选 sbit wela=P2^7; //数码管位选

sbit lcden=P3^4; //LCD使能信号

sbit lcdrs=P3^5; //LCD数据/命令选择信号

//uchar code tab_nie[]=%uchar code tab_index[]=\www.niejinbo.cn\//uchar tab_num[]={0,1,2,3,4,5,6,7,8,9};

uchar tab_time[]={0,0,10,0,0,10,0,0}; //装时间转换数据 uchar code tab_char[]=%uchar code tab_chartime[]=\

uchar count,hour=22,minu=58,sec=26; //*********函数声明区*********** void lcd_dis(); //lcd显示函数 void lcd_init(); //LCD初始化函数 void write_com(uchar); //写命令函数 void write_data(uchar); //写数据函数 void delay(uint); //延时函数 void trans(); //时间转换函数 void write_char(); //写字符串函数 void int_time0(); //定时器0中断函数 void time(); //计时函数

//*********主函数开始*********** void main()

{

TMOD=0x01; //定时器0方式1 EA=1; ET0=1;

TH0=0xb8; //20ms初值,11.0592MHZ TL0=0X00; TR0=1;

write_com(1); lcd_init(); while(1) {

time(); trans(); lcd_dis(); } }

void int_time0() interrupt 1 {

TMOD=0x01; //定时器0方式1 EA=1; ET0=1; TH0=0xb8;

TL0=0X00; ////20ms初值,11.0592MHZ TR0=1; count++; }

void time() {

if(count>=50) //20ms*50=1s {

count=0; sec++; if(sec>=60) { sec=0; minu++; if(minu>=60) {

minu=0; hour++;

if(hour>=24) {

hour=0; } } } } }

//*********时间转换函数开始***** void trans() {

tab_time[0]=hour/10; tab_time[1]=hour; tab_time[3]=minu/10; tab_time[4]=minu; tab_time[6]=sec/10; tab_time[7]=sec; }

//*********lcd显示函数开始****** void lcd_dis() { uchar m;

write_com(0x80+1); //设置光标位置 for(m=0;m<5;m++) //显示\{

write_data(tab_chartime[m]); delay(2); }

write_char(); //显示时间

write_com(0x80+0x40); //设置光标位置为第二行 for(m=0;m<15;m++) //显示\www.niejinbo.cn\{

write_data(tab_index[m]); delay(2); } }

//*********LCD初始化函数开始**** void lcd_init() {

dula=0;

wela=0; // 关闭数码管显示 lcden=0;

write_com(0x38); //设置显示模式:16X2,5X7,8位数据接口 write_com(0x0c); //开显示,显示光标,光标闪烁

write_com(0x06); //读写一个字符后,地址指针及光标加一,且光标加一整屏显示不移动 write_com(0x80); //设置光标指针 }

//*********写字符串函数开始***** void write_char() {

uchar n,a;

for(n=0;n<8;n++)

{

a=tab_time[n]; //分别取时分秒十个位数字 write_data(tab_char[a]); //显示对应数字符号 } }

//*********写命令函数开始******* void write_com(uchar com) {

lcdrs=0; //低电平写命令 P0=com; //写入命令 delay(3); //延时约3ms lcden=1; //LCD使能端置高电平 delay(5); //延时约5ms

lcden=0; //LCD使能端拉低电平 }

//*********写数据函数开始******* void write_data(uchar dat) {

lcdrs=1; //低电平写数据 P0=dat; //写入命令

delay(3); //延时约3ms

lcden=1; //LCD使能端置高电平 delay(5); //延时约5ms

lcden=0; //LCD使能端拉低电平 }

//*********延时函数开始********* void delay(uint k) {

uint i,j;

for(i=k;i>0;i--) for(j=110;j>0;j--); }

Proteus 仿真图

4X4矩阵键盘+1602——51单片机的

Proteus实验

本文转载自小波电子工作室。

C语言源代码

//====================================================== 依次可以从键盘输入0-f,在1602LCD上显示出来 (此程序在所买开发板上验证通过)

//====================================================== //******** 小波电子工作室 All rights reserved****** //******** 个人主页:http://hi.http://www.wodefanwen.com//niejinbo ** //******** 文 件 名: lcd_key.1.c ************ //******** 功能概要: 4*4矩阵键盘扫描 *********** //******** MCU: STC89C52 晶振:11.0592Mhz ********** //******** 设 计 者: 聂金波 ************ //******** 完成日期: 2008-07-14 ************ //******** 当前版本: 0714.1 ************ //******** 改进说明: 暂无 ************

//******** 补充说明: 从键盘输入0-F,在LCD上显示出来 //*********头文件区******************* #include #include #include

#define uchar unsigned char #define uint unsigned int

//*********定义变量区******************* sbit dula=P2^6; //关闭数码管显示之用 sbit wela=P2^7;

sbit lcden=P3^4; //LCD使能信号

sbit lcdrs=P3^5; //LCD数据/命令选择信号 uchar tab_key[50];

uchar code tab[]=%uchar n=0,temp,key;

//*********函数声明区******************** void lcd_disp(); //LCD显示函数 void lcd_init(); //LCD初始化函数 void write_com(uchar); //写命令函数 void write_data(uchar); //写数据函数 void delay(uint); //延迟函数

void key_scan(); //键盘扫描函数 void key_manage1(); //键盘功能分配函数 void key_manage2(); void key_manage3(); void key_manage4(); void key_manage5(); void key_manage6(); void key_manage7(); void key_manage8(); void key_manage9(); void key_manage10(); void key_manage11(); void key_manage12(); void key_manage13(); void key_manage14(); void key_manage15(); void key_manage16();

//**********主函数开始**********

void main() {

lcd_init(); write_com(1); while(1) {

key_scan(); lcd_disp(); } }

//**********LCD显示函数开始***********

void lcd_disp() {

uchar a,i=0; write_com(0x80); for(i=0;i

a=tab_key[i]; write_data(tab[a]); } }

//**********LCD初始化函数开始********* void lcd_init() {

dula=0;

wela=0; // 关闭数码管显示 lcden=0;

write_com(0x38); //设置显示模式:16X2,5X7,8位数据接口 write_com(0x0c); //开显示,显示光标,光标闪烁

write_com(0x06); //读写一个字符后,地址指针及光标加一,且光标加一整屏显示不移动 write_com(0x80); //设置光标指针 }

//**********写命令函数开始************ void write_com(uchar com) {

lcdrs=0; //低电平写命令 P0=com; //写入命令 delay(3); //延时约3ms

lcden=1; //LCD使能端置高电平 delay(5); //延时约5ms lcden=0; //LCD使能端拉低电平 }

//**********写数据函数开始************ void write_data(uchar dat) {

lcdrs=1; //低电平写数据 P0=dat; //写入命令 delay(3); //延时约3ms

lcden=1; //LCD使能端置高电平 delay(5); //延时约5ms lcden=0; //LCD使能端拉低电平 }

//**********键盘扫描函数开始**** void key_scan() {

//**********扫描第一行********* P3=0xfe; temp=P3;

temp=temp&0xf0; if(temp!=0xf0) {

delay(100); if(temp!=0xf0) { temp=P3; switch(temp) {

case 0xee:

key_manage1(); break;

case 0xde: key_manage2(); break;

case 0xbe: key_manage3(); break;

case 0x7e: key_manage4(); break; }

while(temp!=0xf0) {

temp=P3; temp=temp&0xf0; } } }

//**********扫描第二行********* P3=0xfd; temp=P3; temp=temp&0xf0; if(temp!=0xf0) {

delay(100); if(temp!=0xf0) {

temp=P3; switch(temp) {

case 0xed:

key_manage5(); break;

case 0xdd: key_manage6(); break;

case 0xbd: key_manage7(); break;

case 0x7d: key_manage8(); break;

}

while(temp!=0xf0) {

temp=P3; temp=temp&0xf0; } }

}

//**********扫描第三行********* P3=0xfb; temp=P3;

temp=temp&0xf0; if(temp!=0xf0) {

delay(100); if(temp!=0xf0) { temp=P3; switch(temp) {

case 0xeb: key_manage9(); break;

case 0xdb: key_manage10(); break;

case 0xbb: key_manage11(); break;

case 0x7b: key_manage12(); break; }

while(temp!=0xf0) {

temp=P3;

temp=temp&0xf0; } }

}

//**********扫描第四行********* P3=0xf7; temp=P3; temp=temp&0xf0; if(temp!=0xf0) {

delay(100); if(temp!=0xf0)

{

temp=P3;

switch(temp) {

case 0xe7: key_manage13(); break;

case 0xd7: key_manage14(); break;

case 0xb7: key_manage15(); break;

case 0x77: key_manage16(); break; }

while(temp!=0xf0) {

temp=P3;

temp=temp&0xf0; } } } }

//*********延时函数开始************** void delay(uint k) {

uint i,j;

for(i=k;i>0;i--) for(j=50;j>0;j--); }

//******键盘功能分配函数群开始******** // 键盘功能示意图 // 设计者:聂金波

//** 1 ** 2 ** 3 ** 4 **

//** 5 ** 6 ** 7 ** 8 ** //** 9 ** 0 ** s ** c **

//** M1** M2** M3** M4** void key_manage1() {

tab_key[n]=0; n++; }

void key_manage2() {

tab_key[n]=1; n++; }

void key_manage3() {

tab_key[n]=2; n++; }

void key_manage4() {

tab_key[n]=3; n++; }

void key_manage5() {

tab_key[n]=4; n++; }

void key_manage6() {

tab_key[n]=5; n++;

}

void key_manage7() {

tab_key[n]=6; n++;

}

void key_manage8()

{

tab_key[n]=7; n++; }

void key_manage9() {

tab_key[n]=8; n++; }

void key_manage10() {

tab_key[n]=9; n++; }

void key_manage11() {

tab_key[n]=10; n++; }

void key_manage12() {

tab_key[n]=11; n++; }

void key_manage13() {

tab_key[n]=12; n++; }

void key_manage14() {

tab_key[n]=13; n++; }

void key_manage15() {

tab_key[n]=14; n++; }

void key_manage16() {

tab_key[n]=15;

n++; }

Proteus仿真图

依次从键盘输入:abcd 277817639 (本人QQ号)

8952+1602测单片机内部时钟频率——51单片机的Proteus实验

本文转载自小波电子工作室。

C语言源代码

//======================================================= //******** 小波电子工作室 All rights reserved****** //******** 个人主页:http://hi.http://www.wodefanwen.com//niejinbo ** //******** 文 件 名: lcd_freq_0715_2.c ************ //******** 功能概要: LCD显示简易频率计 ******** //******** MCU: STC89C52 晶振:11.0592Mhz ********** //******** 设 计 者: 聂金波 ************

//******** 完成日期: 2008-07-15 ************ //******** 当前版本: 0715_2 ************ //******** 改进说明: 暂无 ************

//=========================================================

本文来源:https://www.bwwdw.com/article/nvlr.html

Top