完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、实验要求
用89C51单片机控制并行接口芯片8255实现6 位八段码 LED 动态方式循环显示一组数据。 二、8255接口芯片的简介 (1)8255芯片是什么 8255A是一种可编程并行I/O口的拓展芯片,可用于拓展多组8位并行I/O口。 (2)如何对8255芯片编程 其实,在程序编写上,8255芯片就相当于拓展一个外部RAM,对它的操作就用指令MOVX即可 我们需要对它的操作是: 1)对其控制字地址写入对各个I/O口的模式 其中方式0、方式1、方式2为: 所以我们如果需要使用PA口和PB口输出并且使用方式1的话,那么控制字写为1000 0000,则程序为: MOV DPTR,#0FF23H //控制口地址MOV A,#80HMOVX @DPTR,A 2)对各个I/O的地址写入需要显示的数字 MOV DPTR,#0FF21H //写入PB口数据 MOVX @DPTR,A MOV DPTR,#0FF20H //写入PA口数据 MOV A,R2 MOVX @DPTR,A (3)8255芯片与51单片机如何连接 单片机在拓展外部芯片时,通常都会使用74LS373作为地址锁存器。 值得一提的是,RD和WR是由硬件自动控制,不需要对其进行软件编程控制。 则单片机与8255的连接如下: 三、代码 1.汇编语言程序 OUTBIT EQU 0FF20HLEDBUF EQU 60H //存储数据NUM EQU 70H //显示数据DELAYT EQU 75H ORG 0000H LJMP START LEDMAP:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H DB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH DELAY: MOV R7,#0 DELAYLOOP: DJNZ R7,DELAYLOOP DJNZ R6,DELAYLOOP RET DISPLAYLDE: MOV R0,#LEDBUF MOV R1,#6 MOV R2,#11011111B //从左边开始显示 LOOP: MOV DPTR,#OUTBIT MOV A,#0FFH MOVX @DPTR,A MOV A,@R0 MOV DPTR,#0FF21H MOVX @DPTR,A MOV DPTR,#OUTBIT MOV A,R2 MOVX @DPTR,A MOV R6,#8 CALL DELAY MOV A,R2 RR A //A循环右移 MOV R2,A INC R0 DJNZ R1,LOOP MOV DPTR,#OUTBIT MOV A,#0FFH MOVX @DPTR,A RET START: MOV DPTR,#0FF23H //控制口地址 MOV A,#81H MOVX @DPTR,A MOV SP,#40H //这句话是什么意思? MOV NUM,#0 MLOOP: INC NUM MOV A,NUM MOV B,A MOV R0,#LEDBUF FILLBUF: MOV A,B ANL A,#0FH //确保A只有一位数(16进制) MOV DPTR,#LEDMAP MOVC A,@A+DPTR MOV @R0,A INC R0 INC B CJNE R0,#LEDBUF+6,FILLBUF MOV DELAYT,#00 DISPAGAIN: CALL DISPLAYLDE DJNZ DELAYT,DISPAGAIN LJMP MLOOP END 2.C语言程序 (在仿真的时候有点快,但i也不能再小了(手动捂脸)) #include "reg51.h"#include "intrins.h"#define u8 unsigned char #define u16 unsigned int u8 xdata*PA=0xFF20;u8 xdata*PB=0xFF21;u8 xdata*CTR=0xFF23;u16 i,j,a,b=0,p;u16 Aa;u8 display[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};void delayms(a){ for(j=a;j>0;j--) { for(i=110;i>0;i--) ; }}void main(){ *CTR=0x80; while(1) { for(p=0;p<16;p++) { b=p; Aa=0xDF; for(j=0;j<6;j++) { for(i=0;i<40;i++) { *PA=Aa; *PB=display[b%16]; } Aa=(Aa>>1)|(Aa<<5); b=b+1; } delayms(200); } }} 四、仿真结果 五、学习小得 1.学到了学到了 (1)EQU 用一个习惯的符号代替汇编语言中的关键字或指令助记符 (2)RR A RR表循环右移,循环右移和逻辑右移的区别是:循环右移一位后,最左的数据放在最右;逻辑右移一位后,最左补零。 C语言里没有循环左移或循环右移的操作符,但可以灵活处理,比如,操作数x有s位循环n位 则循环左移:x=(x< 循环右移:x=(x>>n)|(x<<(s-n)) (3)6位动态数码管显示的实现: MOV R2,#11011111B MOV A,R2 RR A (4)proteus中图纸大小的设置是在:系统—>设置纸张大小 (5)unsigned char xdata 无符号片外数据指针 unsigned char xdata * p 表指针指向一个处于xdata的元素 xdata unsigned char * p=unsigned char * xdata p 表明指针本身位于xdata中 2.调程序有得 (1)#define unsigned char u8 报错:attempt to redefine macro ‘unsigned’ 正确的写法:#define u8 unsigned char (2)先对PA赋值再对PB赋值 两者孰前孰后还是很有区别的 (3)这个for循环是必要的,虽然不知道为什么 for(i=0;i<40;i++) { *PA=Aa; *PB=display[b%16]; } |
|
|
|
只有小组成员才能发言,加入小组>>
2497 浏览 0 评论
1061浏览 2评论
680浏览 1评论
442浏览 0评论
176浏览 0评论
294浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 18:44 , Processed in 1.093777 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号