代码主要有两个问题:
1、如果换成define定义的 DATA = cmd; 报错为什么?用P1 = cmd; 就没事
2、防抖动函数,不想每次都写,所以定义了一个子函数,但是调用的时候报错,应该是地址,指针的问题。sbit定义的变量不是端口的地址吗?
上代码:
#include <reg52.h> //<reg51.h>包含52单片机寄存器库
typedef unsigned int u16;//函数别名,以下程序u16代表int,u8代表char
typedef unsigned char u8;
sbit led1 = P0^0;//控制灯的继电器,开关由光感和人数决定
sbit led2 = P0^1;
sbit led3 = P0^2;
sbit power = P2^6;//总电源开关
#define DATA = P1;//定义LDC1602数据端口
sbit rs = P0^3;//定义LDC1602控制端口
sbit rw = P0^4;
sbit en = P0^5;
sbit SR501_1 = P0^6;//定义两红外个人体感应模块
sbit SR501_2 = P0^7;
sbit light1 = P2^0;//定义三个光敏传感器,采用DO模式,与控制灯的继电器一一对应
sbit light2 = P2^1;
sbit light3 = P2^2;
sbit MQ_1 = P2^3;//定义烟雾传感器,低电平有效
sbit MQ_vcc = P2^4;
sbit buzzer = P2^5;//定义蜂鸣器
u8 people = 0;//人的个数
u8 num = 0;
u8 temp = 1;//烟雾模块取值存放
void delay(u16 num)//延时函数,延时时间=num*1ms
{
u8 x,y;
for(x=num; x>0; x--)
for(y=110; y>0; y--)
{
;//延时1ms
}
}
void write_cmd (u8 cmd)//LDC1602命令指令输入
{
rs = 0;
rw = 0;
P1 = cmd; //如果换成 DATA = cmd; 报错为什么
delay(5);
en = 1;
delay(5);
en = 0;
}
void write_data (u8 dat)//LDC1602数据指令输入
{
rs = 1;
rw = 0;
P1 = dat;
delay(5);
en = 1;
delay(5);
en = 0;
}
void lcd_init (void)//LDC1602初始化操作
{
write_cmd(0x02);
write_cmd(0x06);
write_cmd(0x0c);
write_cmd(0x38);
write_cmd(0x01);
}
u8 read_bit (u8 *ptr)//读端口操作,输入参数ptr是之前定义的端口地址,返回参数是char类型的
{ //我用的是51单片机,读端口要防抖动,不想每次都写,所以写了这个子函数
u8 temp = 0; //但是调用出错,而且还是第一个报错,屏蔽没用他会让屏蔽后的第一次调用报错
temp = ptr;
if (temp != 0)
{
delay(5);
temp = ptr;
if (temp != 0)
{
temp = ptr;
return temp;
}
}
}
void SR501_read(void)//检测人员进出个数
{
u8 num1,num2;
num1 = read_bit(SR501_1);//这里的SR501_1是我sbit定义的端口,这个变量不应该是个地址吗
num2 = read_bit(SR501_1);//有人为高电平,没人低电平
num2 = num2 << 1;//此处人体感应模块二左移做高位,人体感应模块一做地位,链接实际电路再做调整
num2 = num2 || num1;
switch (num2){//通过判断num2取值大小决定人员进入或出去
case 0:break ;
case 1:people++;break;
case 2:if (people != 0)people--;break;
case 3:break;
default:break;
}
}
void smart_sw(void)
{
u8 num1,num2,num3;
num1 = read_bit(light1);//光强度低于光敏传感器高电平,光强度高于光敏传感器低电平
num2 = read_bit(light2);
num3 = read_bit(light3);
if (people != 0)//如果有人,那么一个光敏传感器控制一个灯
{
led1 != num1;
led2 != num2;
led3 != num3;
}
else if(people == 0)//如果没人,灯全部熄灭
{
led1 = led2 = led3 = 1;//连等不成立的话分开写
}
}
void init_MQ(void)//中断初始化,烟雾模块要很长时间预热才稳定,用定时器中断取值
{
TMOD = 0x01;
TH0 = 0xd8;
TL0 = 0xf0;
EA = 1;
ET0 = 1;
TR0 = 1;
MQ_vcc = 1;
}
void main (void)
{
rw = 0;//初始化LDC1602
rs = 0;
en = 0;
lcd_init();
write_cmd(0xc0);//定义光标位置(起始输入位置)
SR501_1 = 0;//初始化两个人体感应模块
SR501_2 = 0;
led1 = led2 = led3 = 1;//初始化灯
MQ_vcc = 0;
while(1) //大循环
{
write_data('I');//输入显示数据
SR501_read();//检测人员进出个数
smart_sw();//智能开关灯
init_MQ();//烟雾报警检测
}
}
void MQ_interrupt(void) interrupt 1
{
TH0 = 0xd8;
TL0 = 0xf0;
num++;
if(num == 100)
{
temp = MQ_1;
num = 0;
if (temp == 0)//发生火警
{
temp = 1;//temp重置
led1 = led2 = led3 = 1;//开灯
power = 0;//断电
}
}
}
慕沐8561609
AAnonymous