⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myboard.c

📁 单片机电子音乐程序
💻 C
📖 第 1 页 / 共 4 页
字号:
                                 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 + -