📄 main.i
字号:
/************************************************
函数unsigned char FindKeyValue (void)用于查找键值
************************************************/
unsigned char FindKeyValue (void)
{
unsigned keyReturn; //返回的键值,并初始化为无键值
keyReturn = 0;
switch (keyState)
{
case 0:
PORTD.7 = 1; //第二行置高电平
PORTD.6 = 0; //第一行置低电平,扫描第一行
keyValue = PINB & keyMask; //读取键值
if(keyValue != keyMask) //如果有键按下,则进入状态1
{
keyState = 1;
}
else //否则第一行置高电平,第二行置低电平,扫描第二行
{
PORTD.6 = 1;
PORTD.7 = 0;
keyValue = PINB & keyMask; //读取键值
if(keyValue != keyMask) //如果有键按下,则进入状态1
{
keyState = 1;
}
else //否则第二行也置高电平
{
PORTD.7 = 1;
}
}
break;
case 1:
if (keyValue == (PINB & keyMask)) //如果读取的按键值和上次一样,则进入状态2,并判断按键,否则进入状态0
{
keyState = 2;
if (PORTD.6 )
{
switch(keyValue)
{
case 0b11100000:
keyReturn = 1;
break;
case 0b11010000:
keyReturn = 2;
break;
case 0b10110000:
keyReturn = 3;
break;
case 0b01110000:
keyReturn = 4;
break;
};
}
else
{
switch(keyValue)
{
case 0b11100000:
keyReturn = 5;
break;
case 0b11010000:
keyReturn = 6;
break;
case 0b10110000:
keyReturn = 7;
break;
case 0b01110000:
keyReturn = 8;
break;
};
}
}
else
{
keyState = 0;
}
break;
case 2: //状态2中判断按键是否已经释放,如果已经释放则返回状态0
PORTD.6 = 0;
PORTD.7 = 0;
if ((PINB & keyMask) == keyMask)
{
keyState = 0;
}
break;
};
return keyReturn;//返回读取的键值
}
// CodeVisionAVR C Compiler
// (C) 1998-2000 Pavel Haiduc, HP InfoTech S.R.L.
#pragma used+
void delay_us(unsigned int n);
void delay_ms(unsigned int n);
#pragma used-
// CodeVisionAVR C Compiler
// (C) 1998-2007 Pavel Haiduc, HP InfoTech S.R.L.
// Prototypes for string functions
#pragma used+
char *strcat(char *str1,char *str2);
char *strcatf(char *str1,char flash *str2);
char *strchr(char *str,char c);
signed char strcmp(char *str1,char *str2);
signed char strcmpf(char *str1,char flash *str2);
char *strcpy(char *dest,char *src);
char *strcpyf(char *dest,char flash *src);
unsigned int strlenf(char flash *str);
char *strncat(char *str1,char *str2,unsigned char n);
char *strncatf(char *str1,char flash *str2,unsigned char n);
signed char strncmp(char *str1,char *str2,unsigned char n);
signed char strncmpf(char *str1,char flash *str2,unsigned char n);
char *strncpy(char *dest,char *src,unsigned char n);
char *strncpyf(char *dest,char flash *src,unsigned char n);
char *strpbrk(char *str,char *set);
char *strpbrkf(char *str,char flash *set);
char *strrchr(char *str,char c);
char *strrpbrk(char *str,char *set);
char *strrpbrkf(char *str,char flash *set);
char *strstr(char *str1,char *str2);
char *strstrf(char *str1,char flash *str2);
char *strtok(char *str1,char flash *str2);
unsigned int strlen(char *str);
void *memccpy(void *dest,void *src,char c,unsigned n);
void *memchr(void *buf,unsigned char c,unsigned n);
signed char memcmp(void *buf1,void *buf2,unsigned n);
signed char memcmpf(void *buf1,void flash *buf2,unsigned n);
void *memcpy(void *dest,void *src,unsigned n);
void *memcpyf(void *dest,void flash *src,unsigned n);
void *memmove(void *dest,void *src,unsigned n);
void *memset(void *buf,unsigned char c,unsigned n);
unsigned int strcspn(char *str,char *set);
unsigned int strcspnf(char *str,char flash *set);
int strpos(char *str,char c);
int strrpos(char *str,char c);
unsigned int strspn(char *str,char *set);
unsigned int strspnf(char *str,char flash *set);
#pragma used-
#pragma library string.lib
//函数void LcdWriteData(unsigned char data)用于向LCD写入一个数据
void LcdWriteData(unsigned char data)
{
DDRA = 0xFF ;
PORTB.1 = 0 ;
PORTB.2 = 1 ;
PORTB.0 = 0 ;
#asm("nop")
#asm("nop")
PORTA = data;
PORTB.0 = 1 ;
#asm("nop")
#asm("nop")
PORTB.0 = 0 ;
#asm("nop")
#asm("nop")
}
//函数void LcdWriteInstruction(unsigned char data)用于向LCD写入一个指令
void LcdWriteInstruction(unsigned char data)
{
DDRA = 0xFF ;
PORTB.1 = 0 ;
PORTB.2 = 0 ;
PORTB.0 = 0 ;
#asm("nop")
#asm("nop")
PORTA = data;
PORTB.0 = 1 ;
#asm("nop")
#asm("nop")
PORTB.0 = 0 ;
#asm("nop")
#asm("nop")
}
//函数unsigned char LcdReadInstruction(void)用于从液晶读取指令
unsigned char LcdReadInstruction(void)
{
unsigned char data;
DDRA = 0x00 ;
PORTB.1 = 1 ;
PORTB.2 = 0 ;
PORTB.0 = 0 ;
#asm("nop")
#asm("nop")
PORTB.0 = 1 ;
#asm("nop")
#asm("nop")
data = PINA ;
PORTB.0 = 0 ;
#asm("nop")
#asm("nop")
return data;
}
//函数unsigned char LcdReadData(void)用于从液晶读取一个字节的数据
unsigned char LcdReadData(void)
{
unsigned char data;
DDRA = 0x00 ;
PORTB.1 = 1 ;
PORTB.2 = 1 ;
PORTB.0 = 0 ;
#asm("nop")
#asm("nop")
PORTB.0 = 1 ;
#asm("nop")
#asm("nop")
data = PINA ;
PORTB.0 = 0 ;
#asm("nop")
#asm("nop")
return data;
}
//函数void LcdCheckBusy(void)用于跳过液晶的忙状态
void LcdCheckBusy(void)
{
while (0x80 == (LcdReadInstruction() & 0x80))
{
}
}
//函数void LcdClear(void)用于液晶清屏
void LcdClear(void)
{
LcdCheckBusy();
LcdWriteInstruction(0x01);
}
//函数void LcdInit(void)用于初始化液晶
void LcdInit(void)
{
DDRB |= 0x07 ;
delay_ms(15);
LcdWriteInstruction(0x38); //LCD内部要求,初始化的时候连续三次设置显示模式
delay_ms(5);
LcdWriteInstruction(0x38);
delay_ms(5);
LcdWriteInstruction(0x38);
LcdCheckBusy();
LcdWriteInstruction(0x38); //8位数据接口
LcdCheckBusy();
LcdWriteInstruction(0x08); //关显示
LcdCheckBusy();
LcdWriteInstruction(0x01); //清屏
LcdCheckBusy();
LcdWriteInstruction(0x06); //读或者写一个字符后地址指针加1
LcdCheckBusy();
LcdWriteInstruction(0x0C); //开显示,不显示光标
}
//函数void LcdSetXY(unsigned char x, unsigned char y)用于指定液晶数据写入的地址
void LcdSetXY(unsigned char x, unsigned char y)
{
unsigned char addr;
addr = 0x80 + x * 0x40 + y; //计算地址
LcdCheckBusy();
LcdWriteInstruction(addr);
}
//函数void LcdPutOneChar(unsigned char c)用于向液晶输入一个显示数据
void LcdPutOneChar(unsigned char c)
{
LcdCheckBusy();
LcdWriteData(c);
}
//函数void LcdPutFlashString(unsigned char flash *str)用于向液晶输入位于Flash中的一个字符串
void LcdPutFlashString(unsigned char flash *str)
{
unsigned char i;
i = 0;
while (str[i] != '\0')
{
LcdCheckBusy();
LcdWriteData(str[i]);
i++;
}
}
//函数void LcdPutRamString(unsigned char *str)用于向液晶输入位于Ram中的一个字符串
void LcdPutRamString(unsigned char *str)
{
unsigned char i;
i = 0;
while (str[i] != '\0')
{
LcdCheckBusy();
LcdWriteData(str[i]);
i++;
}
}
/************************************************************
播放音乐使能TIME1之前必须完成以下工作
初始化*pMusic指针,使其指向某一首音乐
初始化maxMusic,使其等于*pMusic指针指向的音乐的数据的个数
初始化音乐播放的次数playCycle
初始化OCR1A,使其对应于第一个音符
初始化第一个音符比较匹配的次数iCompaCycle
初时话iMusicCycle为1
************************************************************/
/************************************************************
播放音乐使能TIME1之前必须完成以下工作
初始化*pMusic指针,使其指向某一首音乐
初始化maxMusic,使其等于*pMusic指针指向的音乐的数据的个数
初始化音乐播放的次数playCycle
初始化OCR1A,使其对应于第一个音符
初始化第一个音符比较匹配的次数iCompaCycle
初时话iMusicCycle为1
************************************************************/
/************************************************************
Timer1比较匹配中断处理函数
************************************************************/
interrupt [7] void Timer1CompaIsr(void)
interrupt [7] void Timer1CompaIsr(void)
interrupt [7] void Timer1CompaIsr(void)
{
if (--iCompaCycle == 0) //比较匹配次数是否到了
{
if(iMusicCycle < maxMusic) // 判断最后一个音符是否已经被播放
{
OCR1A = dataOfOCR1A[pMusic[++iMusicCycle]]; //装入下一个音符的数据
iCompaCycle = counter[pMusic[iMusicCycle]];
iCompaCycle = iCompaCycle * pMusic[++iMusicCycle];
if(OCR1A == 2500) // IF语句判断OCR1A中是否是装入了空音符的数据,如果是的话就把PD5释放
{
TCCR1A = 0x00;
}
else if (TCCR1A == 0x00) //非空音符时,如果PD5引脚已经释放,则与OCR1连接
{
TCCR1A = 0x40;
}
}
else if(--playCycle != 0) //判断播放次数是否已经为0
{
OCR1A = dataOfOCR1A[pMusic[0]]; //重新装入第一个音符的数据
iCompaCycle = counter[pMusic[0]] * pMusic[1];
iMusicCycle = 1;
if(OCR1A == 2500) // IF语句判断OCR1A中是否是装入了空音符的数据,如果是的话就把PD5释放
{
TCCR1A = 0x00;
}
else if (TCCR1A == 0x00) //非空音符时,如果PD5引脚已经释放,则与OCR1连接
{
TCCR1A = 0x40;
}
}
else
{
TCCR1B = 0x08; //播放结束,关闭TIME1的时钟
}
}
}
/************************************************************
函数MusicInit用于初始化音乐播放
************************************************************/
void MusicInit(void)
{
DDRD.5 = 1; //设置PD5为输出引脚
PORTD.5 = 0; //
TCCR1A = 0x40; //比较匹配时触发PD5引脚
TCCR1B = 0x08; //CTC模式,先不启动定时器
TIMSK |= 0x10; //开放定时器1的比较匹配功能
}
/************************************************************
函数void PlayMusic(unsigned char musicChoose, unsigned char counterChoose)
中musicChoose为选择播放的音乐,counterChoose为播放次数
************************************************************/
void PlayMusic(unsigned char musicChoose, unsigned char counterChoose)
{
//switch语句把选择的音乐序号对应的音乐数据付给pMusic指针
switch (musicChoose)
{
case 1:
pMusic = music1;
maxMusic = 273 ;
break;
case 2:
pMusic = music2;
maxMusic = 223 ;
break;
case 3:
pMusic = music3;
maxMusic = 137 ;
break;
case 4:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -