单片机定时器与串口通信
1、利用中断发出1Khz的方波信号,驱动蜂鸣器鸣叫。
首先,在keil软件编写c文件,生成hex文件
#include<reg51.h>
sbit sound = P2^5;
#define f1(a) (65536-a)/256
#define f2(a) (65536-a)%256
unsigned int i = 500;
unsigned int j = 0;
void main(void)
{
EA = 1;
ET1 = 1;
TMOD = 0x10;
TH1 = f1(i);
TL1 = f2(i);
TR1 = 1;
while (1)
{
i = 460;
while (j < 2000);
j = 0;
i = 360;
while (j < 2000);
j = 0;
}
}
void t1(void) interrupt 3 using 0
{
TR1 = 0;
sound = ~sound;
TH1 = f1(i);
TL1 = f2(i);
j++;
TR1 = 1;
}
然后,在proteus中绘制电路图:
使用生成的hex文件,观察仿真运行是否符合运行。
运行正常,使用实机运行
可以看到,运行效果与仿真无误。
2、LED数码管秒表的制作。用2位数码管显示计时时间,最小计时单位为“百毫秒”,计时范围0.1~9.9s。当第1次按一下计时功能键时,秒表开始计时并显示;第2次按一下计时功能键时,停止计时,将计时的时间值送到数码管显示;如果计时到9.9s,将重新开始从0计时;第3次按一下计时功能键,秒表清0。再次按一下计时功能键,则重复上述计时过程。
keil中的c文件:
#include<reg51.h>
unsigned char code discode1[] = { 0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef };
unsigned char code discode2[] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };
unsigned char timer = 0;
unsigned char second;
unsigned char key = 0;
void int_T0() interrupt 1 using 0
{
TR0 = 0;
TH0 = 0xee;
TL0 = 0x00;
timer++;
if (timer == 20)
{
timer = 0;
second++;
P0 = discode1[second / 10];
P2 = discode2[second % 10];
}
if (second == 99)
{
TR0 = 0;
second = 0;
key = 2;
}
else
{
TR0 = 1;
}
}
void main()
{
TMOD = 0x01;
ET0 = 1;
EA = 1;
second = 0;
P0 = discode1[second / 10];
P2 = discode2[second % 10];
while (1)
{
if ((P3 & 0x80) == 0x00)
{
key++;
switch (key)
{
case 1:
TH0 = 0xee;
TL0 = 0x00;
TR0 = 1;
break;
case 2:
TR0 = 0;
break;
case 3:
key = 0;
second = 0;
P0 = discode1[second / 10];
P2 = discode2[second % 10];
break;
}
while ((P3 & 0x80) == 0x00);
}
}
}
proteus图:
仿真运行:
实机运行:
3、使用定时器实现一个LCD显示时钟。
c文件:
#include<reg51.h>
#include<lcd1602.h>
#define uchar unsigned char
#define uint unsigned int
uchar int_time;
uchar second;
uchar minute;
uchar hour;
uchar code date[] = " H.I.T. CHINA ";
uchar code time[] = " TIME 23:59:55 ";
uchar second = 55, minute = 59, hour = 23;
void clock_init()
{
uchar i, j;
for (i = 0; i < 16; i++)
{
write_data(date[i]);
}
write_com(0x80 + 0x40);
for (j = 0; j < 16; j++)
{
write_data(time[j]);
}
}
void clock_write(uint s, uint m, uint h)
{
write_sfm(0x47, h);
write_sfm(0x4a, m);
write_sfm(0x4d, s);
}
void main()
{
init1602();
clock_init();
TMOD = 0x01;
EA = 1;
ET0 = 1;
TH0 = (65536 - 46483) / 256;
TL0 = (65536 - 46483) % 256;
TR0 = 1;
int_time = 0;
second = 55;
minute = 59;
hour = 23;
while (1)
{
clock_write(second, minute, hour);
}
}
void T0_interserve(void) interrupt 1 using 1
{
int_time++;
if (int_time == 20)
{
int_time = 0;
second++;
}
if (second == 60)
{
second = 0;
minute++;
}
if (minute == 60)
{
minute = 0;
hour++;
}
if (hour == 24)
{
hour = 0;
}
TH0 = (65536 - 46083) / 256;
TL0 = (65536 - 46083) % 256;
}
proteus图:
实机效果:
4、(甲乙两个单片机串口通信)在实物实验时,如果不能找到两个普中单片机,用笔记本电脑的串口助手程序代替其中一个单片机,实现课件上描述的主要功能。
甲机c文件:
#include <reg51.h>
sbit p = PSW ^ 0;
unsigned char Receive(void)
{
unsigned char dat;
while (RI == 0);
;
RI = 0;
ACC = SBUF;
if (RB8 == P)
{
dat = ACC;
return dat;
}
}
void main(void)
{
TMOD = 0x20;
SCON = 0xd0;
PCON = 0x00;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
REN = 1;
while (1)
{
P1 = Receive();
}
}
乙机c文件:
#include <reg51.h>
sbit p = PSW ^ 0;
unsigned char Tab[8] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
void Send(unsigned char dat)
{
TB8 = P;
SBUF = dat;
while (TI == 0);
;
TI = 0;
}
void delay(void)
{
unsigned char m, n;
for (m = 0; m < 250; m++)
for (n = 0; n < 250; n++);
}
void main(void)
{
unsigned char i;
TMOD = 0x20;
SCON = 0xc0;
PCON = 0x00;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
while (1)
{
for (i = 0; i < 8; i++)
{
Send(Tab[i]);
delay();
}
}
}
proteus图:
仿真效果:
5、将单片机串口与笔记本电脑串口模块相连,单片机每隔2秒发送“Hello C51”,笔记本电脑用串口助手软件接收。 如果串口助手发送字符“0" 给单片机,则单片机停止发送; 如果单片机收到“1”,则继续每隔2秒发送“Hello C51”。
c文件:
#include <reg51.h>
#include <stdio.h>
#define uchar unsigned char
unsigned char TR = 0;
void delay(unsigned int i)
{
unsigned char j;
for (; i > 0; i--)
for (j = 0; j < 125; j++)
;
}
void int_isr(void) interrupt 4
{
if (RI == 1)
{
if (SBUF == 1)
{
TR = 1;
}
if (SBUF == 0)
{
TR = 0;
}
RI = 0;
}
}
void main()
{
TH1 = 0xFD;
TL1 = TH1;
TMOD |= 0x20;
SCON = 0x50;
ES = 1;
TR1 = 1;
TI = 1;
EA = 1;
while (1)
{
if (TR == 1)
{
while (1)
{
printf("Hello C51\n");
delay(1000);
if (TR == 0)break;
}
}
else
{
while (1)
{
if (TR == 1)break;
}
}
}
}
实机效果:
6.总结
学了。