采用中断方式. #include 〈reg51.h> sbit P1_0=P1^0;
void timer0(void) interrupt 1using 1 {P1_0=!P1_0; TH0= -1000/256; TL0= -1000%6;} void main(void) {TMOD=0x01; P1_0=0; TH0= -1000/256; TL0= -1000%6; EA=1;ET0=1;TR0=1; do {} while(1); }
例2,设单片机的fosc=6MHz,要求在P1.7脚上的指示灯亮一秒灭一秒. void main(void) {P1_7=0; P1_0=1; TMOD=0x61; TH0= -50000/256; TL0= -50000%6; TH1= -5; TL1= -5; IP=0x08; EA=l; ET0=1; ET1=l; TR0=l; TR1=1; for (;;){} } #include sbit P1_0=P1^0; sbit P1_7=P1^7;
void timer0( ) interrupt 1 using 1 {P1_0=!P1_0; TH0= -50000/256; TL0= -50000%6; }
void timer1( ) interrupt3 using 2 {P1_7=!P1_7;}
例3, 设单片机的fosc=10MHz,要求在P1.0脚上输出周期为2.5μs,占空比20%. #include
#define uchar unsigned char
uchar time; uchar period=250; uchar high=50;
void timer0( ) interrupt l using 1 {TH0= -8333/256; TL0= -8333%6; if(++time==high)P1=0; else if(time==period) {time=0; P1=1;} }
void main(void) {
TMOD=0x01; TH0= -8333/256; TL0= -8333%6; EA=l; ET0=1; TR0=1; do {)while(1); } #include
#define uchar unsigned char #define uint unsigned int uchar time,status,percent,period; bit one_round;
uint oldcount,target=500;
void pulse(void) interrupt 1using l {TH0= -833/256; TL0= -833%6; ET0=l; if(++time==percent)P1=0; else if (time ==100) {time=0;P2=l;}
void tachmeter(void) interrupt 2 using 2 {union {uint word;
struct{uchar hi;uchar lo;}byte; }newcount; newcount_byte.hi=TH1; newcount_byte.lo=TLl;
period=newcount.word--oldcounts;
oldcount=newcount.word; one -round=1; void main(void) {IP=0x04; TMOD=0x01; TCON=0x54; TH1=0;TL1=0; IE=0x86; for(;;) {if(one_round) {if(period {if(percent0) --percent; } } } 串行口
8051系列单片机有一个标准的串行通信接口,发送数据时由TXD端口送出,接收数据时由RXD端口输入.
内置两个缓冲器SBUF,一个接受缓冲器,另一个是接收缓冲器,可实行全双工的串行通信. 近距离可直接用TTL电平,若与计算机通信,则需要将电平转换成RS232电平形式,若需长距离通信可以采用RS485电 平形式,通信的数据必须通过软件的编写来完成. 一,与串行口有关的SFR 1,串行口控制寄存器SCON
SM0 SM1 SM2 REN TB8 RB8 TI RI D7 D6 D5 D4 D3 D2 D1 D0
. SM0,SM1:串行口工作方式控制位(见书P158). . SM2:多机通信控制位(方式2,3);
1→只有接收到第9位(RB8)为1,RI才置位; 0→接收到字符RI就置位. . REN :串行口接收允许位;
1→允许串行口接收;0→禁止串行口接收.
. TB8:方式2和方式3时,为发送的第9位数据,也可以作奇偶 校验位.
. RB8:方式2和方式3时,为接收到的第9位数据;方式1时, 为接收到的停止位.
. TI:发送中断标志;由硬件置位,必须由软件清0. . RI:接收中断标志;由硬件置位,必须由软件清0.
一,与串行口有关的SFR 2,电源控制寄存器PCON SMOD
D7 D6 D5 D4 D3 D2 D1 D0
PCON的第7位SMOD是与串行口的波特率设置有关的选择位. . SMOD:串行口波特率加倍位.
1→方式1,3波特率=定时器 1溢出率/16;方式2波特率为fosc/32; 0→方式1,3波特率=定时器1溢出率/32;方式2波特率为fosc/64. 二,串行口的工作方式 1. 方式0
方式0为移位寄存器输入/输出方式,串行数据通过RXD输入/输出 ,TXD则用于输出移位时钟脉冲.
方式0时,收发的数据为8位,低位在前.波特率固定为fosc/12,其中fosc为单片机外接晶振频率.
发送是以写SBUF寄存器的指令开始的,8位输出结束时TI被置位.
方式0接收是在REN=1和RI=0同时满足时开始的.接收的数据装入SBUF中,结束时RI被置位.
移位寄存器方式的也可用于两个单片机之间的通信.和通常9600波特相比,lMHz通信能力对短距离通信很吸引人. 二,串行口的工作方式 2. 方式1
方式1是10位异步通信方式,1位起始位(0),8位数据位和1位停止位(1).其中的起始 位和停止位在发送时是自动插入的.
任何一条以SBUF为目的寄存器的指令都启动一次发送,发送的条件是TI=0,发送完置TI为1;
方式l接收的前提条件是SCON中的REN为l,同时下列两个条件都满足,本次接收有效,将其装入SBUF和RB8位.否则放弃接收结果.两个条件是: (1)RI=0;(2)SM2=0或 接收到的停止位为1;
方式1的波特率是可变的,波特率可由以下计算公式计算得到: 方式1波特率=2SMOD.(定时器1的溢出率)/32
其中的SMOD为PCON的最高位.定时器1的方式0,1,2,都可以使用,其溢出率为定时时间的倒数值.
二,串行口的工作方式 3. 方式2和方式3
这两种方式都是11位异步接收/发送方式,它们的操作过程完全一样,所不同的是波特率: 方式2波特率=2SMOD.(fosc/64);
方式3波 特率同方式1(定时器l作波特率发生器).
方式2和方式3的发送起始于任何一条\写SBUF\指令,当第9位数据 (TB8)输出之后,置位
TI.
方式2和方式3的接收前提条件也是REN为1.在第9位数据接收到后,如果下列条件同时满足 (1)RI=0;(2)SM2=0或接收 到的第9位为1,则将已接收的数据装入SBUF和RB8,并置位RI,如果条件不满足,则接收无效.
三,串行口的初始化
在使用串行口之前,应对它进行编程初始化,主要是设置产生波特率的定时器1,串行口控制和中断控制寄存器.具体步骤如下:
(1) 确定定时器1的工作方式——编程TMOD寄存器; (2) 计算定时器1的初值——装载TH1,TL1,具体TH1和 TL1的值可查表得到;
(3) 启动定时器1——编程TCON中的TR1位,即置TR1为1; (4) 确定串行口的控制——编程SCON;
(5) 串行口在中断方式工作时,须开CPU和源中断