.
TH0 = (65536 – 500000)/256 ; NUM++;
If (NUM ==10) {
P1_0 =1; P1_1 =0; TR0 =0; }
}
Void INT_0(void) interrupt 0 {
P1_0 =0; P1_1 =1; TR0 =1; NUM =0; } }
解:外部脉冲由管脚输入,可设T0工作于定时器方式1,计数初值为0,当 输入高电平
时对T0计数,当高电平结束时,计数值乘上机器周期数就是脉冲宽度。
工作方式控制字TMOD=00001001B=09H,计数初值TH1=00、TL0=00H。 汇编语言程序: ORG 0000H LJMP MAIN ORG 0100H
MAIN: MOV TMOD ,#09H ;T0定时,方式1,GATE=1 MOV TH0 ,#00H ;置TH0计数初值 MOV TL0 ,#00H ;置TL0计数初值
WAIT: JB P3.2 WAIT ;等待/P3.2引脚变为低电平 SETB TR0 ;预启动T0
WAIT1: JNB P3.2 ,WAIT1 ;等待/P3.2引脚变为高电平、启动计数 WAIT2: JB P3.2 ,WAIT2 ;等待/P3.2引脚再变为低电平 CLR TR0 ;停止计数
MOV 51H ,TH1 ;读取计数值,存入指定的单元 MOV 50H ,TL1 SJMP $ END C语言程序:
#include
unsigned char data *p; void main(void) {
.'
.
TMOD=0x09; /* T0工作在定时器方式1,GATE=1 */ TH0=0; TL0=0;
do { } while (P3.2); /* 等待/P3.2引脚变为低电平 */ TR0=1; /* 启动定时器/计数器0 */ do { } while (! P3.2); /* 等待引脚变为高电平、启动计数*/ do { } while (P3.2); /* 等待引脚再变为低电平 */ TR0=0; /* 停止计数 */ p=0x50; *p=TL0; p=p+1; *p=TH0;
}
解: 有4种工作方式
方式0: 8位同步移位寄存器方式,波特率 fosc/12 方式1: 10位异步收发方式,波特率 可变 方式2: 11位异步收发方式,波特率 fosc/32、fosc/64 方式3: 11位异步收发方式,波特率 可变
解: 串口SBUF 分接收SBUF和发送SBUF,占用同一地址。
解:
分析:甲、乙两机都选择方式1:8位异步通信方式,最高位用作奇偶校验,波特率为1200bps,甲机发送,乙机接收,因此甲机的串口控制字SCON为40H,乙机的串口控制字SCON为50H。 设甲、乙两机的振荡频率为12MHZ,由于波特率为1200。SMOD =0 ,定时/计数器T1选择为
.'
.
方式2,则初值为:
SMOD
初值=256 - fosc×2 /(12×波特率×32) =/(12×1200×32)≈230=E6H
根据要求定时/计数器T1的方式控制字TMOD为20H。 甲机的发送程序:
TSTART:MOV TMOD,#20H MOV TL1,#0E6H MOV TH1,#0E6H MOV PCON,#00H MOV SCON,#40H MOV R0,#30H MOV R7,#10H SETB TR1 LOOP: MOV A,@R0 MOV SBUF,A
WAIT:JNB TI,WAIT CLR TI INC R0
DJINZ R7,LOOP RET
乙机接收程序:
RSTART:MOV TMOD,#20H MOV TL1,#0E6H MOV TH1,#0E6H MOV PCON,#00H MOV DPTR,#0030H MOV R7,#10H
SETB TR1 ;启动定时器1 LOOP:MOV SCON,#50H WAIT: JNB RI,WAIT MOV A,SBUF MOVX @DPTR,A INC R0
DJNZ R7,LOOP RET
甲机对应的C语言发送程序如下:
#include “reg51.h” /* unsigned char data ADDRA [0X30]; /* unsigned char num=0; /* .'
包含8051单片机的寄存器定义头文件 */ 在RAM区定义16个单元 */ 声明计数变量 */
.
unsigned char *p; /* 定义 p为指针 */ void main(void) /* 主程序 */ {
SCON=0x40; /* 置串行口工作方式1 */ TMOD=0x20; /* 定时器1为工作方式2 */ PCON=0x00; /* SMOD=0 */ TL1=0xe6; /* 置计数初值 */ TH1=0xe6; /* 计数重装值 */ TR1=1; /* 启动定时器1 */ EA=1; /* 开中断 */
ES=1; /* 串行口开中断 */
p=ADDRA; /* 设置发送数据缓冲器区指针 */ SBUF=*p; /* 发送第一个数据 */ while (1); /* 等待中断 */ }
void Ser_T1A (void) interrupt 4 /* 中断号4是串行中断 */ {
TI=0; /* 清发送中断标志 */ num++; /* 计数变量加1 */ if (num==0x10) ES=0; /* 判断是否发送完,若已完,则关中断 */ else /* 否则,修改指针,发送下一个数据 */
{
p++; SBUF=*p; } }
乙机对应的C语言程序如下: #include “reg51.h”
unsigned char xdata ADDRB [0X0030];
unsigned char num=0; /* 声明计数变量 */ unsigned char *p; /* 定义 p为指针 */ void main(void) /* 主程序 */ {
SCON=0x50; /* 置串行口工作方式1,允许接收 */
TMOD=0x20; /* 定时器1为工作方式2 */ PCON=0x00; /* SMOD=0 */ TL1=0xe6; /* 置计数初值 */ TH1=0xe6; /* 计数重装值 */ TR1=1; /* 启动定时器1 */ EA=1; /* 开中断 */
ES=1; /* 串行口开中断 */
p=ADDRB; /* 设置接收数据缓冲器区指针 */
.'
.
while (1); /* 等待中断 */
}
void Ser_T1B (void) interrupt 4 /* 中断号4是串行中断 */ {
RI=0; /* 清接收中断标志 */ num++; /* 计数变量加1 */ if (num==16)
ES=0; /* 判断是否接收完,若已完,则关中断 */ else /* 否则,接收数据,修改指针 */ {
*p=SBUF p++;
} }
第7章 单片机系统扩展
1、 在LED显示器上用动态扫描方式实现0123四位数字显示。 2、 在LED显示器上显示4位10进制数,按键每按一次,对应的位数上的数值加1。
3、
在LED显示器上显示4*4键盘上按下的对应按键值(0-9)。
.'