仿真图:
芯片/模块的特点:
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,可以满足大多数应用需求。
74HC573简介:
74HC573是一种集成电路,属于74系列高速CMOS逻辑系列。它是一个八位透明锁存器,常用于存储和锁定数据,以及在需要时将数据输出到其他器件。
74HC573具有8个数据输入端(D0-D7)和8个对应的数据输出端(Q0-Q7)。它还有一个使能输入端( OE ‾ \overline{\text{OE}} OE)和一个锁存控制输入端(LE),用于控制数据的读写和锁存操作。
当锁存控制输入端(LE)为高电平时,74HC573的数据输入端(D0-D7)的数据会被锁存,并存储在内部的锁存器中。此时,数据可以通过数据输出端(Q0-Q7)进行输出。
当使能输入端( OE ‾ \overline{\text{OE}} OE)为低电平时,输出端(Q0-Q7)将激活,并输出锁存器中存储的数据。而当使能输入端( OE ‾ \overline{\text{OE}} OE)为高电平时,输出端将处于高阻态,不会提供电平输出。
74HC573的主要特点包括:
快速响应时间:74HC573采用高速CMOS技术,具有快速的输入输出响应时间,适用于高速数据传输和信号处理。
透明锁存功能:74HC573具有透明锁存功能,在锁存控制输入端(LE)为高电平时,可以将输入数据直接通过并存入锁存器,实现数据的实时锁存。
高驱动能力:74HC573具有较高的输出驱动能力,可以驱动较长的总线线路以及多个负载。
宽工作电压范围:74HC573的工作电压范围通常为2V至6V,适用于多种逻辑电路的工作。
DS18B20特点:
- 单总线接口:DS18B20使用单总线接口进行通信,只需要一个引脚就可以连接多个传感器,简化了电路设计和连接。
- 数字输出:DS18B20以数字形式输出温度值,不需要额外的模数转换器。它使用12位的分辨率来表示温度值,可以实现高精度的温度测量。
- 高精度:DS18B20可以提供从-55°C到+125°C的温度测量范围,并具有±0.5°C的温度精度。因此,在许多应用中,它可以提供可靠和准确的温度测量结果。
- 多功能性:除了测量温度,DS18B20还可以执行其他功能,如温度报警功能。它可以设置上下限温度阈值,并在温度超过或低于这些阈值时触发报警。
- 低功耗:DS18B20采用低功耗设计,工作电流极低,只需要很少的能量来进行温度测量和通信。
- 耐用性:DS18B20具有良好的耐用性和可靠性,其封装材料和结构设计使其适用于各种环境条件下的应用。
L9110特点:
双路驱动:L9110可以同时驱动两个直流电机,每个驱动通道最大电流可达800mA。这使得它非常适用于需要控制多个电机的应用。
低电压工作:L9110可以在较低的电源电压下工作,通常在2.5V至12V之间。这使得它适用于电池供电的低电压应用,如机器人、小型车辆等。
高效能:该芯片采用了双H桥驱动技术,具有较高的效率和较低的功耗。它可以提供高达15kHz的PWM(脉冲宽度调制)频率,以实现电机速度的精确控制。
内置保护功能:L9110具有过温保护和短路保护功能,可有效保护芯片和电机免受过载和短路等异常情况的损害。
引脚简单:L9110只需要几个引脚就可以实现电机的驱动,包括两个输入引脚控制电机的正反转,以及两个输出引脚连接电机。
主程序:
#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include "18b20.h"
#include "lcd1602.h"
#include "delay.h"
sbit L9110H_IN1 = P1^0; //引脚定义
sbit L9110H_IN2 = P1^1;
sbit BUZZER = P2^2;
sbit KEY_UP = P3^5; //按键引脚定义
sbit KEY_DOWN = P3^7;
sbit KEY_FORWORD = P3^6;
sbit KEY_BACK = P3^4;
sbit KEY_START = P1^6;
sbit KEY_STOP = P1^7;
sbit LED_RED = P2^1;
sbit LED_GREEN = P2^0;
bit ReadTempFlag; //定义读时间标志
int temp; //温度读取
float temperature; //实际温度
char dis0[16]; //定义显示区域临时存储数组
unsigned char levelValue = 5; //占空比调整
bit startFlag = 0; //启停标志
bit motorFlag = 1; //正反转标志
bit readRateFlag = 0; //读取速度标志
unsigned int rate; //速度值
unsigned long pulseNum; //脉冲计数
void Timer0_Init(void); //函数声明
void KeyProcess(void); //按键处理
void main(void)
{
L9110H_IN1 = 1;
L9110H_IN2 = 1;
Timer0_Init();
EX1 = 1; //外部中断1开
IT1 = 1; //边沿触发
EA = 1; //全局中断开
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
LCD_DispStr(0, 0, "Now: ");
LCD_DispOneChar(8, 0, 0xdf); //写入温度右上角点
LCD_DispOneChar(9, 0, 'C'); //写入字符C
LCD_DispStr(0, 1, "L: Rate: r/s");
LED_RED = 1;
LED_GREEN = 0;
while (1) //主循环
{
if (ReadTempFlag == 1)
{
EA = 0;
while(!DS18B20_GetTemp(&temp)); //读取温度
temperature = (float)temp * 0.0625; //温度转换
sprintf(dis0, "Now:%4.1f", temperature); //打印温度值
LCD_DispStr(0, 0, dis0);
LCD_DispOneChar(8, 0, 0xdf); //写入温度右上角点
LCD_DispOneChar(9, 0, 'C'); //写入字符C
EA = 1;
if (startFlag == 1)
{
LCD_DispStr(10, 0, " Start");
}
else
{
LCD_DispStr(10, 0, " Stop ");
}
sprintf(dis0, "L:%02d ", (int)levelValue); //打印等级
LCD_DispStr(0, 1, dis0);
if (temperature > 50) //高于报警温度
{
startFlag = 0; //电机停止
BUZZER = 0; //打开蜂鸣器
}
else
{
BUZZER = 1; //关闭蜂鸣器
}
ReadTempFlag = 0;
}
if (readRateFlag == 1)
{
readRateFlag = 0;
rate = pulseNum;
sprintf(dis0, "Rate:%03dr/s", rate); //打印速度
LCD_DispStr(5, 1, dis0);
EX1 = 1;
pulseNum = 0;
}
KeyProcess();
}
}
void KeyProcess(void)
{
if (!KEY_UP) //加速
{
DelayMs(20);
if(!KEY_UP)
{
if (levelValue <= 9)
levelValue++;
}
while(!KEY_UP);
}
if (!KEY_DOWN) //减速
{
DelayMs(20);
if(!KEY_DOWN)
{
if (levelValue > 1)
levelValue--;
}
while(!KEY_DOWN);
}
if (!KEY_FORWORD) //正转
{
DelayMs(20);
if(!KEY_FORWORD)
{
if (startFlag == 1)
{
startFlag = 0;
DelayMs(150);
startFlag = 1;
}
motorFlag = 1;
LED_RED = 1;
LED_GREEN = 0;
}
while(!KEY_FORWORD);
}
if (!KEY_BACK) //反转
{
DelayMs(20);
if(!KEY_BACK)
{
if (startFlag == 1)
{
startFlag = 0;
DelayMs(150);
startFlag = 1;
}
motorFlag = 0;
LED_RED = 0;
LED_GREEN = 1;
}
while(!KEY_BACK);
}
if (!KEY_START) //启动
{
DelayMs(20);
if(!KEY_START)
{
startFlag = 1;
}
while(!KEY_START);
}
if (!KEY_STOP) //停止
{
DelayMs(20);
if(!KEY_STOP)
{
startFlag = 0;
}
while(!KEY_STOP);
}
}
void Timer0_Init(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值 500us
PT0 = 1; //设置高优先级
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
static unsigned char IN1Count = 0;
static unsigned int numCount = 0;
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值 500us
if (startFlag == 1)
{
IN1Count++;
if (IN1Count < levelValue) //占空比调节
{
if (motorFlag == 1) //正转
{
L9110H_IN1 = 1;
L9110H_IN2 = 0;
}
if (motorFlag == 0) //反转
{
L9110H_IN1 = 0;
L9110H_IN2 = 1;
}
}
else if ((IN1Count >= levelValue) && (IN1Count <= 11)) //关闭时间段
{
L9110H_IN1 = 1;
L9110H_IN2 = 1; //关闭
}
else
{
IN1Count = 0; //一个周期结束
}
}
else
{
L9110H_IN1 = 1;
L9110H_IN2 = 1; //关闭
}
numCount++;
if (numCount > 2000)
{
EX1 = 0;
readRateFlag = 1;
numCount = 0;
}
if (numCount % 1000 == 0)
{
ReadTempFlag = 1;
}
}
/*------------------------------------------------
外部中断程序
------------------------------------------------*/
void ISR_Key(void) interrupt 2
{
pulseNum++;
}
设计文件:
链接:https://pan.baidu.com/s/1ddV_q1yAVGrjs-PhEeNtSA?pwd=mgkv