功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶显示当前进出库记录及车位数,同时蓝牙串口上报停车场的数据
2.红外避障模块检测驶入驶出
3.按键可手动更改车位情况
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include <reg52.h> //调用单片机头文件
#include <intrins.h>
#include <stdio.h>
#include <lcd.h>
//波特率设置
#define OSC 11059200 //11.0592MHz
// #define OSC 12000000 //12MHz
// 定时器寄存器值预处理
#define BAUDRATE 9600
#define RH_UART (256-((OSC/12/32) / BAUDRATE))
sbit INFRARED_IN = P2^0; //进入检测红外探头
sbit INFRARED_OUT = P2^1; //驶出检测红外探头
sbit KEY_ADD = P3^4; //按键加
sbit KEY_SUB = P3^6; //按键减
sbit BEEP = P2^2; //蜂鸣器
uchar num_jin; //进入计数
uchar num_chu; //驶出计数
uchar num_car; //停车计数
bit sendFlag = 1; //发送标志
bit oldPinState1 = 0;
bit nowPinState1 = 0;
bit oldPinState2 = 0;
bit nowPinState2 = 0;
/************************* t*10us延时 *************************/
void DelayUs10x(unsigned char t)
{
do
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
/************************* 定时器0初始化 *************************/
void Timer0_Init()
{
TMOD &= 0xF0; //Timer0 16位装载
TMOD |= 0x01;
TL0 = 0x00; //设置定时初始值
TH0 = 0x4C; //设置定时初始值 50ms
TR0 = 1; //开启T0计时
ET0 = 1; //打开T0中断
EA = 1; //打开总中断
}
/************************* 串口初始化 *************************/
void UART0_Init()
{
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20; //8位自动重装
TH1 = RH_UART;
TL1 = TH1;
ET1 = 0; //禁止T1中断
TR1 = 1; //启动T1计时
//ES = 1; //打开串口中断
EA = 1; //打开总中断
}
void UART0_SendByte(unsigned char dat) //串口发送单字节数据
{
unsigned char time_out;
time_out = 0x00;
SBUF = dat; //将数据放入SBUF中
while ((!TI) && (time_out < 100)) //检测是否发送出去
{
time_out++;
DelayUs10x(2);
} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void UART0_SendStr(unsigned char *str) //发送定长度字符串
{
unsigned char *tmp;
unsigned char cnt = 0;
unsigned char length = 0;
tmp = str;
while (*(tmp++) != '\0')
{
length++;
}
while (cnt < length) //发送长度对比
{
UART0_SendByte(*str); //发送单字节数据
str++; //指针++
cnt++; //下一个++
}
}
/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
uint i, j;
for (i = 0; i < q; i++)
for (j = 0; j < 120; j++)
;
}
void key() //独立按键程序
{
/***********************手动修改小区内停车位*************************************/
if (!KEY_ADD) //按键加
{
delay_1ms(20);
if (!KEY_ADD)
{
if (num_car < 4)
{
num_car++;
}
else
{
BEEP = 0;
}
write_sfm2(1, 4, num_jin);
write_sfm2(1, 12, num_chu);
write_sfm2(2, 4, num_car);
write_sfm2(2, 12, 4 - num_car);
}
while (!KEY_ADD);
BEEP = 1;
}
if (!KEY_SUB) //按键减
{
delay_1ms(20);
if (!KEY_SUB)
{
if (num_car >= 1)
{
num_car--;
}
else
{
BEEP = 0;
}
write_sfm2(1, 4, num_jin);
write_sfm2(1, 12, num_chu);
write_sfm2(2, 4, num_car);
write_sfm2(2, 12, 4 - num_car);
}
while (!KEY_SUB);
BEEP = 1;
}
}
/***************主函数*****************/
void main()
{
unsigned char dis[16];
BEEP = 1;
Timer0_Init();
UART0_Init();
init_1602();
write_string(1, 0, "IN : OUT:");
write_string(2, 0, "Car: P:");
write_sfm2(1, 4, num_jin); //进入车辆数显示
write_sfm2(1, 12, num_chu); //驶出车辆数显示
write_sfm2(2, 4, num_car); //停车数显示
write_sfm2(2, 12, 4 - num_car); //空余车位显示
while (1)
{
nowPinState1 = INFRARED_IN;
if (oldPinState1 == 1 && nowPinState1 == 0) //检测到探头1下降沿,汽车驶入
{
if (num_car < 4)
{
num_car++;
if (num_jin <= 255)
{
num_jin++;
}
}
else
{
BEEP = 0;
delay_1ms(200);
delay_1ms(200);
delay_1ms(200);
BEEP = 1;
}
write_sfm2(1, 4, num_jin);
write_sfm2(1, 12, num_chu);
write_sfm2(2, 4, num_car);
write_sfm2(2, 12, 4 - num_car);
}
oldPinState1 = nowPinState1; //记录上一次电平
nowPinState2 = INFRARED_OUT;
if (oldPinState2 == 1 && nowPinState2 == 0) //检测到探头2下降沿, 汽车驶出
{
if (num_car >= 1)
{
num_car--;
if (num_chu <= 255)
{
num_chu++;
}
}
write_sfm2(1, 4, num_jin);
write_sfm2(1, 12, num_chu);
write_sfm2(2, 4, num_car);
write_sfm2(2, 12, 4 - num_car);
}
oldPinState2 = nowPinState2; //记录上一次电平
if (sendFlag == 1) //蓝牙串口发送
{
sendFlag = 0;
sprintf(dis, "IN:%02d OUT:%02d\r\n", (uint)num_jin, (uint)num_chu);
UART0_SendStr(dis);
delay_1ms(20);
sprintf(dis, "Car:%02d P:%02d\r\n", (uint)num_car, (uint)(4 - num_car));
UART0_SendStr(dis);
}
key(); //独立按键程序
}
}
/************************* 定时器0中断 *************************/
void Timer0_Intterupt() interrupt 1
{
static unsigned char time50ms = 0;
TL0 = 0x00; //设置定时初始值
TH0 = 0x4C; //设置定时初始值 50ms
time50ms++;
if (time50ms > 100) //5s
{
sendFlag = 1;
time50ms = 0;
}
}