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

📄 cheshi.c

📁 LPC2124+数码管+液晶+串口+键盘设置+1302 数字时钟 带proteus仿真
💻 C
字号:
#include  <LPC21XX.H>
#define rs (1<<10)
#define rw (1<<11)
#define en (1<<12)
#define busy (1<<7)	   //P0.7

#define ds1302_cs (1<<16)
#define ds1302_sck (1<<17)
#define ds1302_dio (1<<18)

//--------按键引脚设置
#define ENTER_KEY (IO0PIN&(1<<23))
#define ADD_KEY (IO0PIN&(1<<24))
#define DEC_KEY (IO0PIN&(1<<25))

extern unsigned char read_ds1302_rtc(unsigned char rtc_address);
extern void write_ds1302_rtc(unsigned char rtc_address,unsigned char rtc_data);
extern void ds1302_init(void);

extern int putchar (int ch);
extern void serialPuts(char *p);
extern void uart1Init(void);
extern void puthex (int hex);
extern void putstr (char *p);

typedef unsigned char uint8; 
uint8 lcdrtcdatebuffer[]={"   2008/01/01       "};
uint8 lcdrtctimebuffer[]={"   1 00:00:00       "};

char ledUp[]={"The LED is up!\n"};

unsigned int halfsecondflag,secondflag;
unsigned int halfsecondcount=0,secondcount=0;


void ds1302_init(void)
{
	IO0DIR|=ds1302_cs;
	IO0CLR|=ds1302_cs;
	IO0DIR|=ds1302_sck;
	IO0CLR|=ds1302_sck;
	IO0DIR&=~ds1302_dio;
}

void waitLCD()					/*等待LCD*/
{
	IO0DIR|=0x1c00;
	while(1)
	{
		IO0CLR=rs;
		IO0SET=rw;
		IO0SET=en;
		if(!(IO0PIN & busy))break;
		IO0CLR = en;
	}
	IO0DIR|=0xfff;
}
void lcdOp(uint8 dat)					/*送LCD控制码*/
{
	waitLCD();
	IO0CLR=rs;		
	IO0CLR=rw;
	IO0CLR=0xff;	
	IO0SET=dat;		
	IO0SET=en;
	IO0CLR=en;
}
void lcdData(uint8 dat)					/*送LCD显示数据*/	
{
	waitLCD();
	IO0SET=rs;
	IO0CLR=rw;
	IO0CLR=0xff;	
	IO0SET=dat;		
	IO0SET=en;
	IO0CLR=en;
}
void lcdInit(void)					/*初始化LCD,DataSheet里有建议的初始化代码*/
{
	/* LCD配置为两行,5*7字体 */
	lcdOp(0x38);
	lcdOp(0x38);
	lcdOp(0x06);			
	lcdOp(0x0E);	
	lcdOp(0x01);
	/* LCD配置为一行,5*10字体
		lcdOp(0x34);
		lcdOp(0x34);
		lcdOp(0x06);			
		lcdOp(0x0E);	
		lcdOp(0x01);
 	*/	
}
void lcdDisplay(uint8 addr,uint8 *p)					/*LCD显示字符串*/
{
	lcdOp(addr);
	while(*p !='\0'){
		lcdData(*(p++));
	}
}
void lcdClear(void)					/*LCD清屏*/
{
	lcdOp(0x01);
}
void delay (void)  {                         
  unsigned volatile long i,j;
  for(i=0;i<60000;i++)
  for(j=0;j<10;j++)
  ;
}


//----------------------------
//DS1302实时日历时钟结构体变量的定义
struct rtc_struct
{
 signed char second;
 signed char minute;
 signed char hour;
 signed char day;
 signed char month;
 signed char year;
 signed char week;
};
struct rtc_struct ds1302;


#define LEDSEG_CON (1<<25)
#define LEDBIT_CON (1<<26)

//数码管笔段代码表和位选通段代码
const unsigned char LEDSEGCODE[]=
{0x3f,0x06,0x5b,0x4f,0x66,
 0x6d,0x7d,0x07,0x7f,0x6f,0x40,
};
const unsigned char LEDBITCODE[]=
{
 0xfe,0xfd,0xfb,0xf7,
 0xef,0xdf,0xbf,0x7f,
};

//数码管显示变量和显示扫描指针变量定义
unsigned char LEDBuffer[8];
unsigned char LEDPointer;

void display(void)
{
	IO0CLR = 0x000800;
	lcdDisplay(0x80,lcdrtcdatebuffer);
	delay();
	//lcdClear();
	IO0SET = 0x000800;
	lcdDisplay(0xc0,lcdrtctimebuffer);
	delay();
	//lcdClear();
}


//---------------------------
//Timer0定时1ms中断服务程序
void timer0_vect (void) __irq
{
 T0IR=1;
 VICVectAddr=0;
//---------------------------
//数码管显示程序
  //IO0SET|=(0xFF<<16);
 //数码管动态扫描
 //LEDPointer=1;
 IO1CLR|=(0xFF<<16);IO0SET|=LEDSEG_CON;
 IO1SET|=(LEDSEGCODE[LEDBuffer[LEDPointer]]<<16);
 
 IO0CLR|=LEDSEG_CON;

 IO1CLR|=(0xFF<<24);IO0SET|=LEDBIT_CON;
 IO1SET|=(LEDBITCODE[LEDPointer]<<24);
 
 IO0CLR|=LEDBIT_CON;
 LEDPointer++;
 if(sizeof(LEDBuffer)==LEDPointer)LEDPointer=0;
 LEDBuffer[0]=ds1302.hour/10;
 LEDBuffer[1]=ds1302.hour%10;
 LEDBuffer[2]=10;
 LEDBuffer[3]=ds1302.minute/10;
 LEDBuffer[4]=ds1302.minute%10;
 LEDBuffer[5]=10;
 LEDBuffer[6]=ds1302.second/10;
 LEDBuffer[7]=ds1302.second%10; 

//用定时0.5s中读取DS1302的实时日历时钟信息
 halfsecondcount++;
 if(1000==halfsecondcount)
   {
    halfsecondcount=0;
	halfsecondflag=1;
   }

//用定时0.5s中读取DS1302的实时日历时钟信息
 secondcount++;
  if(2000==secondcount)
   {
    secondcount=0;
	secondflag=1;
   }
}


void timer0_init(void)
{
	T0MR0=4999;
	T0MCR=3;
	T0TCR=1;
	VICVectAddr0=(unsigned long)timer0_vect;
	VICVectCntl0=0x20|4;
	VICIntEnable|=(1<<4);
}

void write_time(void)
{
	write_ds1302_rtc(0x8e,0x00);
	      
	write_ds1302_rtc(0x8c,ds1302.year);	//写入ds1302年单元

	write_ds1302_rtc(0x88,ds1302.month); //写入ds1302月单元

	write_ds1302_rtc(0x86,ds1302.day);	//写入ds1302日单元

	write_ds1302_rtc(0x8a,ds1302.week);	//写入ds1302星期单元

	write_ds1302_rtc(0x84,ds1302.hour);	//写入ds1302时单元

	write_ds1302_rtc(0x82,ds1302.minute);	//写入ds1302分单元

	write_ds1302_rtc(0x80,ds1302.second);	//写入ds1302秒单元
	
	write_ds1302_rtc(0x8e,0x80);
}
void time_to_lcdbuffer(void)
{
   lcdrtcdatebuffer[5]=(ds1302.year/10)+0x30;     
   lcdrtcdatebuffer[6]=(ds1302.year%10)+0x30;

   lcdrtcdatebuffer[8]=(ds1302.month/10)+0x30;
   lcdrtcdatebuffer[9]=(ds1302.month%10)+0x30;

   lcdrtcdatebuffer[11]=(ds1302.day/10)+0x30;
   lcdrtcdatebuffer[12]=(ds1302.day%10)+0x30;

   lcdrtctimebuffer[3]=ds1302.week+0x30;

   lcdrtctimebuffer[5]=(ds1302.hour/10)+0x30;
   lcdrtctimebuffer[6]=(ds1302.hour%10)+0x30;

   lcdrtctimebuffer[8]=(ds1302.minute/10)+0x30;
   lcdrtctimebuffer[9]=(ds1302.minute%10)+0x30;

   lcdrtctimebuffer[11]=(ds1302.second/10)+0x30;
   lcdrtctimebuffer[12]=(ds1302.second%10)+0x30;
}
void display1(void)
{   
	time_to_lcdbuffer();
   display();
}

//按键子程序中调用的延时
void Delay (unsigned long t)
{
 while(t--);
}

//按键设置
///*
void KeyBoard_Scan(void)
{

 unsigned char bitse=0;
 unsigned char esc=0;
 unsigned char temp,write;
 
  

 if(ENTER_KEY==0)
   {
    Delay(100000);
	if(ENTER_KEY==0)
	   {
	     ds1302.second=8;
		 ds1302.minute=30;
		 ds1302.hour=10;
		 ds1302.day=1;
		 ds1302.month=10;
		 ds1302.year=8;
		 ds1302.week=5;
		 esc=1;
		 display1();
		 while(ENTER_KEY==0); 	   
	   } 
   }
  while(esc)
 {
 if(ENTER_KEY==0)
   {
    Delay(100000);
	if(ENTER_KEY==0)
	   { 
	    bitse++;
		if(bitse>8)
		  {bitse=0; }
		while(ENTER_KEY==0);	       	   
	   } 
   } 
		        
		     if(bitse==1)
			 {
			   if(ADD_KEY==0) 
			    {
				Delay(100000);
				if(ADD_KEY==0)
			      
				   {ds1302.second++;}				   
                   
				  if(ds1302.second>=59)
					 { ds1302.second=0;}
					 display1();
					while(ADD_KEY==0);
				  
			   	}
				if(DEC_KEY==0)
				 {
				  Delay(100000);
				  if(DEC_KEY==0)
				    { ds1302.second--;}
					  if(ds1302.second<=0) 
					    {ds1302.second=59;}
						display1();
					  while(DEC_KEY==0);
				 }
			   }	

			if(bitse==2)
			{  if(ADD_KEY==0)
			    {
				Delay(100000);
				if(ADD_KEY==0)
			      {
				    ds1302.minute++;
					if(ds1302.minute>=59)
					 { ds1302.minute=0;}
					 display1();
					 while(ADD_KEY==0);
				  }
			   	}
			  if(DEC_KEY==0)
				 {
				  Delay(100000);
				  while(DEC_KEY==0)
				    {
					  ds1302.minute--;
					  if(ds1302.minute<=0) 
					    {ds1302.minute=60;}
						display1();
					  while(DEC_KEY==0);
					}
				 }
			 }

			 if(bitse==3)
			  { if(ADD_KEY==0) 
			    {
				Delay(100000);
				if(ADD_KEY==0)
			      {
				    ds1302.hour++;
					if(ds1302.hour>=24)
					 { ds1302.hour=0;}
					 display1();
					 while(ADD_KEY==0);
				  }
			   	}
			  if(DEC_KEY==0)
				 {
				  Delay(100000);
				  if(DEC_KEY==0)
				    {
					  ds1302.hour--;
					  if(ds1302.hour<=0) 
					  {ds1302.hour=24;}
					  display1();
					  while(DEC_KEY==0);
					}
				 }
			  }
			 //if(bitse==4)esc=0;
			 if(bitse==4)
			 {  if(ADD_KEY==0) 
			    {
				Delay(100000);
				while(ADD_KEY==0)
			      {
				    ds1302.day++;
					if(ds1302.day>=31)
					 { ds1302.day=0;}
					 display1();
					 while(ADD_KEY==0);
				  }
			   	}
			  if(DEC_KEY==0)
				 {
				  Delay(100000);
				  while(DEC_KEY==0)
				    {
					 ds1302.day--;
					 if(ds1302.day<=0) 
					   {ds1302.day=31;}
					   display1();
					  while(DEC_KEY==0);
					}
				 }
			  }
			 
			 if(bitse==5)
			 {  if(ADD_KEY==0) 
			    {
				Delay(100000);
				while(ADD_KEY==0)
			      {
				    ds1302.month++;
					if(ds1302.month>=12)
					 { ds1302.month=0;}
					 display1();
					 while(ADD_KEY==0);
				  }
			   	}
			  if(DEC_KEY==0)
				 {
				  Delay(100000);
				  while(DEC_KEY==0)
				    {
					 ds1302.month--;
					 if(ds1302.month<=0) 
					   {ds1302.month=12;}
					   display1();
					  while(DEC_KEY==0);
					}
				 }
			 }
			 
			  if(bitse==6)
			  { if(ADD_KEY==0) 
			    {
				Delay(100000);
				while(ADD_KEY==0)
			      {
				    ds1302.year++;
					if(ds1302.year>=99)
					 { ds1302.year=0;}
					 display1();
					 while(ADD_KEY==0);
				  }
			   	}
			  if(DEC_KEY==0)
				 {
				  Delay(100000);
				  while(DEC_KEY==0)
				    {
					 ds1302.year--;
					 if(ds1302.year==-1) 
					   {ds1302.year=99;}
					   display1();
					  while(DEC_KEY==0);
					}
				 }
			   }
			 
			if(bitse==7)
			{
			   if(ADD_KEY==0) 
			    {
				Delay(100000);
				while(ADD_KEY==0)
			      {
				    ds1302.week++;
					if(ds1302.week>=7)
					 { ds1302.week=0;}
					 display1();
					  while(ADD_KEY==0);
				  }
			   	}
			  if(DEC_KEY==0)
				 {
				  Delay(100000);
				  while(DEC_KEY==0)
				    {
					 ds1302.week--;
					 if(ds1302.week<=0) 
					   {ds1302.week=7;}
					   display1();
					  while(DEC_KEY==0);
					}
				 }
			  }
			  if(bitse==8)
			  {esc=0;write=1;}	

   }
   if(write==1)
   {
   temp=ds1302.second;	                 
   ds1302.second=(temp/10)*16+(temp%10);	 //将十进制数转换成十六进制

   temp=ds1302.minute;	                 
   ds1302.minute=(temp/10)*16+(temp%10);

   temp=ds1302.hour;                   
   ds1302.hour=(temp/10)*16+(temp%10);

   temp=ds1302.day;	                 
   ds1302.day=(temp/10)*16+(temp%10);

   temp=ds1302.month;	                 
   ds1302.month=(temp/10)*16+(temp%10);

   temp=ds1302.year;	                 
   ds1302.year=(temp/10)*16+(temp%10);

   temp=ds1302.week;	                    
   ds1302.week=(temp/10)*16+(temp%10);
   write_time();
   write=0;
   }
 }


void time_to_uart(void)
{
	unsigned char temp;
		putstr ("20");
	putchar(ds1302.year/10+0x30);
	putchar(ds1302.year%10+0x30);
		putstr ("Year");
					putstr (" ");
	putchar(ds1302.month/10+0x30);
	putchar(ds1302.month%10+0x30);
		putstr ("Month");
					putstr (" ");
	putchar(ds1302.day/10+0x30);
	putchar(ds1302.day%10+0x30);
	  putstr ("Day");
					putstr (" ");
	  putstr ("Week");
	putchar(ds1302.week/10+0x30);
	putchar(ds1302.week%10+0x30);
	  putstr ("\n"); 
	putchar(ds1302.hour/10+0x30);
	putchar(ds1302.hour%10+0x30);
	  putstr ("Hour");
					putstr (" ");
	putchar(ds1302.minute/10+0x30);
	putchar(ds1302.minute%10+0x30);
	  putstr ("Minute");
					putstr (" ");
	putchar(ds1302.second/10+0x30);
	putchar(ds1302.second%10+0x30);
	  putstr ("second");
	  putstr ("\n"); 
}

int  main(void)
{ 
	unsigned char temp;  
	PINSEL0 = 0x00050000;           /* 设置引脚,开串口功能 */ 
	lcdInit();			/*初始化LCD显示*/
	ds1302_init();
	timer0_init();
	uart1Init();

	IO0DIR|=0xffff;		//设置为输出口
	IO0CLR=0xffff;	  

	IO0DIR&=~(0x07<<23); //设置P0.23~25为输入

	  write_ds1302_rtc(0x8e,0x00);
	  write_ds1302_rtc(0x90,0xa5); //打开ds1302涓流充电
	  write_ds1302_rtc(0x8e,0x80);
	//write_time();

//------数码管显示-----初始化
	IO1DIR|=(0xFF<<16);//P1.16-p1.23配置为输出
	IO1DIR|=(0xFF<<24);//P1.23-p1.31配置为输出
 
//---------------------------------------------
//以下将处理的结果存储在Datet和Time显示缓冲区中
while(1)
	{
	KeyBoard_Scan();

	if(1==halfsecondflag)
		{ 	
	halfsecondflag=0;			//清标志

   temp=read_ds1302_rtc(0x81);	                 //读收DS1302的秒单元
   ds1302.second=(temp/16)*10+(temp%16);

   temp=read_ds1302_rtc(0x83);	                 //读取DS1302的分单元
   ds1302.minute=(temp/16)*10+(temp%16);

   temp=read_ds1302_rtc(0x85);                   //读取DS1302的时单元
   ds1302.hour=(temp/16)*10+(temp%16);

   temp=read_ds1302_rtc(0x87);	                 //读取DS1302的日单元
   ds1302.day=(temp/16)*10+(temp%16);

   temp=read_ds1302_rtc(0x89);	                 //读取DS1302的月单元
   ds1302.month=(temp/16)*10+(temp%16);

   temp=read_ds1302_rtc(0x8d);	                  //读取DS1302的年单元
   ds1302.year=(temp/16)*10+(temp%16);

   temp=read_ds1302_rtc(0x8b);	                  //读取DS1302的星期单元  
   ds1302.week=(temp/16)*10+(temp%16);

	time_to_lcdbuffer();
		}
	display();

	if(1==secondflag)		 //隔1秒串口输出一次时间信息
		{ 	
	secondflag=0;			//清标志
	time_to_uart();
		}
	}
}

⌨️ 快捷键说明

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