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

📄 main.c

📁 飞思卡尔的电子钟和电子琴的课程设计,包括源代码
💻 C
字号:
/*-----------------------------------------------------*
*工 程 名:	                                
*硬件连接:                                
*程序描述: SD-HC08 模板生成                            
*/
/*[头文件]*/
#include "GP32C.h"                //映像寄存器地址头文件
#include "clock.h" 


unsigned char ch[]={"please set time!Epress 'B'E"};
unsigned char c[]={"time out!EGet up!E"};
unsigned char init[]={"0000-00-00E00:00:00E"};
unsigned char show[32]={' '};
unsigned char timer[2];
unsigned char time[3];
unsigned int date[3];
unsigned char out;
unsigned char timertem[4];
unsigned char timetem[4];
unsigned char datetem[8];
unsigned char showtime;
unsigned char istimer;
unsigned char issettime;
/*[主函数]*/
void main(void){
	asm("SEI");
	showtime=0x01;istimer=0x00;issettime=0;//模式初始化
	DDRD=0x01;out=1;					//闹钟接口初始化
	timer[0]=0;timer[1]=0;				//闹钟\时间初始化
	time[0]=0;time[1]=0;time[2]=0;
	date[0]=0;date[1]=0;date[2]=0;
	LcdInit();							//LCD显示初始化
	KB_Init();					//键盘初始化
	INTKBSCR&= ~(1<<IntBit); //开放键盘中断(IMASKk=1)  
	PTD=0;
	Timer1init();				//定时器初始化
	asm("CLI");
	while(1){
		if(timer[0]==time[0]&&timer[1]==time[1]&&istimer==0x01){//闹钟启动//开始响铃60秒
	 	   showtime=0;							//关闭时间显示
	 	   lcdshow((unsigned char *)c);
	  	   beep(2);						   
	 	   showtime=1;						//开时间表显示
   		}
	}
}

unsigned char isadddate1(void){//每月天数不一,判断对应月加1
   unsigned char in=0x00;						
   	if((date[1]==1||date[1]==3||date[1]==5||date[1]==7||date[1]==8||date[1]==10||date[1]==12)&&date[2]>=32)
		in=0x01;
	else if((date[1]==4||date[1]==6||date[1]==9||date[1]==11)&&date[2]>=31)
		in=0x01;
	else if((date[1]==2&&date[0]%4==0)&&date[2]==29)in=0x01;
	else if((date[1]==2&&date[0]%4!=0)&&date[2]==28)in=0x01;
	return in;
}
void addtime(void){				//日期,时间累加函数
   unsigned char in;
   time[2]++;             //秒数加1
   if (time[2]>=60){       //秒数未增加到60,转
      time[2]=0; time[1]++;  //秒数增加到60,清0,分钟数加1
   }
   if (time[1]>=60){          //分钟数未增到60,转
      time[1]=0; time[0]++;  //分钟数增加到60,清0,小时数加1
      beep(1);
   }
   if (time[0]>=24){          //小时数未增到24,转
      time[0]=0;             //时数增加到24,清0
      date[2]++;
   }
   in=isadddate1();
   if(in==0x01){						//满足月份加1
	date[1]++;						//月份加1
	date[2]=1;						//天回1
   }
   if(date[1]>=13){					//月大于12
   	  date[0]++;					//年加1,月回1
   	  date[1]=1;
   }
}

void displaytime(void){			//显示时间处理
	if(showtime==0x01){			//可显示时才处理
		unsigned char i=0,j,c[4];
  		int temp=date[0];
  		for(j=0;j<4;j++){		//年中的四位处理,放临时变量
  		   c[j]=(char)(temp%10);
  		   temp/=10;
 	 	}
  		for(j=0;j<4;j++){		//年存到显示单元中
 	 	   show[i]=c[3-j]+0x30;i++;
 	 	}
 	 	show[i]='-';i++;
 	 	for(j=0;j<2;j++){		//月日存到显示单元中
 	 	   show[i]=(char)date[j+1]/10+0x30;i++;
 	 	   show[i]=(char)date[j+1]%10+0x30;i++;
 	 	   if(j==0){show[i]='-';i++;}
 	 	}
 	 	show[i]='E';i++;		//换行
 	 	for(j=0;j<3;j++){		//时,分,秒存到显示单元中
	   		show[i]=0x30+(time[j]/10);i++;
   	       	show[i]=0x30+(time[j]%10);i++;
  	     	if(j==2)break;
  	    	 show[i]=':';i++;
 	   	}
 	   	show[i]='E';
	  	 lcdshow((unsigned char *)show);			//显示日期时间
	  	 if(istimer==0x01)lcdshow1('*',0x4C);		//闹钟开关标志
	}
}
void shilfL(void){						//在设置状态下光标左移
	if(showtime==0x00){	
		unsigned char data;
		LcdCtrl&=~(1<<LcdRS);    //RS、R/W=01,读指令
		LcdCtrl|=(1<<LcdRW);    
		LcdCtrl|=(1<<LcdE);       //E=1
	  	data=LcdData;
	  	data&=0b01111111;
	  	data--;	
	  	if(data==0x04||data==0x07||data==0x42||data==0x45)data--;
	  	if(data==0x3f)data=0x09;
	  	if(data==0xff)data=0x47;
	  	data|=0b10000000;		//写AC地址指令
		LcdCtrl&=~(1<<LcdRS);    //RS、R/W=00,写指令
		LcdCtrl&=~(1<<LcdRW);    
		Lcd_Command(data);		//AC地址减1后写AC地址
	}	
}

void shilfR(void){					//在设置状态下光标右移
	if(showtime==0x00){
		unsigned char data;
		LcdCtrl&=~(1<<LcdRS);    //RS、R/W=01,读指令
		LcdCtrl|=(1<<LcdRW);    
		LcdCtrl|=(1<<LcdE);       //E=1
	  	data=LcdData;
	  	data&=0b01111111;
	  	data++;	
	  	if(data==0x04||data==0x07||data==0x42||data==0x45)data++;
	  	if(data==0x0A)data=0x40;
	  	if(data==0x48)data=0x00;
	  	data|=0b10000000;		//写AC地址指令
		LcdCtrl&=~(1<<LcdRS);    //RS、R/W=00,写指令
		LcdCtrl&=~(1<<LcdRW);    
		Lcd_Command(data);		//AC地址减1后写AC地址
	}
}

void settime(void){				//进入时间设置
	unsigned char i;
	for(i=0;i<8;i++)datetem[i]=0;
	for(i=0;i<4;i++)timetem[i]=0;
	issettime=0x01;				//时间设置位置1
	showtime=0x00;				//时间显示位置0,不显示时间
	lcdshow((unsigned char *)init);
	LcdCtrl&=~(1<<LcdRS);      //RS、R/W=00,写指令
	LcdCtrl&=~(1<<LcdRW);    
  	Lcd_Command(0b00001111);	//开显示,开光标,闪烁
  	Lcd_Command(0b10000000); //后7位为DDRAM地址0x00 
}


void sastimer(void){		  //开始或关闭闹钟标志
	unsigned char i;
	for(i=0;i<4;i++)timertem[i]=0;
	if(istimer==0x00){		  //若关则开
		istimer=0x01;			//标志开
		lcdshow1('*',0x4C);		//显示'*'
	}
	else if(istimer==0x01){						//若开则关
		istimer=0x00;			//标志关
		lcdshow1(' ',0x4C);		//无显示
	}
}

void settimer(void){			//进入闹钟设置
	if(issettime==0){
		unsigned char i=0,j;
		showtime=0x00;				//时间显示位置0,不显示时间
		istimer=0x01;				//开闹钟设置标志
		lcdshow1('*',0x4C);			//显示'*'
		show[i]='E';i++;			//第一行不显示		
	 	for(j=0;j<3;j++){			
		   show[i]=0x30+(timer[j]/10);i++;
	   	   show[i]=0x30+(timer[j]%10);i++;
	  	   if(j==2)break;
	  	   show[i]=':';i++;
	 	}
	 	show[i]='E';
		lcdshow((unsigned char *)show);//显示原设置的时间
		LcdCtrl&=~(1<<LcdRS);      //RS、R/W=00,写指令
		LcdCtrl&=~(1<<LcdRW);    
  		Lcd_Command(0b00001111);	//开显示,开光标,闪烁
  		Lcd_Command(0b11000000); //后7位为DDRAM地址0x40 
	}
}

void ok(void){					//在设置模式下的确定,
	unsigned char i;
	if(showtime==0x00&&issettime==0x01){	//在时间设置模式下的确定,
     	T1SC|=(1<<TSTOPBit);				//停止计数,进行时间修改
	  	time[0]=0;time[1]=0;time[2]=0;		//时间清零,键盘输入的临时时间写入时间
		date[0]=0;date[1]=0;date[2]=0;
		for(i=0;i<4;i++){
			date[0]=(int)(date[0]*10+datetem[i]);
		}
		for(;i<6;i++){
			date[1]=date[1]*10+datetem[i];
			time[0]=time[0]*10+timetem[i-4];
		}
		for(;i<8;i++){
			date[2]=date[2]*10+datetem[i];
			time[1]=time[1]*10+timetem[i-4];
		}
		issettime=0x00;
		T1SC&=~(1<<TSTOPBit);		//开始计数
	}
	if(showtime==0x00&&issettime==0x00){	//在闹钟设置模式下的确定,
	  	timer[0]=0;timer[1]=0;timer[2]=0;	//时间清零,键盘输入的临时定时时间写入定时时间
		for(i=0;i<2;i++){
			timer[0]=timer[0]*10+timertem[i];
		}
		for(;i<4;i++){
			timer[1]=timer[1]*10+timertem[i];
		}
	}
	LcdCtrl&=~(1<<LcdRS);     //RS、R/W=00,写指令
	LcdCtrl&=~(1<<LcdRW);    
	Lcd_Command(0b00001100);  //开显示,关光标显示,不闪烁
	showtime=0x01;				//开时间显示
}

void Delay_ms(unsigned char i)
  {  unsigned char j;
     unsigned char u;
     for(j=0;j<i;j++)
         for(u=0;u<=250;u++) ;
  }


void beep(unsigned char p){	//锋鸣器启动,时间持续p秒
	unsigned char j;
	for(j=0;j<p;j++){//延时p秒
		PTD=1;
		Delay_ms(50);
		PTD=0;
		Delay_ms(200);
		Delay_ms(200);
		if(istimer==0)break;	//如果关闹钟则退出延时
	}
}

void input(KB_valve){		//数字输入
	if(showtime==0x00){
		unsigned char data;
		if(issettime==0x01){		//若是时间设置
			LcdCtrl&=~(1<<LcdRS);    //RS、R/W=01,读指令
			LcdCtrl|=(1<<LcdRW);
			LcdCtrl|=(1<<LcdE);       //E=1    
	  		data=LcdData;				//获取AC的值
	  		data&=0b01111111;
	  		switch(data){				//按AC值不同分别赋给不同的时间临时单元
	  			case 0x00:
	  				datetem[0]=KB_valve-0x30;
	  				lcdshow1(KB_valve,data);
	  				break;
	  			case 0x01:
	  				datetem[1]=KB_valve-0x30;
	  				lcdshow1(KB_valve,data);
	  				break;
	  			case 0x02:
	  				datetem[2]=KB_valve-0x30;
	  				lcdshow1(KB_valve,data);
	  				break;
	  			case 0x03:
	  				datetem[3]=KB_valve-0x30;
	  				lcdshow1(KB_valve,data);
	  				break;
	  			case 0x05:
	  				if((KB_valve-0x30)<=1){
		  				datetem[4]=KB_valve-0x30;
		  				lcdshow1(KB_valve,data);}
	  				break;
	  			case 0x06:
	  				if(datetem[4]==1&&(KB_valve-0x30)>2)break;
	  				datetem[5]=KB_valve-0x30;
	  				lcdshow1(KB_valve,data);
	  				break;
	  			case 0x08:
	  				if(KB_valve-0x30<=3){
		  				datetem[6]=KB_valve-0x30;
		  				lcdshow1(KB_valve,data);}
	  				break;
	  			case 0x09:
	  				if(datetem[6]==3&&(KB_valve-0x30)>1)break;
	  				datetem[7]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  				break;
	  			case 0x40:
	  				if((KB_valve-0x30)>2)break;
	  				timetem[0]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  				break;
	  			case 0x41:
	  				if(timetem[0]==2&&(KB_valve-0x30)>3)break;
	  				timetem[1]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  				break;
	  			case 0x43:
	  				if((KB_valve-0x30)>5)break;
	  				timetem[2]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  				break;
	  			case 0x44:
	  				timetem[3]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  			default:break;
	  		}
		}
		else {						//不是时间设置则是闹钟设置
			LcdCtrl&=~(1<<LcdRS);    //RS、R/W=01,读指令
			LcdCtrl|=(1<<LcdRW);
			LcdCtrl|=(1<<LcdE);       //E=1    
	  		data=LcdData;				//获取AC的值
	  		data&=0b01111111;//获取AC的值
	  		switch(data){			//按AC值不同分别赋给不同的闹钟计时临时单元
	  			case 0x40:
	  				if((KB_valve-0x30)>2)break;
	  				timertem[0]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  				break;
	  			case 0x41:
	  				if(timertem[0]==2&&(KB_valve-0x30)>3)break;
	  				timertem[1]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  				break;
	  			case 0x43:
	  				if((KB_valve-0x30)>5)break;
	  				timertem[2]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  				break;
	  			case 0x44:
	  				timertem[3]=KB_valve-0x30;
		  			lcdshow1(KB_valve,data);
	  			default:break;
	  		}
	  	}
	}
}

void cancel(void){				//取消设置
	if(showtime==0){
		showtime=1;issettime=0;	//模式为显示时间,退出时间设置
		LcdCtrl&=~(1<<LcdRS);     //RS、R/W=00,写指令
		LcdCtrl&=~(1<<LcdRW);    
		Lcd_Command(0b00001100);  //开显示,关光标显示,不闪烁
	}
}

void reset(void){					//时钟复位,全部从零开始
	asm("SEI");
	showtime=0x01;istimer=0x00;issettime=0;//模式初始化
	DDRD=0x01;out=1;					//闹钟接口初始化
	timer[0]=0;timer[1]=0;				//闹钟\时间初始化
	time[0]=0;time[1]=0;time[2]=0;
	date[0]=0;date[1]=0;date[2]=0;
	LcdInit();							//LCD显示初始化
	lcdshow((unsigned char *)ch);
	KB_Init();					//键盘初始化
	INTKBSCR&= ~(1<<IntBit); //开放键盘中断(IMASKk=1)  
	Timer1init();				//定时器初始化
	asm("CLI");					//复位
}

void set(unsigned char KB_valve){		//按键功能选择
	switch(KB_valve){
		case 'A':shilfL();		//A:设置模式下的光标左移
			break;
		case 'B':shilfR();//B:设置模式下的光标右移
			break;
		case 'C':sastimer();	//C:闹钟开关
			break;
		case 'D':settimer();//D:进入闹钟设置	
			break;
		case '#':ok();	//#:确定并退出设置
			break;
		case '*':cancel();//*:取消并退出设置
			break;
		case '0':if(showtime==1){settime();break;}//0:非设置模式下的进入时间设置
		case '1':if(showtime==1){reset();break;}//1:非设置模式下的复位
		default:input(KB_valve);//设置模式下的数字输入
			break;
	}
}







⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -