目录
1、 实验目的:
(1)学习51单片机定时器/计数器的使用方法;
(2)学习定时器实现PWM电机调速的方法。
(3)继续巩固lcd1602的使用。
(4)学习模块化开发的方法
2、实验内容:
(1)05-1产生方波:
设单片机晶振频率为11.0592MHz,请编写程序利用定时器/计数器T0工作在方式1,在P2.7引脚上连续输出周期2秒的方波。在proteus里使用虚拟示波器查看输出波形。将程序烧写进电路板,连接好(风扇)直流电机(J4插座),在电路板中右部的P1处将P27与A/电机短接。观察风扇转动情况。
要求:定时器采用查询和中断两种方式,分别编写程序实现以上功能。
思考题:此时风扇为什么忽转忽停?
代码:
#define VERSION 2 // 版本1为查询 版本2为中断
#include <reg51.h>
typedef unsigned char uchar;
sbit P2_7 = P2^7;
uchar count = 0;
void main(void)
{
TMOD = 0x01;
TR0 = 1;
#if VERSION == 1 //查询方式
while (1)
{
TH0 = 0x3c;
TL0 = 0xb0; // 65536 - 50000 --> 3CB0H
while (!TF0);
TF0 = 0;
count++;
if (count == 20) // 50ms * 20 = 1s
{
P2_7 = !P2_7; // 一秒变换一次
count = 0;
}
}
#elif VERSION == 2 // 中断方式
EA = 1;
ET0 = 1;
TR0 = 1;
while(1);
#endif
}
#if VERSION == 2 // T0中断
void int_T0(void) interrupt 1 using 0
{
TH0 = 0x3c;
TL0 = 0xb0;
count++;
if (count == 20)
{
P2_7 = !P2_7;
count = 0;
}
}
#endif
电路图:
编译:
仿真:
(2)05-2直流电机调速:
利用定时器产生 pwm 波对电机进行调速。单片机p2.7口用于驱动直流电机,开机时电机不转。当按下button复位开关S1(接P3.7口)、S2(接P3.6口)、S3(接P3.5口),风扇分别以1档(占空比50%)、2档(占空比80%)、3档(占空比100%)的速度转动;按下S4(接P3.4口)电机停止转动,档位为0。其中要求使用定时器T0产生周期为2ms的连续脉冲信号。
要求高低电平转换在定时器中断里产生。
代码:
#include <reg51.h>
typedef unsigned char uchar;
sbit work = P2^7; // 连接点击/示波器的引脚
uchar times = 0, count = 0, pwm = 0, max = 250, key, it;
void main(void)
{
work = 0;
TMOD = 0x02; // 方式2
TH0 = 6; // 每次0.25us 记录4次即为1ms, 周期为2ms
TL0 = 6;
EA = 1;
ET0 = 1;
TR0 = 1;
while (1)
{
key = P3 >> 4;
switch (key)
{
case 14:
for (it = 0; it < 255; it++); // 去抖
if (key == P3 >> 4) pwm = 0; // 关闭
break;
case 13:
for (it = 0; it < 255; it++); // 去抖
if (key == P3 >> 4) pwm = 250; // 3档
break;
case 11:
for (it = 0; it < 255; it++); // 去抖
if (key == P3 >> 4) pwm = 200; // 2档
break;
case 7:
for (it = 0; it < 255; it++); // 去抖
if (key == P3 >> 4) pwm = 125; // 1档
}
}
}
void int_T0(void) interrupt 1 // T0计时器中断
{
if (++times == 4) // 每1ms执行一次 周期为2ms
{
times = 0;
if (++count < pwm) work = 1; // 在工作占比中
else if (count < max) work = 0; // 没在工作占比中
else count = 0; // 一轮结束
}
}