仿真图:
芯片/模块的特点:
AT89C52简介:
AT89C52是一款经典的8位单片机,是意法半导体(STMicroelectronics)公司生产的一系列单片机之一。它基于8051内核,并具有许多与其兼容的特性。
AT89C52的主要特点如下:
内部存储器:AT89C52具有8KB的闪存(Flash)存储器,可用于存储用户程序和数据。这些存储器的内容可以通过编程器进行编程和擦除。
RAM存储器:AT89C52配备了256字节的随机存取存储器(RAM),用于暂存数据和程序的变量。
外部扩展性:AT89C52支持多种外部扩展设备的连接,包括外部存储器(如RAM、EEPROM)和外设(如ADC、LCD、UART等),通过外部硬件连接,可以扩展单片机的功能和应用。
通用I/O引脚:AT89C52拥有32个可编程的通用输入/输出引脚,可用于连接外部设备和与其他芯片进行通信。
定时器/计数器:AT89C52内置了3个16位定时器/计数器和一个可编程的串行定时器/计数器。这些计时器/计数器可用于实现定时功能、生成脉冲信号、测量时间间隔等。0
串行通信:AT89C52支持串行通信接口,包括UART(串行异步通信)和SPI(串行外设接口),便于与其他设备进行数据通信和交互。
低功耗模式:AT89C52具有多种低功耗模式,如空闲模式和电源下模式,在不需要执行任务的时候可以将CPU进入低功耗状态以节省能量。
宽电源电压范围:AT89C52的工作电压范围通常为4.0V至5.5V,可以满足大多数应用需求。
主程序:
#include <reg52.h>
#include "main.h"
unsigned int speed=0;
unsigned int PulseCnt=0;
unsigned char pwmValue = 5;
bit dispFlag; //液晶刷新标志
// bit motorFlag; //正反转标识
bit startFlag; //启停标识
bit rekey; //按键标志
void main()
{
// 初始化
MOTOR = 0;
LED_RED = 0;
LCD_Init();
// 定时器初始化
Timer0_Init();
Timer1_Init();
Ext1_Init();
// 开机显示
LCD_DispStr(0, 0, " Welcome!!! ");
DelayS(2);
LCD_Clear();
LCD_DispStr(0, 0, "Rotational speed");
while(1)
{
if (dispFlag == 1)
{
DispSpeed();
dispFlag = 0;
}
KeyProcess();
}
}
void DispSpeed()
{
unsigned char dispRow[16];
TR0 = 0;
speed = PulseCnt;
PulseCnt = 0;
if (startFlag == 1)
{
sprintf(dispRow, "PWM:%3d Start ", (int)pwmValue * 10);
}
else
{
sprintf(dispRow, "PWM:%3d Stop ", (int)pwmValue * 10);
}
LCD_DispStr(0, 0, dispRow);
sprintf(dispRow, "Rate: %7.1fr/s", (float)speed);
LCD_DispStr(0, 1, dispRow);
TH0 = RH_10MS(5); //50ms
TL0 = RL_10MS(5);
TR0 = 1; //启动T0计时
EX1 = 1;
}
void KeyProcess()
{
if ((P2 & 0xFC) != 0xFC)
{
DelayMs(20);
if (rekey == 0)
{
if ((P2 & 0xFC) != 0xFC)
{
rekey = 1;
if (KEY_UP == 0) //加速
{
if (pwmValue <= 9)
pwmValue++;
}
else if (KEY_DOWN == 0) //减速
{
if (pwmValue > 1)
pwmValue--;
}
else if (KEY_LEFT == 0) //开
{
startFlag = 1;
LED_GREEN = 0;
LED_RED = 1;
}
else if (KEY_RIGHT == 0) //停
{
startFlag = 0;
LED_GREEN = 1;
LED_RED = 0;
}
}
}
}
else
{
rekey = 0;
}
}
void Timer0_Init()
{
TMOD &= 0xF0; //Timer0 16位装载
TMOD |= 0x01;
TH0 = RH_10MS(5); //50ms
TL0 = RL_10MS(5);
TR0 = 1; //启动T0计时
ET0 = 1; //打开T0中断
EA = 1; //打开总中断
}
void Timer0_Intterupt() interrupt 1
{
static unsigned int cnt=0;
TH0 = RH_10MS(5); //50ms
TL0 = RL_10MS(5);
cnt++;
if (cnt >= 20) //1s
{
EX1 = 0;
dispFlag = 1;
cnt = 0;
}
}
void Timer1_Init(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH1 = RH_10MS(2); //重新赋值 20ms
TL1 = RH_10MS(2);
EA = 1; //总中断打开
ET1 = 1; //定时器中断打开
TR1 = 1; //定时器开关打开
}
void Timer1_Intterupt(void) interrupt 3
{
static unsigned char IN1Count = 0;
static unsigned long numCount = 0;
TL1 = 0xCD; //设置定时初值 2ms
TH1 = 0xF8; //设置定时初值
IN1Count++;
if (IN1Count < pwmValue) //占空比调节
{
if (startFlag == 1)
{
MOTOR = 1;
}
else
{
MOTOR = 0;
}
}
else if ((IN1Count >= pwmValue) && (IN1Count <= 11)) //关闭时间段
{
MOTOR = 0;
}
else
{
IN1Count = 0; //一个周期结束
}
numCount++;
}
void Ext1_Init()
{
EX1 = 1; //使能外部中断
IT1 = 1; //负边沿触发
}
void Ext1_Intterupt() interrupt 2
{
PulseCnt++;
}
设计文件: