题目
硬件
用到 单片机三块 一个主控 两个副控 分为主路控制器和支路控制器
两个LED灯
一个LCD屏幕
两个红外感应
两个双端光敏电阻
一个三端光敏电阻
以及 时钟模块
代码
主要模块代码
主控
#include <REGX52.H>
#include "DS1302.h"
#include "LCD1602.h"
#include "XPT2046.h"
#include "MatrixKey.h"
#include "Buzzer.h"
unsigned char Key=0;
unsigned char Time[] = {24,10,10,17,59,55,1};//
unsigned char SetTimeA[] = {18,0,5};
unsigned char OffTimeA[] = {6,0,0};
unsigned char SetTimeB[] = {18,0,10};
unsigned char OffTimeB[] = {6,0,0};
unsigned char WT;
unsigned char ADValue;
unsigned char ifopen = 0;
unsigned int TimeO;
unsigned int TimeA;
unsigned int TimeB;
///
void LCD_time()
{
DS1302_ReadTime();
LCD_ShowNum(1,1,DS1302_Time[0],2);
LCD_ShowChar(1,3,'/');
LCD_ShowNum(1,4,DS1302_Time[1],2);
LCD_ShowChar(1,6,'/');
LCD_ShowNum(1,7,DS1302_Time[2],2);
LCD_ShowNum(2,1,DS1302_Time[3],2);
LCD_ShowChar(2,3,':');
LCD_ShowNum(2,4,DS1302_Time[4],2);
LCD_ShowChar(2,6,':');
LCD_ShowNum(2,7,DS1302_Time[5],2);
}
void LCD_ShowTimechange()
{
LCD_ShowNum(1,1,Time[0],2);
LCD_ShowChar(1,3,'/');
LCD_ShowNum(1,4,Time[1],2);
LCD_ShowChar(1,6,'/');
LCD_ShowNum(1,7,Time[2],2);
LCD_ShowNum(2,1,Time[3],2);
LCD_ShowChar(2,3,':');
LCD_ShowNum(2,4,Time[4],2);
LCD_ShowChar(2,6,':');
LCD_ShowNum(2,7,Time[5],2);
}
void LCD_ShowSetTimeA()
{
LCD_ShowNum(2,1+8,SetTimeA[0],2);
LCD_ShowChar(2,3+8,':');
LCD_ShowNum(2,4+8,SetTimeA[1],2);
LCD_ShowChar(2,6+8,':');
LCD_ShowNum(2,7+8,SetTimeA[2],2);
}
void LCD_ShowOffTimeA()
{
LCD_ShowNum(1,1+8,OffTimeA[0],2);
LCD_ShowChar(1,3+8,':');
LCD_ShowNum(1,4+8,OffTimeA[1],2);
LCD_ShowChar(1,6+8,':');
LCD_ShowNum(1,7+8,OffTimeA[2],2);
}
void LCD_ShowSetTimeB()
{
LCD_ShowNum(2,1+8,SetTimeB[0],2);
LCD_ShowChar(2,3+8,':');
LCD_ShowNum(2,4+8,SetTimeB[1],2);
LCD_ShowChar(2,6+8,':');
LCD_ShowNum(2,7+8,SetTimeB[2],2);
}
void LCD_ShowOffTimeB()
{
LCD_ShowNum(1,1+8,OffTimeB[0],2);
LCD_ShowChar(1,3+8,':');
LCD_ShowNum(1,4+8,OffTimeB[1],2);
LCD_ShowChar(1,6+8,':');
LCD_ShowNum(1,7+8,OffTimeB[2],2);
}
void InitDS1302WithTime()
{
DS1302_init();
DS1302_WriteByte(0x8E,0x00);
//Give time
DS1302_SetTime();
}
void Int0_Init(void)
{
IT0=1;
IE0=0;
EX0=1;
EA=1;
PX0=1;
}
//
void ReadTimeToDs1302()
{
int i = 0;
DS1302_ReadTime();
for(i = 0;i<=7;i++)
{
Time[i] = DS1302_Time[i];
}
}
void WriteTimeToDs1302()
{
int i = 0;
for(i = 0;i<=7;i++)
{
DS1302_Time[i] = Time[i];
}
DS1302_SetTime();
}
void ChangeTimePart()
{
ReadTimeToDs1302();
LCD_time();
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
WT = Key - 1;
if(Key == 1 || Key == 2 || Key == 3|| Key == 4||Key == 5||Key == 6)//year
{
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
if(Key == 1)
Time[WT] += 1;
if(Key == 2)
Time[WT] -= 1;
if(Key == 3)
Time[WT] += 10;
if(Key == 4)
Time[WT] -= 10;
LCD_ShowTimechange();
if(Key == 16)
{
Key = 0;
break;
}
}
if(Key == 16)
{
Key = 0;
break;
}
}
if(Key == 16)
{
Key = 0;
break;
}
}
WriteTimeToDs1302();
}
void ChangeTimePart_AA()
{
LCD_ShowSetTimeA();
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
WT = Key - 1;
if(Key == 1 || Key == 2 || Key == 3)
{
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
if(Key == 1)
SetTimeA[WT] += 1;
if(Key == 2)
SetTimeA[WT] -= 1;
if(Key == 3)
SetTimeA[WT] += 10;
if(Key == 4)
SetTimeA[WT] -= 10;
LCD_ShowSetTimeA();
if(Key == 16)
{
Key = 0;
break;
}
}
if(Key == 16)
{
Key = 0;
break;
}
LCD_ShowSetTimeA();
}
if(Key == 16)
{
Key = 0;
break;
}
}
}
void ChangeTimePart_AB()
{
LCD_ShowOffTimeA();
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
WT = Key - 1;
if(Key == 1 || Key == 2 || Key == 3)
{
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
if(Key == 1)
OffTimeA[WT] += 1;
if(Key == 2)
OffTimeA[WT] -= 1;
if(Key == 3)
OffTimeA[WT] += 10;
if(Key == 4)
OffTimeA[WT] -= 10;
LCD_ShowOffTimeA();
if(Key == 16)
{
Key = 0;
break;
}
}
if(Key == 16)
{
Key = 0;
break;
}
LCD_ShowOffTimeA();
}
if(Key == 16)
{
Key = 0;
break;
}
}
}
void ChangeTimePart_BA()
{
LCD_ShowSetTimeB();
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
WT = Key - 1;
if(Key == 1 || Key == 2 || Key == 3)
{
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
if(Key == 1)
SetTimeB[WT] += 1;
if(Key == 2)
SetTimeB[WT] -= 1;
if(Key == 3)
SetTimeB[WT] += 10;
if(Key == 4)
SetTimeB[WT] -= 10;
LCD_ShowSetTimeB();
if(Key == 16)
{
Key = 0;
break;
}
}
if(Key == 16)
{
Key = 0;
break;
}
LCD_ShowSetTimeB();
}
if(Key == 16)
{
Key = 0;
break;
}
}
}
void ChangeTimePart_BB()
{
LCD_ShowOffTimeB();
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
WT = Key - 1;
if(Key == 1 || Key == 2 || Key == 3)
{
while(1)
{
Key = 0;
while(Key == 0)
Key = MatrixKey();
if(Key == 1)
OffTimeB[WT] += 1;
if(Key == 2)
OffTimeB[WT] -= 1;
if(Key == 3)
OffTimeB[WT] += 10;
if(Key == 4)
OffTimeB[WT] -= 10;
LCD_ShowOffTimeB();
if(Key == 16)
{
Key = 0;
break;
}
}
if(Key == 16)
{
Key = 0;
break;
}
LCD_ShowOffTimeB();
}
if(Key == 16)
{
Key = 0;
break;
}
}
}
void Int0_Routine(void) interrupt 0
{
while(1)
{
while(Key == 0)
Key = MatrixKey();
if(Key == 13)
{
ChangeTimePart();
}
if(Key == 14)
{
ChangeTimePart_AA();
}
if(Key == 15)
{
ChangeTimePart_AB();
}
if(Key == 10)
{
ChangeTimePart_BA();
}
if(Key == 11)
{
ChangeTimePart_BB();
}
if(Key == 16)
{
Key = 0;
break;
}
}
}
//
//unsigned char Time[] = {24,10,10,17,59,55,1};
//unsigned char SetTime[] = {18,0,0};
//unsigned char OffTime[] = {6,0,0};
void LedWithTime()
{
DS1302_ReadTime();
TimeO = DS1302_Time[3]*60*60 + DS1302_Time[4]*60 + DS1302_Time[5];
TimeA = SetTimeA[0]*60*60 + SetTimeA[1]*60 + SetTimeA[2];
TimeB = OffTimeA[0]*60*60 + OffTimeA[1]*60 + OffTimeA[2];
if(TimeO > TimeB && TimeO < TimeA)
{
P2_0 = 1;
ifopen = 0;
}
else
{
P2_0 = 0;
ifopen = 1;
}
TimeO = DS1302_Time[3]*60*60 + DS1302_Time[4]*60 + DS1302_Time[5];
TimeA = SetTimeB[0]*60*60 + SetTimeB[1]*60 + SetTimeB[2];
TimeB = OffTimeB[0]*60*60 + OffTimeB[1]*60 + OffTimeB[2];
if(TimeO > TimeB && TimeO < TimeA)
{
P2_2 = 1;
ifopen = 0;
}
else
{
P2_2 = 0;
ifopen = 1;
}
ADValue = XPT2046_ReadAD(XPT2046_VBAT);
if(ADValue <= 16)
{
P2_1 = 0;
}
else
{
P2_1 = 1;
}
if(ADValue >= 28)
{
while(XPT2046_ReadAD(XPT2046_VBAT)>=28)
{
P2_0 = 1;
P2_2 = 1;
}
}
else
{
if(ifopen == 1)
{
P2_0 = 0;
P2_2 = 0;
}
}
}
void AD()
{
if(P3_0 == 0)
{P2_3 = 0;Buzzer_Time_500HZ(100);}
else
P2_3 = 1;
if(P3_1 == 0)
{P2_4 = 0;Buzzer_Time_500HZ(100);}
else
P2_4 = 1;
}
//
int main()
{
LCD_Init();
Int0_Init();
InitDS1302WithTime();
while(1)
{
LCD_time();
LedWithTime();
AD();
}
}
支路控制代码
#include <REGX52.H>
#define uchar unsigned char
sbit key = P3^3;
void Delay(unsigned int t)
{
while(t--);
}
void Adelay(unsigned int i)
{
unsigned int j;
for(;i>0;i--)
for(j=0;j<333;j++){}
}
void Delay1000ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
i = 8;
j = 1;
k = 5;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Int0_Init(void)
{
IT0=1;
IE0=0;
EX0=1;
EA=1;
PX0=1;
}
//P3_0 == 0 hei
//P3_0 == 1 ming
//P3_1 == 0 qidong
//P3_1 == 1 guanji
//P0_0 == 0 qidong
//P0_0 == 1 guanji
void main()
{
Int0_Init();
P3_1 = 1;
P1_6 = 1;
P1_5 = 0;
P1_4 = 1;
P2_1 = 1;
while(1)
{
while(P3_1 == 0)
{
P1_7 = 1;
if(P1_6 == 0)
{
break;
}
if(P1_4 == 1)
{
P2_1 = 0;
P0_0 = 0;
while(P1_4 == 1);
P2_1 = 1;
P0_1 = 1;
}
if(P3_0 == 1)//PWM
{
P0_0 = 0;
Delay(2);
P0_0 = 1;
Delay(8);
}
if(P3_0 == 0)//PWM
{
P0_0 = 0;
Delay(7);
P0_0 = 1;
Delay(3);
}
}
P2_0 = 0;
}
}
void Int0_Routine(void) interrupt 0
{
if(P3_1 == 0)
{
P0_0= 0;
P1_7= 0;
while(P3_2 == 0);
}
}
头文件补充
LCD1602
#include <REGX52.H>
//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
//函数定义:
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
LCD_WriteCommand(0x01);//光标复位,清屏
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:-32768~32767
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i,SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
}
}
DS1302
#include <REGX52.H>
//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
//函数定义:
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
LCD_WriteCommand(0x01);//光标复位,清屏
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:-32768~32767
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i,SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
}
}
XPT2046
#include <REGX52.H>
//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
//函数定义:
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
LCD_WriteCommand(0x01);//光标复位,清屏
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:-32768~32767
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i,SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
}
}
Mkey
#include <REGX52.H>
#include "Delay.h"
/**
* @brief 矩阵键盘读取按键键码
* @param 无
* @retval KeyNumber 按下按键的键码值
如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0
*/
unsigned char MatrixKey()
{
unsigned char KeyNumber=0;
P1=0xFF;
P1_3=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
P1=0xFF;
P1_2=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
P1=0xFF;
P1_1=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
P1=0xFF;
P1_0=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
return KeyNumber;
}
Delay
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
Buzzer
#include <REGX52.H>
#include <INTRINS.H>
//蜂鸣器端口:
sbit Buzzer=P2^5;
/**
* @brief 蜂鸣器私有延时函数,延时500us
* @param 无
* @retval 无
*/
void Delay10us(unsigned int n) //@11.0592MHz
{
unsigned char i;
while(n--)
{i = 2;
while (--i);
}
}
void Delay2ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 4;
j = 146;
do
{
while (--j);
} while (--i);
}
void Buzzer_Delay500us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 227;
while (--i);
}
/**
* @brief 蜂鸣器发声
* @param ms 发声的时长,范围:0~32767
* @retval 无
*/
void Buzzer_Time(unsigned int ms)//2000hz的相应
{
unsigned int i;
for(i=0;i<ms*2;i++)
{
Buzzer=!Buzzer;
Buzzer_Delay500us();
}
}
void Buzzer_Time_500HZ(unsigned int ms)//500hz
{
unsigned int i;
for(i=0;i<ms/2+1;i++)
{
Buzzer=!Buzzer;
Delay2ms();
}
}
/**
* @brief 蜂鸣器发声
* @param ms 发声的时长,范围:0~32767
* @retval hz 频率
*/
void Buzzer_Time_hz(unsigned int ms,unsigned int hz)
{
unsigned int i;
unsigned int n = 100000 / hz;
for(i=0;i<ms*100;i++)
{
Buzzer=!Buzzer;
Delay10us(n);
}
}
应用
主控板 控制时间 每个灯允许量的时间 灯光亮度 是否灭灯
副控板 控制灯的亮灭 互相交流是否灭灯 PWM调光
如果看得懂代码 大概也知道引脚口对应的什么功能
主控P2口主动给副板发信息
主控P3口接受信息
副控P3 P1接受信息 P2开关灯 P1与另一个板子交流
详细欢迎于本人交流,我主要留痕