51单片机c语言指针 *,c语言,51单片机编程指针问题

代码主要有两个问题:

1、如果换成define定义的  DATA = cmd; 报错为什么?用P1 = cmd; 就没事

2、防抖动函数,不想每次都写,所以定义了一个子函数,但是调用的时候报错,应该是地址,指针的问题。sbit定义的变量不是端口的地址吗?

上代码:

#include    //包含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 <

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;//断电

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值