标题:
红外遥控开关 220V供电+485通信+DS18B20+继电器控制电路+蜂鸣器电路PCB+单片机程序
[打印本页]
作者:
woshizh
时间:
2019-8-3 19:19
标题:
红外遥控开关 220V供电+485通信+DS18B20+继电器控制电路+蜂鸣器电路PCB+单片机程序
本来想着做一块红外遥控的开关,来控制家里面的灯,在做的过程中,不断增加了一些功能,最后做成了一块开发板
原理图:
无标题2.png
(60.22 KB, 下载次数: 15)
下载附件
2019-8-3 19:17 上传
原理图PDF
Schematic_HS038.pdf
(102.18 KB, 下载次数: 51)
2019-8-3 19:18 上传
点击文件名下载附件
下载积分: 黑币 -5
板子的PCB图:
无标题.png
(64.29 KB, 下载次数: 19)
下载附件
2019-8-3 19:07 上传
PCB源文件:
HS038.zip
(20.71 KB, 下载次数: 49)
2019-8-3 19:10 上传
点击文件名下载附件
下载积分: 黑币 -5
代码:
源程序.zip
(788.14 KB, 下载次数: 54)
2019-8-3 19:15 上传
点击文件名下载附件
下载积分: 黑币 -5
源程序用于测试开发板各个部分的功能。(3P端子用于接温度传感器或者红外接收头)
单片机源程序如下:
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "ds18b20.h"
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
#define uchar unsigned char
#define uint unsigned int
uint wendu;
uchar cmd[12]={'\0'};
uchar str[]={'0','0','\0'};
uchar str1[]="℃ \n";
uchar cmd_count = 1;//字符数量计数器
uchar max_length = 10;//最大接收字符长度
uchar cmd_length = 0;//记录字符串长度
P3M1 = 0x00;//0000 0000
P3M0 = 0X04;//0000 0100
sbit IR=P3^2; //红外接口标志
sbit LED1 = P1^0;//指示
sbit LED2 = P1^1;//运行
//sbit JDQ = P2^3;//继电器
sbit FMQ = P2^2;//蜂鸣器
bit write=0;//写24C02的标志;
sbit sda=P2^0;//数据线
sbit scl=P2^1;//时钟线
sbit RST=P2^5; //时钟 不需要,可以关掉
sbit CS_DA =P2^4 ; //HJ-3G DAC HL-1不需要,可以关掉
sbit JD=P0^6;
unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
unsigned char irtime; //红外用全局变量
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
unsigned char Ir_work();
void Ircordpro(void);
void delay1ms(unsigned int z)
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=510;y>0;y--);
}
void tim0_isr (void) interrupt 1
{
irtime++; //用于计数2个下降沿之间的时间
}
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
i=0;
irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{
irtime=0;
startflag=1;
}
}
void TIM0init(void)//定时器0初始化
{
TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
ET0=1; //开中断
TR0=1;
}
void uart_init()
{
以下是使用独立波特率发生器
SCON=0x50; //[bit6:5]SM1 SM2 = 1 0;[bit4]REN=1
AUXR=0x11; //[bit4]BRTR=1,允许独立波特率发生器运行;[bit0]SIBRS=1,独立波特率作为串口1的波特率发生器,此时定时器1释放
BRT=0XF4; //独特波特率发生器定时器(产生波特率9600)
EA=1;
//ES=1;
TMOD = 0x20;//定时器1 工作模式2
TH1 = TL1 = 0XFD;//9600
SCON = 0X40;
//SM0 = 0;SM1 = 1;//方式1 8位波特率可变
REN = 1;
EA = 1;
ES = 1;//关闭串口中断,防止程序进入中断,无法正常工作。
TR1 = 1;
}
void EX0init(void)
{
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
EA = 1; //开总中断
}
unsigned char Ir_work()//红外键值散转程序
{
unsigned char temp = 0;
switch(IRcord[2])//判断第三个数码值
{
case 0x0c:temp = 1;break;//1 显示相应的按键值
case 0x18:temp = 2;break;//2
case 0x5e:temp = 3;break;//3
case 0x08:temp = 4;break;//4
case 0x1c:temp = 5;break;//5
case 0x5a:temp = 6;break;//6
case 0x42:temp = 7;break;//7
case 0x52:temp = 8;break;//8
case 0x4a:temp = 9;break;//9
default:break;
}
irpro_ok=0;//处理完成标志
return temp;
}
void Ircordpro(void)//红外码值处理函数
{
unsigned char i,j,k,cord,value;
k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
value=value|0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}
//void bee()
//{
// FMQ = 1;
// delay1ms(100);
//// FMQ = 1;
//// delay1ms(1000);
//}
void delay()
{ ;; }
void start() //开始信号
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop() //停止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons() //应答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
void init()
{
RST=0; //总线时钟低电评
CS_DA =0 ;
sda=1;
delay();
scl=1;
delay();
}
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void write_add(uchar address,uchar date)
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_add(uchar address)
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
void Buzzer(uint Number,uchar Time) //可以选择鸣响次数和音频
{
uchar h,j;
uint i ;
for (h = 0; h < Number; h ++)
{
for (i = 0; i < Time; i ++)
{
FMQ = ~FMQ; //BUZZER取反
for (j = 0 ; j < 100 ; j ++); //需要产生方波,调节音频
}
delay1ms(10); //间隔时间
}
FMQ = 0; //注意PNP=0;NPN=1关闭蜂鸣器,否则三极管电流会很大。
}
void send_char(unsigned char *str)
{
while(*str != '\0')
{
SBUF = *str;
while(TI == 0);
TI = 0;
str++;
}
}
uchar wendu_filter(uchar count)
{
uchar i=0;
uint sum = 0;
for(i=0;i<count;i++)
{
sum += ((uchar)(rd_temperature()));
}
return (uint)(sum/count);
}
void main(void)
{
uchar temp,high,med,low,min;
// uint wendu;
// uchar str[]={'0','0','\0'};
// uchar str1[]="℃ ";
uchar str2[]="send 1 and receive temperature\n";
uchar str5[12]={'\0'};
uchar i,rev_flag=0;
init();
EX0init(); //初始化外部中断
TIM0init();//初始化定时器
uart_init(); //定时器1 工作模式2
while(!init_ds18b20())//初始化失败
LED1 = 0;
TMOD = 0X22;//LED1 = 1;JDQ = 0;
write_add(2,2);
delay1ms(50);
FMQ = 0;
delay1ms(100);
// FMQ = 0;
while(1)//主循环
{
if(irok) //如果接收好了进行红外处理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
temp = Ir_work();
if(temp == 1)
{
JDQ = 1;
Buzzer(20,10);
}
if(temp == 2)
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
作者:
woshizh
时间:
2019-8-3 19:21
第一次发帖子,希望和大家交流学习
作者:
AnthonyDeng
时间:
2019-8-15 12:49
前排支持~~~~~
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1