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

📄 main.i

📁 使用AVR单片机实现的万年历功能,其中使用了ds1302和1602
💻 I
📖 第 1 页 / 共 5 页
字号:
                DS1302Data[10] = DS1302Data[6];
		}
}




interrupt [20] void Timer0CompIsr(void)
interrupt [20] void Timer0CompIsr(void)
interrupt [20] void Timer0CompIsr(void)
{
	time2msIsOK = 1;	//中断中置2ms时间到
}
/*****************************************************
函数void TimingInit(void)为计时初始化函数
*****************************************************/
void TimingInit(void)
{
	TCCR0 = 0x0B;       //CTC模式,64分频,PB3为通用引脚(OC0不与其连接)
	OCR0 = 0x7C;        //OCR0置124
	TIMSK |= 0x02;      //允许TIM0比较匹配中断
	time10msCounter = 0;
	time500msCounter = 0;
	time2sCounter = 0;
	time20sCounter = 0;
}
/*****************************************************************
函数void FindTime(void)为查询2ms,10ms,500ms,2s,20s是否到的函数
*****************************************************************/
void FindTime(void)
{
	if (time2msIsOK)
	{
		time2msIsOK = 0;
        
		if(++time10msCounter == 5)
        {
			time10msIsOK = 1;
            time10msCounter = 0;                    
			
			if(++time500msCounter == 50)
            {
				time500msIsOK = 1;
				time500msCounter = 0;                                     
                
				if(++time2sCounter == 4)
				{
					time2sIsOK = 1;
					time2sCounter = 0;
					
					if(++time20sCounter == 10)
					{
						time20sIsOK = 1;
						time20sCounter = 0;
					}
                                                
				}
                                        
			}
                                
		}       
                        
	}  
	
}

 




/******************************************************
函数void UsartInit(void)用于初始化USART
******************************************************/
void UsartInit(void)
void UsartInit(void)
void UsartInit(void)
{
	UBRRH = (unsigned char)(((unsigned int)((unsigned long)4000000	/(16*(unsigned long)9600		)-1)) >> 8);    //计算波特率寄存器应该赋的值
	UBRRL = (unsigned char)((unsigned int)((unsigned long)4000000	/(16*(unsigned long)9600		)-1));
	UCSRC = 0xA6;                //设置偶校验,1位停止位,8位数据位
	UCSRA = 0x00;                //不设置倍速,波特率分频器分频系数为16
	UCSRB = 0x98;                //使能接收中断,使能接收和发送
	usartCounter = 0;
	DDRD.0 = 0;
	DDRD.1 = 1;
}

interrupt [12] void UsartReceive (void)
{
	unsigned char status;		//status用于存储接收数据的状态
	unsigned char data;			//data用于存储接收的数据
	unsigned char iCycle;		//循环变量
	status = UCSRA;				//读取状态量
	data = UDR;					//读取数据

	if((status & 0x1C) == 0x00)			//判断所读取的数据是否正确
	{

		if (data == 0xBB)				//判断是否为报文的起始字节
		{
			dataReceiveOK = 1;			//置位可以接收时钟数据的标志位
			usartCounter = 0;			//清0缓冲区计数器
		}
		else if (data == 0xEE)			//判断是否报文为结束字节
		{
			dataReceiveOK = 0;			//是的话清0可以接收时钟数据的标志位

			if (usartCounter == 8)		//如果连续8个字节都是没有错误
			{
				UDR = 0x01;				//向上位机返回1,否则返回0

				for (iCycle = 0; iCycle < 8; iCycle++)
				{
					DS1302Data[iCycle] = reBuffer[iCycle];	//把接收到的数据赋值给时钟变量
				}
				
				DS1302CheckDataOve();	//数据有效性判断
				FindDataOfWeek();		//计算星期
				DS1302WriteTimeData();	//写入DS1302

			}
			else
			{
				UDR = 0x00;		//接收不成功,向上位机返回0
			}
		}
		else
		{

			if (dataReceiveOK)
			{
				reBuffer[7-usartCounter] = data;	//把接收到的数据写入缓冲区
				++usartCounter;
			}
		}
	
	}
}

//interrupt [USART_TXC] void UsartTransmit (void)
//{
//}

//bit noiseSetFlag;	//用于存放闹钟是否起闹的标志
unsigned char noiseMusicChoose;		//定义闹钟音乐选择的变量
bit noiseMusicOrPlayMusic;			//标识设置播放的音乐还是闹钟音乐

 
void SeeLunarAndWeek(void);
void SetTimeAndSolar(void); 
void SetNoiseData(void);
void SetMusicPlay(void);        
unsigned char NoiseTimeFlag(void);

void SeeLunarAndWeek(void)
{
        LcdClear();		//清屏
        LcdSetXY(0, 0);		//设置显示农历初始化的数据
        LcdPutFlashString(lunarData);
        time2sIsOK = 0;				//清哦2s到达的标志以及计数器
        time2sCounter = 0;
        
        while (1)
        {
                FindTime();				//判断各个时间段是否已经到达
                        
                DS1302ReadTimeData(); //读取时间
				FindDataOfWeek();		//计算星期
                SolarToLunar();			//国历转换为农历
                Change();				//显示数据送缓冲区
                DisplayTwo();			//显示农历和星期
                                
                if (time2sIsOK == 1)		//2s到了则返回显示阳历和时间
                {
                        LcdSetXY(0, 0);
                        LcdPutFlashString(solarData);
                        LcdSetXY(1, 0);
                        LcdPutFlashString(timeData);
                        DisplayOne();
                        break;
                }

                
        }
}

void SetTimeAndSolar(void)
{
        unsigned char key6KeyValue;			//用于存储键值
        bit setbit;							//有键按下的标志
        bit setOnbit;						//显示的标志
        unsigned char key6I;				//循环变量
        
        setbit = 0;							//各个标志位清0
        setOnbit = 0;
        key6KeyValue = 0;
        time10msIsOK = 0;   
        time500msIsOK = 0; 
        time20sIsOK = 0;
        time500msCounter = 0;
        time20sCounter = 0;
		//显示初始化
        LcdSetXY(0, 0);
        LcdPutFlashString(solarData);
        LcdSetXY(1, 0);
        LcdPutFlashString(timeData);
        DS1302ReadTimeData();
        Change();
        DisplayOne(); 
        
        key6I = 0;
        
        while (1)
        {
                FindTime();		//判断各个时间段是否已经到达
                
                if(time10msIsOK)
                {
                        time10msIsOK = 0;
                        key6KeyValue = FindKeyValue();		//读取键值
                        
                        switch (key6KeyValue)
                        {
                        case 6: 
                                time20sCounter = 0;			//只要有键按下则清0 20s计数器
                                
                                if (setbit)					//设置时间
                                {
		                        FindDataOfWeek();	//计算星期
                                        DS1302WriteTimeData();
                                }
                                
                                break;
                        case 1:		//按键1为右移处理
                                setbit = 1;				//有键按下标志位置1,表示有键按下
                                time20sCounter = 0;			//只要有键按下则清0 20s计数器
                                //以下两行显示为了防止刚才恰好没有显示  
                                LcdPutOneChar((DS1302Data[key6I] / 10) + 48);
                                LcdPutOneChar((DS1302Data[key6I] % 10) + 48);  
                                
                                if (key6I == 0)
                                {
                                        key6I = 6;
                                }
                                else if (key6I == 4)
                                {
                                        key6I = 2;
                                }
                                else
                                {
                                        --key6I;
                                }
                                
                                break;
                        case 2:		//按键2为左移处理
                                setbit = 1;				//有键按下标志位置1,表示有键按下
                                time20sCounter = 0;			//只要有键按下则清0 20s计数器  
                                //以下两行显示为了防止刚才恰好没有显示
                                LcdPutOneChar((DS1302Data[key6I] / 10) + 48);
                                LcdPutOneChar((DS1302Data[key6I] % 10) + 48);
                                
                                if (key6I == 6)
                                {
                                        key6I = 0;
                                }
                                else if (key6I == 2)
                                {
                                        key6I = 4;
                                }
                                else
                                {
                                        ++key6I;
                                }
                                
                                break;
                        case 3:		//	按键3为加1处理
                                setbit = 1;				//有键按下标志位置1,表示有键按下
                                time20sCounter = 0;			//只要有键按下则清0 20s计数器
                                ++DS1302Data[key6I];
                                break;
                         case 4:			//按键4为减1处理
                                setbit = 1;				//有键按下标志位置1,表示有键按下
                                time20sCounter = 0;			//只要有键按下则清0 20s计数器
                                --DS1302Data[key6I];
                                break;
                         case 5:			//按键5为加10处理
                                setbit = 1;				//有键按下标志位置1,表示有键按下
                                time20sCounter = 0; 			//只要有键按下则清0 20s计数器
                                DS1302Data[key6I] += 10;
                                break;
                         case 8:				//按键8为减10处理
                                setbit = 1;				//有键按下标志位置1,表示有键按下
                                time20sCounter = 0;			//只要有键按下则清0 20s计数器
                                DS1302Data[key6I] -= 10;
                                break;
                         };
                         
                } 
                
                if ((key6KeyValue == 6)||(time20sIsOK ==1))//按下退出键或者20s没有键按下则推出时间设置
                {       
                        
                        DS1302ReadTimeData();
                        FindDataOfWeek();
                        Change();
                        LcdSetXY(0, 0);
                        LcdPutFlashString(solarData);
                        LcdSetXY(1, 0);
                        LcdPutFlashString(timeData);
                        DisplayOne(); 
                        break;
                }
                else
                {
                        if (time500msIsOK)			//500ms到,取反显示标志
                        {
                                time500msIsOK = 0;
                                setOnbit = ~setOnbit;
                        }
                        
                        switch (key6I)			//选择显示的位置
                        { 
                        case 0: 
                                LcdSetXY(1, 14);
                                break;
                        case 1:
                                LcdSetXY(1, 11);
                                break;
                        case 2:                 
                                LcdSetXY(1, 8);
                                break;
                        case 4: 
                                LcdSetXY(0, 14);
                                break;
                        case 5:                 
                                LcdSetXY(0, 11);
                                break;
                        case 6:                 
                                LcdSetXY(0, 8);
                                break;
                        };
                        
                        DS1302CheckDataOve();
                        
                        if (setOnbit)			//500ms显示数据,500ms显示空格
                        {
                                LcdPutOneChar(0x20);
                                LcdPutOneChar(0x20);
                        }
                        else
                        {
                                LcdPutOneChar((DS1302Data[key6I] / 10) + 48);
                                LcdPutOneChar((DS1302Data[key6I] % 10) + 48);
                        }  
                        
                        switch (key6I)			//选择显示的位置
                        { 
                        case 0: 
                                LcdSetXY(1, 14);
                                break;
                        case 1:
                                LcdSetXY(1, 11);
                                break;
                        case 2:                 
                                LcdSetXY(1, 8);
                                break;
                        case 4: 
                                LcdSetXY(0, 14);
                                break;
                        case 5:                 
                                LcdSetXY(0, 11);
                                break;
                        case 6:                 
                                LcdSetXY(0, 8);
                                break;
                        };
                }
                
        }
        
        
} 

void SetNoiseData(void)
{
        unsigned char key7KeyValue;		//存储按键键值的变量
        bit setbit;						//有键按下的标志
        bit setOnbit;					//显示的标志
        unsigned char key7I;			//循环变量
        
        setbit = 0;						//各个标志位清0
        setOnbit = 0;
        key7KeyValue = 0;
        time10msIsOK = 0;   
        time500msIsOK = 0; 
        time20sIsOK = 0;
        time500msCounter = 0;
        time20sCounter = 0;
               
        DS1302ReadRamData();			//读取闹钟数据
         

        
        for (key7I = 0; key7I < 8; key7I++)				//把闹钟数据赋值给DS1302Data
        {
                DS1302Data[key7I] = noiseData[key7I];
        }
        
		//显示初始化

        LcdSetXY(0, 0);
        LcdPutFlashString(solarData);
        LcdSetXY(1, 0);
        LcdPutFlashString(timeData);
        Change();
        DisplayOne(); 
 
         LcdSetXY(1, 6);	
         if (noiseData[8] == 0x01)
         {
                LcdPutOneChar(0x2A);
         }
         else
         {
                LcdPutOneChar(0x20);
         }
                
        key7I = 0;
        
        while (1)
        {
                FindTime();		//判断各个时间段是否已经到达
                
                if(time10msIsOK)
                {
                        time10msIsOK = 0;
                        key7KeyValue = FindKeyValue();		//读取键值
                        
                        switch (key7KeyValue)
                        {
                        case 7: 
                                time20sCounter = 0;			//只要有键按下则清0 20s计数器
                                
               

⌨️ 快捷键说明

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