单片机 蓝牙/WIFI无线遥控智能家居系统设计

在这里插入图片描述
main.c


#include <reg52.h>
#include <intrins.h>
               
#include "lcd1602.h"                                            /* 1602显示驱动文件 调用init和显示字符串2个函数 */
#include "ds18b20.h" 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>



typedef unsigned int u16;
typedef unsigned char u8;

typedef unsigned int uint;
typedef unsigned char uchar;
	

//以下是C调低音的音频宏定义
#define L1  262    //将"L1"宏定义为低音"1"的频率262Hz         时间是1/262=3826/2 us    取半周期
#define L2  286    //将"L2"宏定义为低音"2"的频率286Hz
#define L3  311    //将"L3"宏定义为低音"3"的频率311Hz
#define L4  349    //将"L4"宏定义为低音"4"的频率349Hz
#define L5  392    //将"L5"宏定义为低音"5"的频率392Hz
#define L6  440    //将"l_a"宏定义为低音"6"的频率440Hz
#define L7  494    //将"L7"宏定义为低音"7"的频率494Hz
//以下是C调中音的音频宏定义
#define Z1    523     //将"Z1"宏定义为中音"1"的频率523Hz
#define Z2    587     //将"Z2"宏定义为中音"2"的频率587Hz
#define Z3    659     //将"Z3"宏定义为中音"3"的频率659Hz
#define Z4    698     //将"Z4"宏定义为中音"4"的频率698Hz
#define Z5    784     //将"Z5"宏定义为中音"5"的频率784Hz
#define Z6    880     //将"Z6"宏定义为中音"6"的频率880Hz
#define Z7    987     //将"Z7"宏定义为中音"7"的频率523H      
//以下是C调高音的音频宏定义
#define H1  1046    //将"H1"宏定义为高音"1"的频率1046Hz
#define H2  1174    //将"H2"宏定义为高音"2"的频率1174Hz
#define H3  1318    //将"H3"宏定义为高音"3"的频率1318Hz
#define H4  1396    //将"H4"宏定义为高音"4"的频率1396Hz
#define H5  1567    //将"H5"宏定义为高音"5"的频率1567Hz
#define H6  1760    //将"H6"宏定义为高音"6"的频率1760Hz
#define H7  1975    //将"H7"宏定义为高音"7"的频率1975Hz

/*  ******************************************    */
//  ********   硬件端口定义   
/*  ******************************************    */
sbit sound = P2 ^ 3;    //蜂鸣器



/*  ******************************************    */
//  ********   程序变量定义
/*  ******************************************    */
unsigned int C;     //储存定时器的定时常数
unsigned char u, t;	 //音乐所用的变量
unsigned char velocity = 50;	//控制节拍使用的 这里100表示一个拍子100ms


/*  ******************************************    */
//  ********  音乐0	   天空之城
/*  ******************************************    */
//以下是《天空之城》简谱    //每行对应一小节音符
unsigned int code music0[]=
{	Z6,Z7,/**/H1,Z7,H1,H3,/**/Z7,Z3,Z3, /**/Z6,Z5,Z6,H1,/**/Z5,Z3,Z3, /**/Z4,Z3,Z4,H1,
	Z3,H1,H1,H1,/**/Z7,Z4,Z4,Z7,/**/Z7,Z6,Z7, /**/H1,Z7,H1,H3,/**/Z7,Z3,Z3, /**/Z6,Z5,Z6,H1,
	Z5, Z3,/**/Z4,H1,Z7,H1,/**/H2,H2,H2,H1,/**/H1,Z6,Z7,Z5,/**/Z6,H1,H2, /**/H3,H2,H3,H5,
	H2,Z5,Z5, /**/H1,Z7,H1,H3,/**/H3, /**/Z6,H1,Z7,H2,/**/H1,Z5,Z5, /**/H4,H3,H2,H1,
	H3, /**/Z3,H3, /**/H6,H5,H5, /**/H3,H2,H1,H1,/**/H2,H1,H2,H5,/**/H3,H3,
	H6,H5, /**/H3,H2,H1,H1,/**/H2,H1,H2,Z7,/**/Z6,Z6,Z7, /**/Z6,0xff}; //以0xff作为音符的结束标志      

//以下是简谱中每个音符的节拍
//"4"对应4个延时单位,"2"对应2个延时单位,"1"对应1个延时单位 
unsigned char code music0_JP[ ]=
{	4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,4,12,
	20,4,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8,
	32, 4, /**/8,4,6,8, /**/4,4,4,16, /**/8,4,6,8, /**/24,4,4, /**/12,4,8,8,
	24,4,4, /**/4,4,8,8, /**/32, /**/4,8,8,6, /**/12,4,16, /**/8,8,8,8,
	30, /**/20,8, /**/16,8,8, /**/4,4,16,8, /**/8,4,4,8, /**/20,8,
	16,16, /**/4,20,8, /**/8,4,4,8, /**/20,4,4, /**/32};

/*  ******************************************    */
/*  ********   延时100ms	控制音乐节拍 */
/*  ******************************************    */
void delay1()
{
	uint i, j;
	for ( i = 0; i < velocity; i++ )
		for ( j = 0; j < 125; j++ )
			;
}

/*********************************************************************************
 * 【函 数 名】: void SerInit(void)
 * 【功    能】: 串口初始化程序 设置波特率为9600
 **********************************************************************************/
//void SerInit( void )
//{
//	TMOD	= 0x20; /* 用定时器设置串口波特率	   9600 */
//	TH1	= 0xfd; /* 使用定时器1作为波特率发生器 9600波特率 */
//	TL1	= 0xfd;
//	TR1	= 1;
//	REN	= 1;    /* 串口初始化 */
//	SM0	= 0;
//	SM1	= 1;
//	EA	= 1;    /* 开启总中断 */
//	ES	= 1;    /* 串口中断 */
//}

#define FSOC 11059200L    //晶振
#define BAUD  9600        //波特率

/*
*********************************************************************************************************
*	函 数 名: bsp_InitUart
*	功能说明: 初始化CPU的U串口硬件设备。未启用中断。
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
void SerInit(void)
{
	SCON = 0x50;	/* 010 1 0000B,工作方式1, 8位UART,波特率可变,允许接收 */
	TMOD = 0x20;	/* T1工作于方式2 */
	TCON = 0x40;	/* 定时器1开始计数 */
	TH1 = -(FSOC/BAUD/12/16);		/* T1计数初值 */
	TL1 = -(FSOC/BAUD/12/16);
	PCON = 0x80;	/* SMOD置1,双倍速率 */
	RI = 0;
	TI = 0;
	
	ES = 1;//中断
	EA = 1;//总中断
	
}

/*********************************************************************************
 * 【函 数 名】: void send_cmd(unsigned char dat)
 * 【功    能】: 串口发送数据命令 						
 **********************************************************************************/
void send(unsigned char dat) {
	SBUF = dat;			 //发送指令到SBUF
	while (!TI)
		;			 //等待发送结束
	TI = 0;				 //清除结束标志,以便再发送数据
}
/*********************************************************************************
 * 【函 数 名】: Print_Str(unsigned char *s)
 * 【功    能】: 串口发送 一个字符串 				
 **********************************************************************************/
void Print_Str(unsigned char *s) {
	while (*s != '\0') {
		send(*s++);
	}
}
/* 显示温度 */
void DisplayTEMP( int value )
{
	unsigned char	disp[15];
	unsigned char	count=0;

	if ( value >= 0 )
	{
		disp[count++] = ' ';   
	} else {
		disp[count++] = '-';  
	}
	disp[count++]	= '0' + value % 1000 / 100;
	disp[count++]	= '0' + value % 100 / 10;
	disp[count++]	= '.';
	disp[count++]	= '0' + value % 10;
	disp[count++]	= 0xdf;
	disp[count++]	= 'C';
	disp[count++]	= 0;

	LCD_write_str( 5, 0, disp );
}

/* pwm初始化定时器0 */
void init_timer0_pwm( void )
{
	TMOD	&= 0xf0;
	TMOD	|= 0x01;        /* 定时器1为工作方式1  16bit */
	TH0	= (65536 - 1000) / 256;
	TL0	= (65536 - 1000) % 256;
	ET0	= 1;            /* 开定时器1中断 */
	TR0	= 1;            /* 关闭定时器 */
	EA	= 1;            /* 开总开关 */
}

/* 音乐初始化定时器0 */
void init_timer0_yinyue( void )
{
	TMOD	&= 0xf0;
	TR0	= 1;
	ET0	= 1;            /* 定时器T1中断允许 */
	EA	= 1;            /* 开总中断 */
}

int	temp;//温度
u8	pwm_count	= 0;
u8	ZHANKONGBI	= 5;    /* 值越大 小灯越亮 */
char	Txd_data	= 0;  //串口接收的数据
char	mode		= 0;  //模式0PWM 模式1音乐 模式2温度 其他模式值无所谓

/*  ******************************************    */
/*  ********   主函数 程序逻辑 */
/*  ******************************************    */
sbit DULA = P2 ^ 6;

sbit	WELA	= P2 ^ 7;
sbit	D6RL	= P0 ^ 6;


void main()
{
	LCD_init();//初始化
	LCD_write_str( 0, 1, "hello~" );
	
	
	SerInit();
	
	
	Print_Str("test");//测试用
	
	DULA=1;
	P0=0X00;
	DULA=0;
	
	WELA=1;
	P0=0X00;
	WELA=0;
	
	while ( 1 )
	{
		if ( mode == 1 )
		{
			u = 0;                                          /* 从第1个音符f[0]开始播放 */
			while ( music0[u] != 0xff )                     /* 只要没有读到结束标志就继续播放 */
			{
				C	= 460830 / music0[u];
				TH0	= (8192 - C) / 32;              /* 可证明这是13位计数器TH0高8位的赋初值方法     5 */
				TL0	= (8192 - C) % 32;              /* 可证明这是13位计数器TL0低5位的赋初值方法 */
				TR0	= 1;                            /* 启动定时器T0 */
				for ( t = 0; t < music0_JP[u]; t++ )    /* 控制节拍数 */
					delay1();                       /* 延时1个节拍单位 */
				TR0 = 0;                                /* 关闭定时器T1 */
				u++;                                    /* 播放下一个音符 */
			}
			TR0	= 0;                                    /* 关闭定时器 */
			sound	= 1;                                    /* 关闭蜂鸣器 */
		}else if ( mode == 2 )
		{
			temp = getTmpValue();
			DisplayTEMP( temp );
			
			sound	= 1;     
			
			delayMs(10);
		}
	}
}



void Uart_isr() interrupt 4             /* 中断接收程序 */
{
	if ( RI )                       /* 判断是否接收完,接收完成后,由硬件置RI位 */
	{
		Txd_data	= SBUF; /* 读入缓冲区 */
		RI		= 0;    /* 清标志 */
		SBUF		= Txd_data;
		while ( !TI )
			;               /* 等待发送结束 */
		TI = 0;                 /* 清除结束标志,以便再发送数据 */

	
	  
		
		if ( Txd_data == '1' )
		{
			WELA=1;
	    P0=0X00;
	    WELA=0;
			
			mode = 0;
			init_timer0_pwm();
		}else if ( Txd_data == '2' )
		{
			if ( ZHANKONGBI < 9 )
				ZHANKONGBI++;

			SBUF = '0' + ZHANKONGBI;
			while ( !TI )
				;       /* 等待发送结束 */
			TI = 0;         /* 清除结束标志,以便再发送数据 */
		}else if ( Txd_data == '3' )
		{
			
			
			if ( ZHANKONGBI > 0 )
				ZHANKONGBI--;

			SBUF = '0' + ZHANKONGBI;
			while ( !TI )
				;       /* 等待发送结束 */
			TI = 0;         /* 清除结束标志,以便再发送数据 */
		}else if ( Txd_data == '4' )
		{
			init_timer0_yinyue();
			mode = 1;
			
			WELA=1;
	    P0=0X00;
	    WELA=0;
			
		}else if ( Txd_data == '5' )
		{
			mode	= 5;
			WELA	= 1;    /* 改变电压之前先拉高 */
			D6RL	= 1;
			WELA	= 0;    /* 改变完了就拉低锁存 */
		}else if ( Txd_data == '6' )
		{
			mode	= 5;
			WELA	= 1;    /* 改变电压之前先拉高 */
			D6RL	= 0;
			WELA	= 0;    /* 改变完了就拉低锁存 */
		}else if ( Txd_data == '7' )
		{
			mode = 2;
			
			WELA=1;
	    P0=0X00;
	    WELA=0;
		}
	}
}


sbit LED = P1 ^ 0;
/* ==================定时器1中断服务程序=============== */
void timer0_server( void )
interrupt 1
{
	/* mode=0 pwm */
	if ( mode == 0 )
	{
		TH0	= (65536 - 1000) / 256;
		TL0	= (65536 - 1000) % 256;


		pwm_count++;
		if ( pwm_count == 10 )
		{
			pwm_count	= 0;
			LED		= 0;
		}
		if ( ZHANKONGBI == pwm_count )
		{
			LED = 1;
		}
	}else if ( mode == 1 )
	{
		/* mode=1 yinyue */
		sound	= !sound;               /* 将P3.7引脚输出电平取反,形成方波 */
		TH0	= (8192 - C) / 32;      /* 可证明这是13位计数器TH0高8位的赋初值方法 */
		TL0	= (8192 - C) % 32;      /* 可证明这是13位计数器TL0低5位的赋初值方法 */
	}
}



ds18b20.h

#include <reg52.h>
#include <intrins.h>
#include <math.h>



sbit ds = P2^2;
 

/******************************************/
//延时n   ms
/******************************************/
 void delayMs(unsigned int a)
{
    unsigned int i, j;
    for(i = a; i > 0; i--)
        for(j = 100; j > 0; j--);
 }

 
 /******************************************/
//初始化
/******************************************/
void dsInit()
 {
    
    unsigned int i;  
    ds = 0;
    i = 100;  
     while(i>0) i--;
    ds = 1;   
    i = 4;
     while(i>0) i--;
 }
 
void dsWait()
 {
      unsigned int i;
      while(ds);  
      while(~ds);
      i = 4;
      while(i > 0) i--;
}

/******************************************/
//读取一位
/******************************************/
bit readBit()
{
    unsigned int i;
    bit b;
    ds = 0;
    i++;   
    ds = 1; 
   i++; i++;  
    b = ds;
    i = 8; 
    while(i>0) i--;
    return b;
}
/******************************************/
//读取一个字节
/******************************************/
unsigned char readByte()
{
    unsigned int i;
    unsigned char j, dat;
   dat = 0;
    for(i=0; i<8; i++)
    {
        j = readBit();
      
        dat = (j << 7) | (dat >> 1);
    }
    return dat;
}

/******************************************/
//写入一个字节
/******************************************/
void writeByte(unsigned char dat)
{
    unsigned int i;
    unsigned char j;
    bit b;
    for(j = 0; j < 8; j++)
    {
        b = dat & 0x01;
        dat >>= 1;
    
        if(b)   
        {
           ds = 0;          i++; i++;  
            ds = 1;    
            i = 8; while(i>0) i--;  
        }
        else  
        {
            ds = 0;
          i = 8; while(i>0) i--;  
            ds = 1;
           i++; i++;
        }
   }
}
/******************************************/
//发送读取命令
/******************************************/
void sendChangeCmd()
{
    dsInit();    
    dsWait();   
    delayMs(1);    
    writeByte(0xcc);
    writeByte(0x44);
}
/******************************************/
//发送读取命令
/******************************************/
void sendReadCmd()
{
    dsInit();
    dsWait();
    delayMs(1);
    writeByte(0xcc); 
    writeByte(0xbe); 
}
/******************************************/
//获取温度  扩大了10倍
/******************************************/
int getTmpValue()
{
    unsigned int tmpvalue;
    int value; 
    float t;
    unsigned char low, high;
	
	EA=0;
	  sendChangeCmd();//ds18b20
	EA=1;
	
	  //delayMs(1000);
	
	EA=0;
    sendReadCmd();
    low = readByte(); 
    high = readByte();
	EA=1;
   
    tmpvalue = high;
    tmpvalue <<= 8;
    tmpvalue |= low;
    value = tmpvalue;
    
  
    t = value * 0.0625;
    
    value = t * 10 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
    return value;
		
}


lcd1602.h



#include <reg52.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
LCD_init();
LCD_write_str(1,1,"2223123");
*/

sbit lcd_rs=P3^5;
sbit lcd_rw=P3^6;
sbit lcd_en=P3^4;


#define DataPort P0

#define RS_CLR lcd_rs=0
#define RS_SET lcd_rs=1

#define RW_CLR lcd_rw=0

#define EN_CLR lcd_en=0
#define EN_SET lcd_en=1



void delay_lcd_ms(unsigned int a) {
	unsigned int i, j;
	for (i = a; i > 0; i--)
		for (j = 100; j > 0; j--)
			;
}
//***********************************************************************
//	显示屏命令写入函数
//***********************************************************************
void LCD_write_com(unsigned char com) 
{	
	RS_CLR;
	RW_CLR;
	EN_SET;
	DataPort = com;                 //命令写入端口
	delay_lcd_ms(5);
	EN_CLR;
}

//***********************************************************************
//	显示屏数据写入函数
//***********************************************************************
void LCD_write_data(unsigned char dataa) 
{
	RS_SET;
	RW_CLR;
	EN_SET;
	DataPort = dataa;                //数据写入端口
	delay_lcd_ms(5);
	EN_CLR;
}


//***********************************************************************
//	显示屏字符串写入函数
//***********************************************************************
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s) 
{
	
    if (y == 0) 
    {
    	LCD_write_com(0x80 + x);        //第一行显示
    }
    else 
    {
    	LCD_write_com(0xC0 + x);        //第二行显示
    }
    
    while (*s) 
    {
    	LCD_write_data( *s);
    	s ++;
    }
}


//***********************************************************************
//	显示屏初始化函数
//***********************************************************************
void LCD_init(void) 
{
	 LCD_write_com(0x38);		//显示模式设置  
    delay_lcd_ms(5);
	 LCD_write_com(0x38);		//显示模式设置  
    delay_lcd_ms(5);
	 LCD_write_com(0x38);		//显示模式设置  
    delay_lcd_ms(5);
	
	
    LCD_write_com(0x38);		//显示模式设置  
    delay_lcd_ms(5);
    LCD_write_com(0x08);		//显示关闭
    delay_lcd_ms(5);
    LCD_write_com(0x01);		//显示清屏
    delay_lcd_ms(5);
    LCD_write_com(0x06);		//显示光标移动设置
    delay_lcd_ms(5);
    LCD_write_com(0x0C);		//显示开及光标设置
    delay_lcd_ms(5);
}

猜你喜欢

转载自blog.csdn.net/x1131230123/article/details/107367337
今日推荐