main.i

来自「使用AVR单片机实现的万年历功能,其中使用了ds1302和1602」· I 代码 · 共 1,876 行 · 第 1/5 页

I
1,876
字号
        0x1d,0x2a,0xd5,0x00,
        0x8a,0x2b,0x65,0x02,
        0x14,0x1b,0x4a,0x00,
        0x82,0x1d,0x52,0x06,
        0x0d,0x1c,0x95,0x00,
        0x18,0x19,0x2d,0x00,
        0x85,0x19,0x2e,0x05,
        0x11,0x32,0xad,0x00,
        0x1c,0x15,0x6b,0x00,
        0x88,0x15,0xac,0x03,
        0x13,0x2d,0xa5,0x00,
        0x81,0x2e,0xa5,0x0b,
        0x0b,0x2d,0x4a,0x00,
        0x16,0x2c,0x96,0x00,
        0x84,0x34,0x97,0x06,
        0x10,0x29,0x2f,0x00,
        0x1a,0x12,0xae,0x00,
        0x87,0x0a,0xb6,0x05,
        0x11,0x16,0xb4,0x00,
        0x1d,0x2d,0xa9,0x00,
        0x8a,0x36,0xa5,0x02,
        0x15,0x36,0x4b,0x00,
        0x82,0x3a,0x4b,0x07,
        0x0e,0x34,0x97,0x00,
        0x19,0x29,0x57,0x00,
        0x86,0x29,0x5b,0x05,
        0x10,0x12,0xda,0x00,
        0x1c,0x16,0xd5,0x00,
        0x88,0x1b,0x54,0x03
};
/*****************************************************
二维字符数组week[7][17]用于存放星期一到星期天的英文数据
*****************************************************/
flash char week[7][17]=
{
"WEEK:     MONDAY",
"WEEK:    TUESDAY",
"WEEK:  WEDNESDAY",
"WEEK:   THURSDAY",
"WEEK:     FRIDAY",
"WEEK:   SATURDAY",
"WEEK:     SUNDAY"
};       
/*****************************************************
数组solarData[17]、lunarData[17]、timeData[17]用于初始化显示
*****************************************************/
flash char solarData[17] = "SOLAR:20  -  -  ";  //  用于存放阳历的数据
flash char lunarData[17] = "LUNAR:20  -  -  ";  //  用于存放阴历的数据
flash char timeData[17] = "TIME:     :  :  ";   //  用于存放时间的数据
/*****************************************************
display1用于存放时间和星期的缓冲区数据
display2用于存放国历的缓冲区数据
display3用于存放农历的缓冲区数据
*****************************************************/
unsigned char display1[8];
unsigned char display2[8];
unsigned char display3[8];

void Change(void);
void DisplayOne(void);
void DisplayTwo(void);
unsigned int FindDataOfYear(void);
void FindDataOfWeek(void);
void SolarToLunar(void);


bit time2msIsOK;	//2ms时间到
bit time10msIsOK;	//10ms时间到
bit time500msIsOK;	//500ms时间到
bit time2sIsOK;		//2s时间到
bit time20sIsOK;	//20s时间到
unsigned char time10msCounter;	//用于计算2ms的个数
unsigned char time500msCounter;	//用于计算10ms的个数
unsigned char time2sCounter;	//用于计算500ms的个数
unsigned char time20sCounter;	//用于计算2s的个数

void TimingInit(void);
void FindTime(void);

/******************************************************
数据帧格式 BB 20 08 12 23 00 14 15 10 EE
BB 起始字节
20 年高位
08 年低位
12 月份
23 日期
00 空字节
14 小时
15 分钟
10 秒
EE 结束字节
******************************************************/

 

unsigned char reBuffer[8];	//定义接收缓冲区
unsigned char usartCounter;	//接收数据的个数
bit dataReceiveOK;			//标志接收OK

void UsartInit(void);




/*
  CodeVisionAVR C Compiler
  (C) 1998-2007 Pavel Haiduc, HP InfoTech S.R.L.

  BCD conversion functions
*/


#pragma used+

unsigned char bcd2bin(unsigned char n);
unsigned char bin2bcd(unsigned char n);

#pragma used-

#pragma library bcd.lib

/*****************************************************
函数void DS1302WriteOneWord(unsigned char addr, unsigned char data)
用于向DS1302的addr地址写入data的数据
*****************************************************/
void DS1302WriteOneWord(unsigned char addr, unsigned char data)
{
	unsigned char i;
	DDRD |= 0x0C	;
	DDRD.4 = 1	;
	PORTD.2 = 0	;
	#asm("nop")
	#asm("nop")
	PORTD.3 = 0	;
	#asm("nop")
	#asm("nop")
	PORTD.2 = 1	;
	#asm("nop")
	#asm("nop")

	for(i = 8; i > 0; i--)
	{
		
		if (addr & 0x01)
		{
			PORTD.4 = 1	;
		}
		else
		{
			PORTD.4 = 0	;
		}

		#asm("nop")
		#asm("nop")
		PORTD.3 = 1	;
		#asm("nop")
		#asm("nop")
		PORTD.3 = 0	;
		#asm("nop")
		#asm("nop")
		addr = addr >> 1;
	}

	for(i = 8; i > 0; i--)
	{
		
		if (data & 0x01)
		{
			PORTD.4 = 1	;
		}
		else
		{
			PORTD.4 = 0	;
		}

		#asm("nop")
		#asm("nop")
		PORTD.3 = 1	;
		#asm("nop")
		#asm("nop")
		PORTD.3 = 0	;
		#asm("nop")
		#asm("nop")
		data = data >> 1;
	}

	PORTD.2 = 0	;
	#asm("nop")
	#asm("nop")
}
/*****************************************************
函数unsigned char DS1302ReadOneWord(unsigned char addr)
用于从DS1302中的addr地址读取数据
*****************************************************/
unsigned char DS1302ReadOneWord(unsigned char addr)
{
	unsigned char i;
	unsigned char data;
	DDRD |= 0x0C	;
	DDRD.4 = 1	;
	PORTD.2 = 0	;
	#asm("nop")
	#asm("nop")
	PORTD.3 = 0	;
	#asm("nop")
	#asm("nop")
	PORTD.2 = 1	;
	#asm("nop")
	#asm("nop")

	for(i = 8; i > 0; i--)
	{
		
		if (addr & 0x01)
		{
			PORTD.4 = 1	;
		}
		else
		{
			PORTD.4 = 0	;
		}

		#asm("nop")
		#asm("nop")
		PORTD.3 = 1	;
		#asm("nop")
		#asm("nop")
		PORTD.3 = 0	;
		#asm("nop")
		#asm("nop")
		addr = addr >> 1;
	}

	DDRD.4 = 0		;
	data = 0;

	for (i = 8; i > 0; i--)
	{
		data = data >> 1;

		if (PIND.4 == 1	)
		{
			data |= 0x80;
		}

		PORTD.3 = 1	;
		#asm("nop")
		#asm("nop")
		PORTD.3 = 0	;
		#asm("nop")
		#asm("nop")
	}
	
	PORTD.2 = 0	;
	#asm("nop")
	#asm("nop")
	return (data);

}
/*****************************************************
函数void DS1302WriteTimeData(void)用于向DS1302
写入时钟日期数据
*****************************************************/
void DS1302WriteTimeData(void)
{
	DS1302WriteOneWord(0x8E, 0x00);							//关闭写保护
	DS1302WriteOneWord(0x80, 0x80);							//关闭时钟
	DS1302WriteOneWord(0x8C, bin2bcd(DS1302Data[6]));		//写入年份		
	DS1302WriteOneWord(0x88, bin2bcd(DS1302Data[5]));		//写入月份
	DS1302WriteOneWord(0x86, bin2bcd(DS1302Data[4]));		//写入日		
	DS1302WriteOneWord(0x8A, bin2bcd(DS1302Data[3]));		//写入星期		
	DS1302WriteOneWord(0x84, bin2bcd(DS1302Data[2]));		//写入小时
	DS1302WriteOneWord(0x82, bin2bcd(DS1302Data[1]));		//写入分钟
	DS1302WriteOneWord(0x80, bin2bcd(DS1302Data[0]));		//写入秒,开启时钟
	DS1302WriteOneWord(0x8E, 0x80);							//开启写保护
}
/*****************************************************
函数void DS1302ReadTimeData(void)用于从DS1302中
读取时钟日期数据
*****************************************************/
void DS1302ReadTimeData(void)
{
	DS1302WriteOneWord(0x8E, 0x00);							//关闭写保护
	DS1302Data[6] = bcd2bin(DS1302ReadOneWord(0x8D));		//读取年份
	DS1302Data[5] = bcd2bin(DS1302ReadOneWord(0x89));		//读取月份
	DS1302Data[4] = bcd2bin(DS1302ReadOneWord(0x87));		//读取日
	DS1302Data[3] = bcd2bin(DS1302ReadOneWord(0x8B));		//读取星期
	DS1302Data[2] = bcd2bin(DS1302ReadOneWord(0x85));		//读取小时
	DS1302Data[1] = bcd2bin(DS1302ReadOneWord(0x83));		//读取分钟
	DS1302Data[0] = bcd2bin(DS1302ReadOneWord(0x81));		//读取秒
	DS1302WriteOneWord(0x8E, 0x80);							//开启写保护
}

/*****************************************************
函数void DS1302WriteRamData(void)用于向DS1302
写入闹钟数据
*****************************************************/
void DS1302WriteRamData(void)
{
	DS1302WriteOneWord(0x8E, 0x00);							//关闭写保护
	DS1302WriteOneWord(0xCE, bin2bcd(noiseData[8]));
	DS1302WriteOneWord(0xCC, bin2bcd(noiseData[6]));		//写入年份		
	DS1302WriteOneWord(0xC8, bin2bcd(noiseData[5]));		//写入月份
	DS1302WriteOneWord(0xC6, bin2bcd(noiseData[4]));		//写入日		
	DS1302WriteOneWord(0xCA, bin2bcd(noiseData[3]));		//写入星期		
	DS1302WriteOneWord(0xC4, bin2bcd(noiseData[2]));		//写入小时
	DS1302WriteOneWord(0xC2, bin2bcd(noiseData[1]));		//写入分钟
	DS1302WriteOneWord(0xC0, bin2bcd(noiseData[0]));		//写入秒
	DS1302WriteOneWord(0x8E, 0x80);							//开启写保护
}
/*****************************************************
函数void DS1302ReadRamData(void)用于从DS1302中
读取闹钟数据
*****************************************************/
void DS1302ReadRamData(void)
{
	DS1302WriteOneWord(0x8E, 0x00);							//关闭写保护
	noiseData[8] = bcd2bin(DS1302ReadOneWord(0xCF));
	noiseData[6] = bcd2bin(DS1302ReadOneWord(0xCD));		//读取年份
	noiseData[5] = bcd2bin(DS1302ReadOneWord(0xC9));		//读取月份
	noiseData[4] = bcd2bin(DS1302ReadOneWord(0xC7));		//读取日
	noiseData[3] = bcd2bin(DS1302ReadOneWord(0xCB));		//读取星期
	noiseData[2] = bcd2bin(DS1302ReadOneWord(0xC5));		//读取小时
	noiseData[1] = bcd2bin(DS1302ReadOneWord(0xC3));		//读取分钟
	noiseData[0] = bcd2bin(DS1302ReadOneWord(0xC1));		//读取秒
	DS1302WriteOneWord(0x8E, 0x80);							//开启写保护
}
/*****************************************************
函数void DS1302CheckDataOve(void)用于纠正校时数据的错误
*****************************************************/
void DS1302CheckDataOve(void)
{

	unsigned char checkDayOve;
	
	DS1302Data[7] = 20;
	
	if (DS1302Data[0] > 59)
	{
		DS1302Data[0] = 59;
	}

	if (DS1302Data[1] > 59)
	{
		DS1302Data[1] = 59;
	}

	if (DS1302Data[2] > 23)
	{
		DS1302Data[2] = 23;
	}

	if (DS1302Data[6] > 50)
	{
		DS1302Data[6] = 50;
	}
	else if (DS1302Data[6] == 0)
	{
	        DS1302Data[6] = 1;
	}

	if (DS1302Data[5] > 12)
	{
		DS1302Data[5] = 12;
	} 
	else if (DS1302Data[5] == 0)
	{
	        DS1302Data[5] = 1;
	}

	switch (DS1302Data[5])
	{
	case 2:
		if (DS1302Data[6] % 4)
		{
			checkDayOve = 28;
		}
		else
		{
			checkDayOve = 29;
		}
		break;

	case 4:
		checkDayOve = 30;
		break;

	case 6:
		checkDayOve = 30;
		break;

	case 9:
		checkDayOve = 30;
		break;

	case 11:
		checkDayOve = 30;
		break;

	default :
		checkDayOve = 31;
		break;
	};

	if (DS1302Data[4] > checkDayOve)
	{
		DS1302Data[4] = checkDayOve;
	}
	else if (DS1302Data[4] == 0)
	{
	        DS1302Data[4] = 1;
	}

}




void KeyInit(void)
void KeyInit(void)
void KeyInit(void)
{
	//设置引脚的输入模式和输出模式
	DDRB &= 0x0F		;
	PORTB |= 0xF0		;
	DDRD |= 0xC0		;
	PORTD |= 0xC0			;

	keyMask = 0xF0;   //屏蔽码,没有按键时为0xF0
	keyValue = 0x00;  //初始化键值为0
	keyState = 0x00;  //初始化按键状态为第0歌状态
}

⌨️ 快捷键说明

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