📄 myboard.c
字号:
0x04,0x05,0x06,0x0b, /*键盘4,5,6,B*/
0x07,0x08,0x09,0x0c, /*键盘7,8,9,C*/
0x0e,0x00,0x0f,0x0d}; /*键盘*,0,#,D*/
const uint code c_musicFreq[]={64260,64400,64524,64580, /*低音5,6,7,中音1*/
64684,64777,64820,64898, /*中音2,3,4,5*/
64968,65030,65058,65110, /*中音6,7,高音1,2*/
65157,65178,65217}; /*高音3,4,5*/
/*Constant Tables Over*/
/*************************************************************************/
/*System Variables*/
uint keyFlag;
uchar hour=10;min=0;sec=0;
uchar DisplayArray[6];
uchar password[6]={0x00,0x00,0x00,0x00,0x00,0x00};
static uchar LEDFlag=0;
bit LEDCycle100msFlag=0,LEDCycle500usFlag=0,LEDCycle10msFlag=0,LEDAutoFlag=1,LEDKeyFlag=0;
static uchar s_musicCounter=0x00,s_tableCounter;
bit musicAutoFlag=1,musicKeyFlag=1;
uchar Int0Flag,TH0Global,TL0Global;
uchar UARTKeyFlag=0xaa,modifyTimeFlag=0;
/*System Variables Over*/
/*************************************************************************/
/*System Functions*/
void IdleForLogin(); /*登陆系统前的密码检测模块*/
void Login(void); /*系统登录模块*/
void MainSystem(void); /*系统主程序*/
void ScanKeys(void); /*扫描键盘模块*/
uchar KeyJudge(void); /*按键预处理*/
void KeyHandle(uchar keyIndex); /*按键处理模块*/
void LEDHandle(void); /*流水灯方案选择*/
void AutoShow(void); /*开始流水灯自动循环演示*/
void StopAutoShow(void); /*停止流水灯自动循环演示*/
void DropDown(void); /*水滴方案*/
void CircleFlash(void); /*环扫方案*/
void GradualFlash(void); /*渐明渐暗方案*/
void SlowFlash(void); /*慢闪方案*/
void FastFlash(void); /*快闪方案*/
void ScrShift(uchar keyIndex); /*六位数码管顺序左移*/
void ClearScr(void); /*清屏*/
void ReadPassword(); /*从24C02中读取密码*/
void WritePassword(); /*将屏幕的六位数字作为密码存入24C02中*/
void StatusSend(void); /*下位机状态反馈(串口)*/
void Delay (uint value); /*10us延时*/
void ModifyTime(void); /*调整时间*/
void ScanSeg7(); /*数码管扫描显示*/
/*System Functions Over*/
/*************************************************************************/
/*IIC Varialbes & Functions*/
sbit SCL=P3^4; /*定义IIC总线的时钟线*/
sbit SDA=P3^5; /*定义IIC总线的数据线*/
void StartIIC(); /*发送IIC总线启动时序*/
void StopIIC(); /*发送IIC总线停止时序*/
void IICClockDelay(); /*IIC总线时钟电平延时*/
void IICAck(bit ackValue); /*MCU对24C02的应答函数*/
uchar IICRcvByte(); /*MCU从24C02接收一个字节*/
bit IICSendByte(uchar byteData); /*MCU向24C02发送一个字节*/
/*MCU向24C02的指定地址写入若干个字节数据函数*/
bit IICWrite(uchar slaveAddress,uchar subAddress,uchar *dataPointer,uchar num);
/*MCU从24C02的指定地址度去若干个字节数据函数*/
bit IICRead(uchar slaveAddress,uchar subAddress,uchar *dataPointer,uchar num);
/*IIC Varialbes & Functions Over*/
/*************************************************************************/
/*************************************************************************/
void main(void) /*主程序入口*/
{
TMOD=0x11; /*Timer0工作在案MODE1,16位定时器,Timer1工作在MODE2,自动重新装载模式*/
/*| 定时器1 | 定时器1 |*/
/*| GATE|C/T| M1 | M0 | GATE|C/T| M1 | M0 |*/
TH0=(65536-SCAN_CYCLE)/256; /*设定Timer0每隔SCAN_CYCLEu中断一次*/
TL0=(65536-SCAN_CYCLE)%256;
TR0=1; /*启动TEMER0*/
TH1=(65536-10000)/256; /*设定Timer1每10ms中断一次*/
TL1=(65536-10000)%256;
T2CON=0x38; /*令定时器2作为串口波特率发生器
/*|TF2|EXF2|RCLK|TCLK|EXEN2|TR2|C/T2|CP/RL2|*/
TL2=0xd9; /*设定串口波特率为9600,晶振为12MHz*/
TH2=0xff;
RCAP2L=0xd9; /*根据串口波特率9600设定自动重载寄存器*/
RCAP2H=0xff;
TR2=1; /*启动定时器2*/
SCON=0x50; /*设定UART工作在MODE3模式,可传送和接收数据,REN=1*/
/*| SM0| SM1| SM2| REN| TB8| RB8| TI | RI |*/
IE=0x9a; /*使能总中断、Timer0,1中断、外部中断1,2*/
/*| EA| - | ET2| ES | ET1| EX1| ET0| EX0|*/
IP=0x12; /*优先Timer0中断*/
/*| - | - | PT2| PS | PT1| PX1| PT0| PX0|*/
ReadPassword(); /*先把24C02中的密码读到密码缓冲区中*/
ClearScr(); /*预清屏*/
P3_3=1; /*关喇叭*/
P2=0x00; /*点亮8个发光二极管*/
while(1)
{
IdleForLogin();
}
}
/*************************************************************************/
void IdleForLogin() /*登陆系统前的密码检测模块*/
{
static uint s_UARTSendCounter;
uchar keyPtr,i;
keyPtr=KeyJudge(); /*键盘扫描判断*/
if(keyPtr!=0x55)
{
switch(c_keyCode[keyPtr])
{
case 0x0a: ReadPassword(); /*按A键:读取24C02中的密码并显示*/
for(i=0;i<5;i++) /*显示密码1秒后恢复*/
{
Delay(20000);
}
ClearScr();
break;
case 0x0b: WritePassword(); /*按B键:将屏幕中的六位数字设为密码*/
ClearScr();
break;
case 0x0c: ClearScr(); /*按C键:清屏*/
break;
case 0x0d: Login(); /*按D键:比较密码,如果密码正确则进入系统*/
break;
case 0x0e: /*按*键:保留*/
break;
case 0x0f: /*按#键:保留*/
break;
default: ScrShift(keyPtr); /*以上均不是则为数字键,六位数码管顺序左移*/
break;
}
UARTKeyFlag=0xaa; /*清串口键盘命令标志位*/
}
if(++s_UARTSendCounter>200) /*定期上传系统状态*/
{
s_UARTSendCounter=0;
StatusSend();
}
}
/*************************************************************************/
void Login(void) /*系统登录模块*/
{
uchar i;
for(i=0;i<6;i++) /*比较密码是否正确*/
{
if(DisplayArray[i]!=password[i])
{
return;
}
}
TR1=1; /*启动系统时基Timer1,中断周期10ms*/
ClearScr(); /*清屏*/
s_musicCounter=0x01;
LEDFlag=0x01;
ModifyTime(); /*初始设定时间*/
while (1)
{
MainSystem(); /*进入系统主程序*/
}
}
/*************************************************************************/
void MainSystem(void) /*系统主程序*/
{
static uint s_UARTSendCounter;
uchar keyPtr;
keyPtr=KeyJudge(); /*键盘扫描判断*/
if(keyPtr!=0x55) /*如果按某键则进行相应处理*/
{
KeyHandle(keyPtr);
UARTKeyFlag=0xaa; /*清串口键盘命令标志位*/
}
LEDHandle(); /*流水灯处理模块*/
if(++s_UARTSendCounter>200) /*定期上传系统状态*/
{
s_UARTSendCounter=0;
StatusSend();
}
if(modifyTimeFlag==1)
{
ModifyTime(); /*根据新秒值调整时间*/
modifyTimeFlag=0;
}
}
/*************************************************************************/
void ScanKeys(void) /*扫描键盘模块*/
{
uchar scanValue=0xef,iScan,scanTempUchar;
for(iScan=0;iScan<4;iScan++)
{
P1=scanValue; /*发扫描值*/
scanTempUchar=P1; /*读入扫描值*/
if((scanTempUchar&0x01)==0x00) /*第一列被按*/
{
keyFlag|=(0x0001<<(iScan*4+0)); /*置此键的标志位*/
}
else
{
keyFlag&=~(0x0001<<(iScan*4+0));/*清此键的标志位*/
}
if((scanTempUchar&0x02)==0x00) /*第二列被按*/
{
keyFlag|=(0x0001<<(iScan*4+1)); /*置此键的标志位*/
}
else
{
keyFlag&=~(0x0001<<(iScan*4+1));/*清此键的标志位*/
}
if((scanTempUchar&0x04)==0x00) /*第三列被按*/
{
keyFlag|=0x0001<<(iScan*4+2); /*置此键的标志位*/
}
else
{
keyFlag&=~(0x0001<<(iScan*4+2));/*清此键的标志位*/
}
if((scanTempUchar&0x08)==0x00) /*第四列被按*/
{
keyFlag|=0x0001<<(iScan*4+3); /*置此键的标志位*/
}
else
{
keyFlag&=~(0x0001<<(iScan*4+3));/*清此键的标志位*/
}
scanValue=scanValue<<1|0x01; /*置下一次扫描值*/
}
}
/*************************************************************************/
uchar KeyJudge(void) /*按键预处理*/
{
uchar j,counterKeyPressedNum;
uchar keyRet=0x55; /*初始按键返回码设定为无按码0x55*/
uint uintTemp;
ScanKeys(); /*扫描键盘*/
if(keyFlag!=0)
{
Delay(1000); /*延时10ms以消除抖动*/
ScanKeys();
P1=0x0f;
while((P1&0x0f)!=0x0f); /*没松开按键就等按键松开*/
counterKeyPressedNum=0;
for(j=0;j<16;j++)
{
uintTemp=((uint)0x0001)<<j;
if((keyFlag&uintTemp)==uintTemp)/*依次检测键盘扫描标志KeyFlag,如某位置一则按键个数寄存器加一*/
{
counterKeyPressedNum++;
keyRet=j;
}
}
if(counterKeyPressedNum>1) /*如果不止一个键被按则丢弃此状态返回无按码0x55*/
{
return 0x55;
}
else /*某键被按,返回此键的标识码*/
{
return(keyRet);
}
}
if(UARTKeyFlag!=0xaa) /*如果上位机发键盘指令则返回此键盘值*/
{
return(UARTKeyFlag);
}
return(0x55);
}
/*************************************************************************/
void KeyHandle(uchar keyIndex) /*按键处理模块*/
{
switch(c_keyCode[keyIndex]) /*按数字键N:循环播放第N首音乐*/
{
case 0x00: s_musicCounter=0; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x01: s_musicCounter=1; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x02: s_musicCounter=2; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x03: s_musicCounter=3; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x04: s_musicCounter=4; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x05: s_musicCounter=5; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x06: s_musicCounter=6; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x07: s_musicCounter=7; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x08: s_musicCounter=8; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x09: s_musicCounter=9; musicAutoFlag=0; s_tableCounter=0x00; break;
case 0x0a: sec++; /*按A键:调整时钟秒值*/
ModifyTime();
break;
case 0x0b: min++; /*按B键:调整时钟分值*/
ModifyTime();
break;
case 0x0c: hour++; /*按C键:调整时钟时值*/
ModifyTime();
break;
case 0x0d: if(musicKeyFlag==1) /*按D键:开始/停止音乐自动循环播放*/
{
s_musicCounter=1;
musicAutoFlag=1;
musicKeyFlag=~musicKeyFlag;
}
else
{
s_musicCounter=0;
musicAutoFlag=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -