资源描述
单片机应用课程设计
19.5-20
作业:
2.2 答:C8051F020单片机有5个独立的物理存储空间,分别是:
(1) 64K字节程序存贮器空间(地址范围0~0FFFFH);该部分空间一般仅能进行读操作,寻址方式是基址加变址寻址,指令操作码是MOVC,指令只有两条,是MOVC A,@A+PC或MOVC A,@A+DPTR;
(2) 256字节内部RAM空间(地址范围0~0FFH);该部分空间可以采用直接寻址也可以采用间接寻址访问;访问该空间数据的传送指令操作码是MOV;
(3) 128字节内部特殊功能寄存器空间(地址范围80—0FFH);该部分空间只能采用直接寻址进行访问,一般用特殊功能寄存器名字代表该空间中的地址用在指令中;
(4) 256位寻址空间(位地址范围0—0FFH);该部分空间只能采用位寻址访问,访问该空间数据传送指令的操作码是MOV,指令中出现的地址是位地址;
(5) 64K字节外部数据存贮器(RAM/IO)空间(地址范围0~0FFFFH);该部分空间只能采用寄存器间接寻址,读操作的指令是:MOVX A,@DPTR或MOVX A,@Ri(i=0或1);写操作的指令是:MOVX @DPTR,A或MOVX @Ri(i=0或1)。
2.11
配置步骤如下:
(1). 按UART0E = 1(XBR0.2=1)、SMB0EN = 1(XBR0.0=1)、SPI0E=1(XBR0.1=1)、CP0E = 1(XBR0.7=1) 、EMIFLE =1(XBR2.1=1)和XBARE = 1(XBR2.6=1)设置XBR0、XBR1 和XBR2,则有:XBR0 = 0x87,XBR1 = 0x00,XBR2 = 0x42;
(2). 将外部存储器接口配置为复用方式并使用低端口,有:PRTSEL = 0(EMI0CF.5),EMD2 (EMI0CF.4)= 0;
(3) 将作为模拟输入的端口1 引脚配置为模拟输入方式:设置P1MDIN 为0xE3(P1.4、P1.3 和P1.2 为模拟输入,所以它们的对应P1MDIN 被设置为逻辑‘0’);
(4).UART0有最高优先级,P0.0 被分配给TX1,P0.1 被分配给RX1。SPI的优先级次之,P0.2分配给SCK,P0.3分配给MISO,P0.4分配给MOSI,由于外部存储器接口选在低端口(EMIFLE = 1),P0.5分配给ALE,P0.6分配给/RD,P0.7分配给/WR。(又因为外部存储器接口被配置为复用方式,所以在执行对片外操作的MOVX 指令期间,外部存储器接口将驱动端口2(地址总线高8位) 和端口3(地址总线低8位和8位的数据总线分时复用)。将P1MDIN 设置为0xE3,使P1.2、P1.3、P1.4 被配置为模拟输入,导致交叉开关跳过这些引脚;)P1.0分配给NSS;分配SMBus需要的引脚,P1.1 被分配给SDA,跳过P1.2、P1.3、P1.4,则接着P1.5 被分配给SCL。 接下来分配CP0的引脚,P1.6 被分配给CP0。
(5). 将UART0 的TX 引脚(TX1,P0.0)、ALE、/RD、/WR(P0.[7:5])的输出设置为推挽方式,通过设置P0MDOUT = 0xE1 来实现。
(6). 通过设置P2MDOUT = 0xFF 和P3MDOUT = 0xFF 将EMIF 端口(P2、P3)的输出方式配置为推挽方式;
(7). 通过设置P1MDOUT = 0x00(配置输出为漏极开路)和P1 = 0xFF(逻辑‘1’选择高阻态)禁止3 个模拟输入引脚的输出驱动器。
3.1
ORG 0000H
LJMP MAIN
MAIN:
MOV R4, #0
MOV DPL, #0
NEXT:
MOV DPH, #10H
MOVX A, @DPTR
MOV DPH, #25H
MOVX @DPTR,A
INC DPTR
DJNZ R4, NEXT
SJMP $
3.2
Clr c
mov a, 31h
subb a,#0
Jc negative
Sjmp exit
Negative:
Clr c
Mov a,30h
Cpl a
Add a,#1
Mov 30h,a
Mov a,31h
Xrl a,#7fh
Addc a,#0
Mov 31h,a
Exit:
Sjmp exit
3.4
X data 35h
Y data 36h
Org 0000h
Sjmp main
Org 0100h
Main:
Mov a,x
Cjne a,#0,not_equal
Mov y,#0
Sjmp exit
Not_equal:
Jc negative
Mov y,#1
Sjmp exit
Negative:
Mov y,#-1
Exit:
Sjmp exit
3.12
C51语言有三种不同类型的存储区域(memory areas):程序区、内部数据存储区和外部数据存储区。
C51编译器允许8051微处理器使用各种类型的存储区域。可以在变量声明时使用存储器类型(memory types)来指定变量所希望占用的存储区域类型,具体如下表所示。
存储器类型
存储区域
大小
code
程序存储区
64KB
data
直接寻址的内部数据存储区
128B
idata
间接寻址的内部数据区
256B
bdata
位寻址的内部数据存储区
16B
xdata
外部数据存储或
64KB
far
扩充的RAM和ROM
pdata
分页的外部数据存储区
256B
3.16
通用指针总是占用三个字节。第1个字节保存存储器类型编码值,第2个字节保存地址的高字节,第3 个字节保存地址的低字节。许多C51的库例程使用这种指针类型,通用指针类型可以访问任何存储区域内变量。
具体指针是在声明时指定了存储器类型的指针,是指向特定存储区域中的指针变量。因为存储器类型在编译时就已经指定,所以和通用指针不同,具体指针不需要保存存储器类型字节。具体指针可以保存在一个字节(idata, data, bdata, pdata类型指针)或2个字节(code 和xdata类型指针)中。
具体指针可以用来访问8051声明的存储区内的变量。具体指针的效率高,但灵活性较差。
使用通用指针类型的代码和具体指针类型的代码相比,完成相同的功能代码的运行速度要慢很多。这是因为通用指针类型只有在程序运行时才能知道实际的变量存储区类型,因此编译器就不能对内存访问进行优化,从而只能生成可以访问任意存储区的通用代码。如果必须优先考虑程序的运行速度,那么只要有可能就应该使用具体指针来替代通用指针。
4.7
解:要在P1.2上产生周期为350us的矩形波,让P1.2引脚300us维持低电平,然后50us是高电平,然后循环这个过程。可以设定定时器是50us定时周期,那么定时器中断6次就是300us的时间,7次正好一个周期。
(1)确定定时常数
假设使用系统时钟的12分频作为计数源,则计数周期T计数=12/晶振频率=12/(12×)=1μs
假设采用定时器1的工作方式1(16位的定时器),则
计数初值TC=M-T/T计数,可计算出初值TC=216-50=65486=ffceH
因此初值应为:TH1=0xff,TL1=0xce。
(2)计数器初始化程序
初始化程序包括定时器初始化和中断系统初始化,主要是对IP、IE、CKCON、TCON、TMOD的相应位进行正确的设置,并将时间常数送入定时器中。
(3)计数器中断服务程序
中断服务程序除了完成要求的方波产生这一工作之外,还要注意将时间常数重新送入定时器中,为下一次产生中断作准备。
//主程序
#include <c8051f020.h>
sbit P1_2= P1^2;
void main( )
{
int count=0; //6次T1中断为300us
CKCON&=0xef; //定时器1的计数源选择系统脉冲的12分频
TMOD=0x10; //定时器1,方式1
P1_2=0;
TH1=0xff; //定时初值
TL1=0xce;
IE|=0x88; //允许定时器1中断
IP|=0x08; //定时器1中断为高优先级中断
TCON|=0x40; //启动定时器1
While(1); //死循环,等待中断,产生方波
}
//中断服务程序
void Timer1_ISR (void) interrupt 3
{
TH1=0xff; //重装初值
TL1|=0xce;
count++; //中断计数
if (count==6) //300us到,P1.2置高电平
{
P1_2=1;
}
Else if(count==7)
{
P1_2=0;
count==0;
}
}
4.15、设利用T1工作在定时方式2(自动重装初值)提供波特率,T1M=0(按振荡器12分频)计数,SMOD0=0,T1初值计算如下:
X=256-=256-=250=FAH
UART0用方式1串行通信:
查询方式发送程序:
#include <c8051f020.h>
unsigned char xdata tbuf[]=“hello c8051f020”;
unsigned char c;
void main(void)
{
unsigned char i;
unsigned char xdata *p=tbuf;
TMOD=0x20; //初始化并启动T1
TH1=0xfa;
TL1=0xfa;
TR1=1;
SCON0=0x40; //UART0初始化,方式1
for(i=0;i<14;i++)
{
c=*p; //取一字节并加上校验信息
ACC=c;
TB8=P;
SBUF0=c; //发送
p++;
while(!TI0); //等待发送完成
TI=0;
}
}
查询方式接收程序:
#include <c8051f020.h>
unsigned char c;
void main(void)
{
unsigned char i;
char data *p; //发送数据块地址指针
TMOD=0x20; //初始化并启动T1
TH1=0xfa;
TL1=0xfa;
TR1=1;
SCON0=0x50; //UART0初始化,允许接收
p=0x20; //地址指针初始化
for(i=0;i<14;i++)
{
while(!RI0); //等待UART0接收一个字符
RI=0;
c=SBUF0; //取收到的字符进行校验
ACC=c;
if(TB8 = = P) { *p=c; p++;}//无错,放入接收缓冲区
}
}
展开阅读全文