一个经典的单片机课程设计。
主要用到的模块和资源有:LCD12864中文液晶模块,at24c02存储器模块用于存用户密码,ds18b20温度传感器模块,ISD1802语音模块用于语音报警,红外接收探头,用于接收红外键盘的信息、矩阵键盘4*4、红外势热,用于检测人体,GSM模块用于发送报警短信或者拨打用户手机等。IO口输入输出、串口发送。
编译环境:Uv4 for c51
主要的文件有:
#ifndef _GLOBAL_
#define _GLOBAL_
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit led=P2^0;
sbit beep=P2^3;
sbit Play=P2^4;
sbit PlayL=P2^5;
#include "key.h"
#include "ds18b20.h"
#include "12864.h"
#include "at24c02.h"
#include "app.h"
#include "gsm.h"
#include "hongwai.h"
#include "heat.h"
#endif
1、矩阵扫描程序:(分别扫描行列)
#include "key.h"
#define key P1
bit getnew = 0;
uchar keynum;
code uchar keyout[4] = {0x7f,0xbf,0xdf,0xef};
uchar Input_Code(void)
{
getnew = 0;
key_input();
if(getnew == 1)
{
getnew = 0;
switch (keynum)
{
case 1:return 'D';break;
case 2:return 'C';break;
case 3:return 'B';break;
case 4:return 'A';break;
case 5:return '#';break;
case 6:return '9';break;
case 7:return '6';break;
case 8:return '3';break;
case 9:return '0';break;
case 10:return '8';break;
case 11:return '5';break;
case 12:return '2';break;
case 13:return '*';break;
case 14:return '7';break;
case 15:return '4';break;
case 16:return '1';break;
default:return keynum;break;
}
}
else return 0;
}
static void key_input(void)
{
uchar i;
key = 0X0F;
if((key|0XF0) != 0XFF)
{
delay(10);
if((key|0XF0) != 0XFF)
{
for(i = 0;i < 4;i++)
{
key = keyout[i];
keynum = key;
while((key|0XF0) != 0XFF);
switch(keynum|0XF0)
{
case 0XF7:
keynum = (i*4+1);
getnew = 1;
return ;break;
case 0XFB:
keynum = (i*4+2);
getnew = 1;
return ;break;
case 0XFD:
keynum = (i*4+3);
getnew = 1;
return ;break;
case 0XFE:
keynum = (i*4+4);
getnew = 1;
return ;break;
}
}
}
}
}
2、温度传感器读取温度
#include"DS18B20.h"
int temp;
float temp_get()
{
float tt;
uchar a,b;
temp_start();
temp_reset();
temp_delay(1);
temp_writebyte(0xcc);
temp_writebyte(0xbe);
a=temp_readbyte();
b=temp_readbyte();
temp=b;
temp<<=8;
temp=temp|a;
tt=temp*0.0625;
tt=(uint)(tt*10+0.5);
tt=tt/10;
return tt;
}
static void temp_delay(uint count)
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
static void temp_reset(void)
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
static bit temp_readbit(void)
{
uint i;
bit dat;
DS=0;i++;
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
static uchar temp_readbyte(void)
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=temp_readbit();
dat=(j<<7)|(dat>>1);
}
return(dat);
}
static void temp_writebyte(uchar dat)
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)
{
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++;
}
}
}
static void temp_start(void)
{
temp_reset();
temp_delay(1);
temp_writebyte(0xcc);
temp_writebyte(0x44);
}
//static void temp_readrom()
//{
// uchar sn1,sn2;
// temp_reset();
// temp_delay(1);
// temp_writebyte(0x33);
// sn1=temp_readbyte();
// sn2=temp_readbyte();
//}
3、12864液晶显示
#include "12864.h"
sbit LCD_RS = P3^5;
sbit LCD_RW = P3^6;
sbit LCD_EN = P3^7;
sbit LCD_PSB = P2^1;
#define delay_nop(); {_nop_();_nop_();_nop_();_nop_();};
#define data_port P0
void delay(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
void lcd_init()
{
LCD_PSB = 1;
lcd_writecmd(0x34);
delay(5);
lcd_writecmd(0x30);
delay(5);
lcd_writecmd(0x0C);
delay(5);
lcd_writecmd(0x01);
delay(5);
}
void lcd_clean(void)
{
lcd_writecmd(0x01);
delay(5);
}
void lcd_show(uchar x, uchar y,uchar *cn)
{
uchar i = 0;
lcd_pos(x,y);;
while(cn[i] != '\0')
lcd_writedata(cn[i++]);
}
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delay_nop();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
void lcd_pos(uchar x,uchar y)
{
uchar pos;
if (y==0)
{y=0x80;}
else if (y==1)
{y=0x90;}
else if (y==2)
{y=0x88;}
else if (y==3)
{y=0x98;}
pos = x+y ;
lcd_writecmd(pos);
}
void lcd_writecmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
data_port = cmd;
delay_nop();
LCD_EN = 1;
delay_nop();
LCD_EN = 0;
}
void lcd_writedata(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
data_port = dat;
delay_nop();
LCD_EN = 1;
delay_nop();
LCD_EN = 0;
}
4、红外键盘输入
/*
Óõ½Òý½Å: 3.2
Óõ½ÍâÉè: ¶¨Ê±Æ÷0 ¡¢ÍⲿÖÐ¶Ï 0
Ïȵ÷ÓÃir_init()½øÐгõʼ»¯,ÔÙµ÷ÓÃir_get()µÃµ½ºìÍâ½ÓÊÕµÄÖµ
*/
#include "hongwai.h"
uchar irtime; /*ÓÃÓÚ¼Æʱ*/
uchar ir_data; /*ºìÍâ×îºóµÄµ½µÄÖµ*/
uchar ircord[4]; /*´æ·Å½âµÃµÄÂð*/
uchar irdata[33]; /*´æ·ÅºìÍâÂë*/
static bit startflag = 0; /*ÊÇ·ñ¿ªÊ¼´¦Àí±ê־λ*/
static bit getnew = 0;
void HW_Init(void) /*ºìÍâ³õʼ»¯*/
{
timer0_init();
EX0_init();
}
uchar HW_get(void) /*·µ»ØºìÍâµÃµ½µÄÖµ*/
{
if(getnew == 1)
{
getnew = 0;
switch (ir_data)
{
case 0x16:return '0';break;
case 0x0c:return '1';break;
case 0x18:return '2';break;//2
case 0x5e:return '3';break;//3
case 0x08:return '4';break;//4
case 0x1c:return '5';break;
case 0x5a:return '6';break;
case 0x42:return '7';break;
case 0x52:return '8';break;
case 0x4a:return '9';break;
case 0x19:return '*';break;
case 0x0d:return '#';break;
default:return ir_data;break;
}
}
else return 0;
}
/*ÄÚ²¿º¯Êý*/
static void timer0_init(void) /*¶¨Ê±Æ÷0³õʼ»¯*/
{
TMOD|=0x02;/*¶¨Ê±Æ÷0¹¤×÷·½Ê½2£¬TH0ÊÇÖØ×°Öµ£¬TL0ÊdzõÖµ*/
TH0=0x00;/*ÖØÔØÖµ*/
TL0=0x00; /*³õʼ»¯Öµ*/
ET0=1;/*¿ªÖжÏ*/
TR0=1;
}
static void EX0_init(void) /*ÍⲿÖжÏ0³õʼ»¯*/
{
IT0 = 1;/*Ö¸¶¨ÍⲿÖжÏ0ϽµÑØ´¥·¢£¬INT0 (P3.2)*/
EX0 = 1;/*ʹÄÜÍⲿÖжÏ*/
EA = 1;/*¿ª×ÜÖжÏ*/
}
static void ircordpro(void) /*ºìÍâÂëÖµ´¦Àíº¯Êý*/
{
uchar i, j, k;
uchar value;
k=1;
for(i=0;i<4;i++) /*´¦ÀíÒ»¶ÎºìÍâÂë4¸ö×Ö½Ú*/
{
for(j=1;j<=8;j++) /*´¦Àí1¸ö×Ö½Ú8λ*/
{
/*´óÓÚijֵΪ1£¬Õâ¸öºÍ¾§ÕñÓоø¶Ô¹Øϵ£¬ÕâÀïʹÓÃ12M¼ÆË㣬´ËÖµ¿ÉÒÔÓÐÒ»¶¨Îó²î*/
if(irdata[k]>7)value|=0x80;
if(j<8)value>>=1;
k++;
}
ircord[i]=value;
value=0;
}
if(ircord[2] == ~ircord[3])
{
ir_data = ircord[2];
getnew = 1;
}
}
/*Öжϴ¦Àíº¯Êý*/
void tim0_isr (void) interrupt 1 using 1
{
irtime++; /*ÓÃÓÚ¼ÆÊý2¸öϽµÑØÖ®¼äµÄʱ¼ä*/
}
void EX0_ISR (void) interrupt 0 /*ÍⲿÖжÏ0·þÎñº¯Êý*/
{
static uchar i; /*½ÓÊÕºìÍâÐźŴ¦Àí*/
if(startflag)
{
if(irtime<63&&irtime>=33)i=0; /*Òýµ¼Âë TC9012µÄÍ·Â룬9ms+4.5ms*/
irdata[i]=irtime; /*´æ´¢Ã¿¸öµçƽµÄ³ÖÐøʱ¼ä£¬ÓÃÓÚÒÔºóÅжÏÊÇ0»¹ÊÇ1*/
irtime=0;
i++;
if(i==33)
{
i=0;
ircordpro(); /*ºìÍâÂëÖµ´¦Àí*/
}
}
else
{
irtime=0;
startflag=1;
}
}
5、GSM发送短信
#include "gsm.h"
/***********************************************************
º¯ÊýÃû³Æ£ºPrint_Char
º¯Êý¹¦ÄÜ£º·¢Ë͵¥¸ö×Ö·û
Èë¿Ú²ÎÊý:ch ³ö¿Ú²ÎÊý£ºÎÞ
***********************************************************/
void Print_Char(uchar ch)//·¢Ë͵¥¸ö×Ö·û
{
SBUF=ch; //ËÍÈ뻺³åÇø
while(!TI); //µÈ´ý·¢ËÍÍê±Ï
TI=0; //Èí¼þÇåÁã
}
/***********************************************************
º¯ÊýÃû³Æ£ºPrint_Str
º¯Êý¹¦ÄÜ£º·¢ËÍ×Ö·û´®
Èë¿Ú²ÎÊý:*str ³ö¿Ú²ÎÊý£ºÎÞ
***********************************************************/
void Print_Str(uchar *str1)//·¢ËÍ×Ö·û´®
{
unsigned char i = 0;
while(str1[i] != '\0')
{
SBUF = str1[i];
while(!TI); // µÈÌØÊý¾Ý´«ËÍ
TI = 0; // Çå³ýÊý¾Ý´«ËͱêÖ¾
i++; // ÏÂÒ»¸ö×Ö·û
}
}
/***********************************************************
º¯ÊýÃû³Æ£ºIni_UART
º¯Êý¹¦ÄÜ£º´®¿Ú³õʼ»¯¡¢¶¨Ê±Æ÷³õʼ»¯
Èë¿Ú²ÎÊý:ÎÞ ³ö¿Ú²ÎÊý£ºÎÞ
***********************************************************/
void Init_UART(void)//´®¿Ú³õʼ»¯¡¢¶¨Ê±Æ÷³õʼ»¯
{
TMOD=0x20;
TH1=0xfa;
TL1=0xfa; //UART²¨ÌØÂÊÉèÖÃ:9600
TR1=1;
SM0=0;
SM1=1;
REN=1;
EA=1;
PCON=0x80;
}
void Send_Message(void)
{
lcd_clean();
lcd_show(0,0," °²È«¾¯¸æ");
lcd_show(0,1,"±¨¾¯¶ÌÐÅ·¢ËÍÖÐ..");
Print_Str("AT+CNMI=2,1");
Print_Str("\r\n");
delay(200);
Print_Str("AT+CMGF=1");
Print_Str("\r\n");
delay(200);
Print_Str("AT+CMGS=\"1111111111\"");//phone number
Print_Str("\r\n");
delay(1000);
Print_Str("Smart House System: Warning, your house is under danger! ");
Print_Char(0x1a); //·¢ËͶÌÐÅ
delay(10);
lcd_show(0,2," ÒÑ·¢ËÍ");
delay(2000);
lcd_clean();
}
// Print_Str("AT+CPMS=\"SM\"");
// delay(1000);
6、AT24C02存储器芯片(IIC接口)
#include "at24c02.h"
sbit sda=P2^7;
sbit scl=P2^6;
void nop()
{
_nop_();
_nop_();
}
//void delay1(unsigned int m)
//{
// unsigned int n;
// for(n=0;n<m;n++);
//}
void AT24C02_Init()
{
scl=1;
nop();
sda=1;
nop();
}
void start()
{
sda=1;
nop();
scl=1;
nop();
sda=0;
nop();
scl=0;
nop();
}
void stop()
{
sda=0;
nop();
scl=1;
nop();
sda=1;
nop();
}
void writebyte(unsigned char j)
{
unsigned char i,temp;
temp=j;
for (i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
nop();
sda=CY;
nop();
scl=1;
nop();
}
scl=0;
nop();
sda=1;
nop();
}
unsigned char readbyte()
{
unsigned char i,j,k=0;
scl=0; nop(); sda=1;
for (i=0;i<8;i++)
{
nop(); scl=1; nop();
if(sda==1)
j=1;
else
j=0;
k=(k<<1)|j;
scl=0;
}
nop();
return(k);
}
void clock()
{
unsigned char i=0;
scl=1;
nop();
while((sda==1)&&(i<255))
i++;
scl=0;
nop();
}
uchar read24c02( uchar address)
{
unsigned char i;
start();
writebyte(0xa0);
clock();
writebyte(address);
clock();
start();
writebyte(0xa1);
clock();
i=readbyte();
stop();
delay(10);
return(i);
}
//void write24c02(unsigned char address,unsigned char info)
//{
// start();
// writebyte(0xa0);
// clock();
// writebyte(address);
// clock();
// writebyte(info);
// clock();
// stop();
// delay(500);
//}
主要业务逻辑函数app.c
#include "app.h"
uchar CodeInput[5]=0; //keyborad input
uchar CodeRead[5]; //at24c02 read
//uint ErrorTime = 0; //input wrong code
uint Lock_STA=1;
/*ϵͳ¹¤×÷½çÃæ*/
void Main_Menu(void)
{
lcd_show(0,0,"ÖÇÄܼҾӱ¨¾¯ÏµÍ³");
if(Lock_STA){
lcd_show(0,1," ¹¤×÷ÖÐ..");
lcd_show(0,2,"°´ÈÎÒâ¼üÊäÈëÃÜÂë: ");
}
}
/*Óû§Ö÷½çÃæ*/
void Wel_Menu()
{
uchar key_temp='0';
uint cnt=0;
Lock_STA=0; //ÄܽøÈ뻶ÓÒ³Ã棬֤Ã÷ÒѾ½âËø
lcd_clean();
lcd_show(0,0," ÌøתÖÐ..");
delay(800);
lcd_clean();
lcd_show(1,0,"Welcome Home");
lcd_show(0,1,"ζȣº");
lcd_show(4,1,"¡æ");
// lcd_show(0,1,"°´* ¼üÍ˳ö");
// lcd_show(0,2,"°´D ¼ü·¢ËͶÌÐÅ");
while(1){
if(cnt%100 == 0) /*ÿ1 ÃëË¢Ò»´ÎζÈ*/
{
cnt=0;
Get_Temperture();
}
cnt++;
delay(10);
lcd_show(0,2,"°´* ¼üÖØÐÂÉÏËø");
if(Input_Code()=='*') {Lock_STA=1;break;}
// key_temp=Input_Code();//||HW_get();
// switch(key_temp){
// case '1': ;break; //code Adjust
// case '*': Lock_STA=1;return;break; //lock again
// case '#': ;break;
// case 'A': ;break;
// default: break;
// }
}
lcd_show(3,3,"ÒÑËø¶¨");
delay(500);
}
/*¶ÁȡζȲ¢ÏÔʾ*/
void Get_Temperture()
{
uchar temp_num = 0; /*ÓÃÓÚ´¢´æζÈÖµ*/
uchar tempstr[3] = 0; /*ÓÃÓÚ´¢´æζÈÖµ×Ö·û´®*/
temp_num = temp_get();
tempstr[0] = (temp_num/10)+'0';
tempstr[1] = (temp_num%10)+'0';
tempstr[2] = '\0';
lcd_show(3,1,tempstr);
}
/*ÊäÈëÃÜÂ룬ÒÔ#ºÅ¼ü½áÊø*/
void Code_Input()
{
uchar key_temp='0',tempcode[2]=0;
uint cnt=0,count=0;
while(key_temp!='#'){
if(((key_temp=Input_Code())!=0)||((key_temp=HW_get())!=0)){
tempcode[0]=key_temp;
tempcode[1]='\0';
lcd_show(cnt,3,tempcode);
CodeInput[cnt]=key_temp;
cnt++;
if(cnt>=8)cnt=0;
led=~led;
}
}
cnt--;
CodeInput[cnt]='\0';
// lcd_show(4,3,CodeInput);
}
//void Code_Init()
//{
// uint cnt_24=0;
// for(cnt_24=0;cnt_24<4;cnt_24++){ //дÈë³õʼÃÜÂë
// write24c02(cnt_24+16,'1');
// }
//}
void Read_Code()
{
uint cnt_24,count=0;
for(cnt_24=0;cnt_24<4;cnt_24++){ //´Ó´æ´¢Æ÷¶ÁÃÜÂë
CodeRead[count]=read24c02(cnt_24+16);
count++;
}
CodeRead[count]='\0';
// lcd_show(0,3,CodeRead);
}
//Input Code Accepted, return 1;
int Code_Judge()
{//CodeRead:´Ó´æ´¢Æ÷¶Áµ½µÄÃÜÂë
//CodeInput:´Ó¼üÅÌÊäÈëµÄÃÜÂë
uint i;
Read_Code();
for(i=0;i<sizeof(CodeRead);i++){
if(CodeInput[i]==CodeRead[i])
continue;
else break;
}
if(i>=sizeof(CodeRead)) return 1;
else return 0;
}
void USER_Ammited()
{
uint ErrorCnt=0;
while(1)
{
lcd_clean();
Main_Menu(); //main menu
Code_Input(); //key in code
if(Code_Judge()){ //ÃÜÂëÑéÖ¤
break;
}
else{
ErrorCnt++;
if(ErrorCnt>=3)
{Vol_Display();Send_Message();return;} //ÃÜÂëÊäÈë´ÎÊý³¬¹ý3´Î£¬·¢Ëͱ¨¾¯¶ÌÐÅ
lcd_show(0,2,"ÃÜÂë´íÎó£¬ÇëÖØÊÔ");
beep = 0;
delay(2000);
beep = ~beep;
}
}
Wel_Menu(); //enter welcome menu
}
void Vol_Display()
{
Play=1;
Play=0;
Play=0;
}
void Heat_Warning()
{//
uchar temp_num = 0;
temp_num = temp_get();
if(temp_num=='50'||temp_num=='51'||temp_num=='52')
Send_Message();
}