2024-09-01
售卖作品
00

在这里插入图片描述

c
#include <reg52.h> #include <intrins.h> #include "lcd1602.h" //按键1 暂停播放 //按键2 上一首 //按键3 下一首 //按键4 加速播放 //按键5 减速播放 #define uchar unsigned char #define uint unsigned int //以下是C调低音的音频宏定义 #define L1 262 //将"L1"宏定义为低音"1"的频率262Hz 时间是1/262=3826/2 us 取半周期 #define L2 286 //将"L2"宏定义为低音"2"的频率286Hz #define L3 311 //将"L3"宏定义为低音"3"的频率311Hz #define L4 349 //将"L4"宏定义为低音"4"的频率349Hz #define L5 392 //将"L5"宏定义为低音"5"的频率392Hz #define L6 440 //将"l_a"宏定义为低音"6"的频率440Hz #define L7 494 //将"L7"宏定义为低音"7"的频率494Hz //以下是C调中音的音频宏定义 #define Z1 523 //将"Z1"宏定义为中音"1"的频率523Hz #define Z2 587 //将"Z2"宏定义为中音"2"的频率587Hz #define Z3 659 //将"Z3"宏定义为中音"3"的频率659Hz #define Z4 698 //将"Z4"宏定义为中音"4"的频率698Hz #define Z5 784 //将"Z5"宏定义为中音"5"的频率784Hz #define Z6 880 //将"Z6"宏定义为中音"6"的频率880Hz #define Z7 987 //将"Z7"宏定义为中音"7"的频率523H //以下是C调高音的音频宏定义 #define H1 1046 //将"H1"宏定义为高音"1"的频率1046Hz #define H2 1174 //将"H2"宏定义为高音"2"的频率1174Hz #define H3 1318 //将"H3"宏定义为高音"3"的频率1318Hz #define H4 1396 //将"H4"宏定义为高音"4"的频率1396Hz #define H5 1567 //将"H5"宏定义为高音"5"的频率1567Hz #define H6 1760 //将"H6"宏定义为高音"6"的频率1760Hz #define H7 1975 //将"H7"宏定义为高音"7"的频率1975Hz /* ****************************************** */ // ******** 硬件端口定义 /* ****************************************** */ sbit sound = P1 ^ 6; //蜂鸣器 /* ****************************************** */ // ******** 程序变量定义 /* ****************************************** */ unsigned int C; //储存定时器的定时常数 unsigned char u, t; //音乐所用的变量 unsigned char velocity = 60; //控制节拍使用的 这里100表示一个拍子100ms unsigned char press_key = 0; //按键 按下后会改变数值 初始值为0 unsigned char open_flag = 0; //暂停时为0 播放时为1 unsigned char music_crr = 0; //当前是播放哪一首音乐 可以为0 1 2 分别是是三首歌 unsigned char code name0[]="1 TianKongZC "; unsigned char code name1[]="2 LiangZhiLaoHu "; unsigned char code name2[]="3 MoLiHua "; unsigned char code name3[]="4 XiaoXingXing "; unsigned char *song_name[]={name0,name1,name2,name3}; /* ****************************************** */ // ******** 音乐0 天空之城 /* ****************************************** */ //以下是《天空之城》简谱 //每行对应一小节音符 unsigned int code music0[]= { Z6,Z7,/**/H1,Z7,H1,H3,/**/Z7,Z3,Z3, /**/Z6,Z5,Z6,H1,/**/Z5,Z3,Z3, /**/Z4,Z3,Z4,H1, Z3,H1,H1,H1,/**/Z7,Z4,Z4,Z7,/**/Z7,Z6,Z7, /**/H1,Z7,H1,H3,/**/Z7,Z3,Z3, /**/Z6,Z5,Z6,H1, Z5, Z3,/**/Z4,H1,Z7,H1,/**/H2,H2,H2,H1,/**/H1,Z6,Z7,Z5,/**/Z6,H1,H2, /**/H3,H2,H3,H5, H2,Z5,Z5, /**/H1,Z7,H1,H3,/**/H3, /**/Z6,H1,Z7,H2,/**/H1,Z5,Z5, /**/H4,H3,H2,H1, H3, /**/Z3,H3, /**/H6,H5,H5, /**/H3,H2,H1,H1,/**/H2,H1,H2,H5,/**/H3,H3, H6,H5, /**/H3,H2,H1,H1,/**/H2,H1,H2,Z7,/**/Z6,Z6,Z7, /**/Z6,0xff}; //以0xff作为音符的结束标志 //以下是简谱中每个音符的节拍 //"4"对应4个延时单位,"2"对应2个延时单位,"1"对应1个延时单位 unsigned char code music0_JP[ ]= { 4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,4,12, 20,4,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, 32, 4, /**/8,4,6,8, /**/4,4,4,16, /**/8,4,6,8, /**/24,4,4, /**/12,4,8,8, 24,4,4, /**/4,4,8,8, /**/32, /**/4,8,8,6, /**/12,4,16, /**/8,8,8,8, 30, /**/20,8, /**/16,8,8, /**/4,4,16,8, /**/8,4,4,8, /**/20,8, 16,16, /**/4,20,8, /**/8,4,4,8, /**/20,4,4, /**/32}; /* ****************************************** */ // ******** 音乐1 /* ****************************************** */ unsigned int code music1[]= { Z1,Z2,Z3,Z1,Z1,Z2,Z3,Z1,Z3,Z4,Z5,Z3,Z4,Z5,Z5,Z6,Z5,Z4, Z3,Z1,Z5,Z6,Z5,Z4,Z3,Z1,Z2,L5,Z1,Z2,L5,Z1,0xff}; //以0xff作为音符的结束标志 //以下是简谱中每个音符的节拍 //"4"对应4个延时单位,"2"对应2个延时单位,"1"对应1个延时单位 unsigned char code music1_JP[ ]= { 8,8,8,8,8,8,8,8,8,8,8,8,8,8,4,4,4,4,8,8,4,4,4,4,8,8,8,8,16,8,8,8,1}; /* ****************************************** */ // ******** 音乐2 /* ****************************************** */ unsigned int code music2[]= { Z3,Z3,Z5,Z6,H1,H1,Z6, Z5,Z5,Z6,Z5, Z3,Z3,Z5,Z6,H1,H1,Z6, Z5,Z5,Z6,Z5, Z5,Z5,Z5,Z3,Z5, Z6,Z6,Z5, Z3,Z2,Z3,Z5,Z3,Z2, Z1,Z1,Z2,Z1,0xff}; //以0xff作为音符的结束标志 //以下是简谱中每个音符的节拍 //"4"对应4个延时单位,"2"对应2个延时单位,"1"对应1个延时单位 unsigned char code music2_JP[ ]= { 16,8,8,8,8,8,8, 16,8,8,32, 16,8,8,8,8,8,8, 16,8,8,32, 16,16,16,8,8, 16,16,32, 16,8,8,16,8,8, 16,8,8,32,1}; /* ****************************************** */ // ******** 音乐3 小星星 /* ****************************************** */ unsigned int code music3[]= { H3,H3,H3,H2,H1,H2,H5,H5,H1,H1,H1,H1,Z6, Z7,H3,H3,Z5,Z6,H6,H5,H4,H3,H2,H1,H1, Z6,H1,H2,H5,H5,H2,H1,H2,H2,Z1,H3,H3, H3,H2,H1,H2,H5,H5,H1,H1,H1,H1,Z6,Z7, H3,H3,Z5,Z6,H6,H5,H4, H3,H2,H1,H1,Z6,H1,H2,H5,H5,Z5,H2,H1, 0xff}; //以0xff作为音符的结束标志 //以下是简谱中每个音符的节拍 //"4"对应4个延时单位,"2"对应2个延时单位,"1"对应1个延时单位 unsigned char code music3_JP[ ]= { 8,2,2,2,2,4,4,8, 8,2,2,2,2, 4,4,4,4,8,4,2,2,4,2,2,8, 2,2,2,2,2,2,2,2,8,8,8,2,2,2,2,4,4,8,8,2,2,2,2,4,4,4,4,8,4,2,2, 8,2,2,4,2,2,2,2,2,2,4,12 }; /* ****************************************** */ // ******** 延时1ms 用于一般延时 /* ****************************************** */ void delay(uint z) { uint x; while (z--) { for (x = 125; x > 0; x--) ; } } /* ****************************************** */ // ******** 延时100ms 控制音乐节拍 /* ****************************************** */ void delay1() { uint i, j; for (i = 0; i < velocity; i++) for (j = 0; j < 125; j++) ; } /* ****************************************** */ // ******** 定时器初始化函数 用了定时器1 /* ****************************************** */ void init_timer(void) { EA = 1; //开总中断 ET1 = 1; //定时器T1中断允许 TMOD &= 0x0f; TMOD |= 0x00; // 使用定时器T1的模式1(13位计数器) TR1 = 1; } #define GPIO_KEY P3 /* 矩阵键盘扫描 电子琴 */ unsigned char ScanKey( void ) { char a = 0; unsigned char map[]={3,7,11,15,2,6,10,14,1,5,9,13,0,4,8,12}; unsigned char KeyValue = 0xff; GPIO_KEY = 0x0f; if ( GPIO_KEY != 0x0f ) /* 读取按键是否按下 */ { delay( 5 ); /* 延时10ms进行消抖 */ if ( GPIO_KEY != 0x0f ) /* 再次检测键盘是否按下 */ { /* 测试列 */ GPIO_KEY = 0X0F; switch ( GPIO_KEY ) { case (0X07): KeyValue = 0; break; case (0X0b): KeyValue = 1; break; case (0X0d): KeyValue = 2; break; case (0X0e): KeyValue = 3; break; } /* 测试行 */ GPIO_KEY = 0XF0; switch ( GPIO_KEY ) { case (0X70): KeyValue = KeyValue; break; case (0Xb0): KeyValue = KeyValue + 4; break; case (0Xd0): KeyValue = KeyValue + 8; break; case (0Xe0): KeyValue = KeyValue + 12; break; } while ( (a < 100) && (GPIO_KEY != 0xf0) ) /* 检测按键松手检测 */ { delay( 10 ); a++; } KeyValue=map[KeyValue]+1; } } return KeyValue;//返回按键 } /* ****************************************** */ // ******** 处理按键 按下按键后 相应变量改变 /* ****************************************** */ void delay_key(void) { if (press_key == 1) //暂停控制 { press_key = 0; if (open_flag == 0) { open_flag = 1; //开始 } else { open_flag = 0; //暂停 } } if (press_key == 2) //上一首 { press_key = 0; if (music_crr > 0) { music_crr = (music_crr - 1) % 4; } else { music_crr = 3; //如果是第0首歌 那么按上一首就是第3首 } LCD_write_str(0,0,song_name[music_crr]);//显示歌名 } if (press_key == 3) //下一首 { press_key = 0; music_crr = (music_crr + 1) % 4; LCD_write_str(0,0,song_name[music_crr]);//显示歌名 } if (press_key == 4) //加快播放速度 { press_key = 0; velocity = velocity - 5; } if (press_key == 5) //降低播放速度 { press_key = 0; velocity = velocity + 5; } } /* ****************************************** */ // ******** 主函数 程序逻辑 /* ****************************************** */ void main() { LCD_init(); init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 open_flag = 0; //关闭音乐 LCD_write_str(0,0,song_name[music_crr]);//显示歌名 while (1) { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 if (music_crr == 0 && open_flag == 1) { u = 0; //从第1个音符f[0]开始播放 while (music0[u] != 0xff) //只要没有读到结束标志就继续播放 { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 if (music_crr != 0) //切换音乐 { init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 break; } if (open_flag == 0) //如果暂停音乐 { while (open_flag == 0) { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 } } C = 460830 / music0[u]; TH1 = (8192 - C) / 32; //可证明这是13位计数器TH0高8位的赋初值方法 5 TL1 = (8192 - C) % 32; //可证明这是13位计数器TL0低5位的赋初值方法 TR1 = 1; //启动定时器T0 for (t = 0; t < music0_JP[u]; t++) //控制节拍数 delay1(); //延时1个节拍单位 TR1 = 0; //关闭定时器T1 u++; //播放下一个音符 } init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 } if (music_crr == 1 && open_flag == 1) { u = 0; //从第1个音符f[0]开始播放 while (music1[u] != 0xff) //只要没有读到结束标志就继续播放 { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 if (music_crr != 1) //切换音乐 { init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 break; } if (open_flag == 0) //如果暂停音乐 { while (open_flag == 0) { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 } } C = 460830 / music1[u]; TH1 = (8192 - C) / 32; //可证明这是13位计数器TH0高8位的赋初值方法 5 TL1 = (8192 - C) % 32; //可证明这是13位计数器TL0低5位的赋初值方法 TR1 = 1; //启动定时器T0 for (t = 0; t < music1_JP[u]; t++) //控制节拍数 delay1(); //延时1个节拍单位 TR1 = 0; //关闭定时器T1 u++; //播放下一个音符 } init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 } if (music_crr == 2 && open_flag == 1) { u = 0; //从第1个音符f[0]开始播放 while (music2[u] != 0xff) //只要没有读到结束标志就继续播放 { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 if (music_crr != 2) //切换音乐 { init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 break; } if (open_flag == 0) //如果暂停音乐 { while (open_flag == 0) { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 } } C = 460830 / music2[u]; TH1 = (8192 - C) / 32; //可证明这是13位计数器TH0高8位的赋初值方法 5 TL1 = (8192 - C) % 32; //可证明这是13位计数器TL0低5位的赋初值方法 TR1 = 1; //启动定时器T0 for (t = 0; t < music2_JP[u] / 2; t++) //控制节拍数 delay1(); //延时1个节拍单位 TR1 = 0; //关闭定时器T1 u++; //播放下一个音符 } init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 } if (music_crr == 3 && open_flag == 1) { u = 0; //从第1个音符f[0]开始播放 while (music2[u] != 0xff) //只要没有读到结束标志就继续播放 { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 if (music_crr != 3) //切换音乐 { init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 break; } if (open_flag == 0) //如果暂停音乐 { while (open_flag == 0) { press_key = ScanKey(); //获取按下的键 delay_key(); //将按下的键值传入处理函数 改变状态变量 } } C = 460830 / music3[u]; TH1 = (8192 - C) / 32; //可证明这是13位计数器TH0高8位的赋初值方法 5 TL1 = (8192 - C) % 32; //可证明这是13位计数器TL0低5位的赋初值方法 TR1 = 1; //启动定时器T0 for (t = 0; t < music3_JP[u] ; t++) //控制节拍数 delay1(); //延时1个节拍单位 TR1 = 0; //关闭定时器T1 u++; //播放下一个音符 } init_timer(); TR1 = 0; //关闭定时器 sound = 1; //关闭蜂鸣器 } } } void Time1(void) interrupt 3 //T1定时器的中断等级要注意 是3 { sound=!sound; //将P3.7引脚输出电平取反,形成方波 TH1=(8192-C)/32;//可证明这是13位计数器TH0高8位的赋初值方法 TL1=(8192-C)%32;//可证明这是13位计数器TL0低5位的赋初值方法 }
c
#include <reg52.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* LCD_init(); LCD_write_str(1,1,"2223123"); */ sbit lcd_rs=P2^4; sbit lcd_rw=P2^5; sbit lcd_en=P2^6; #define DataPort P0 #define RS_CLR lcd_rs=0 #define RS_SET lcd_rs=1 #define RW_CLR lcd_rw=0 #define EN_CLR lcd_en=0 #define EN_SET lcd_en=1 void delay_lcd_ms(unsigned int a) { unsigned int i, j; for (i = a; i > 0; i--) for (j = 100; j > 0; j--) ; } //*********************************************************************** // 显示屏命令写入函数 //*********************************************************************** void LCD_write_com(unsigned char com) { RS_CLR; RW_CLR; EN_SET; DataPort = com; //命令写入端口 delay_lcd_ms(5); EN_CLR; } //*********************************************************************** // 显示屏数据写入函数 //*********************************************************************** void LCD_write_data(unsigned char dataa) { RS_SET; RW_CLR; EN_SET; DataPort = dataa; //数据写入端口 delay_lcd_ms(5); EN_CLR; } //*********************************************************************** // 显示屏单字符写入函数 //*********************************************************************** void LCD_write_char(unsigned char x,unsigned char y,unsigned char dataa) { if (y == 0) { LCD_write_com(0x80 + x); //第一行显示 } else { LCD_write_com(0xC0 + x); //第二行显示 } LCD_write_data( dataa); } //*********************************************************************** // 显示屏字符串写入函数 //*********************************************************************** void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s) { if (y == 0) { LCD_write_com(0x80 + x); //第一行显示 } else { LCD_write_com(0xC0 + x); //第二行显示 } while (*s) { LCD_write_data( *s); s ++; } } //*********************************************************************** // 显示屏初始化函数 //*********************************************************************** void LCD_init(void) { LCD_write_com(0x38); //显示模式设置 delay_lcd_ms(5); LCD_write_com(0x38); //显示模式设置 delay_lcd_ms(5); LCD_write_com(0x38); //显示模式设置 delay_lcd_ms(5); LCD_write_com(0x38); //显示模式设置 delay_lcd_ms(5); LCD_write_com(0x08); //显示关闭 delay_lcd_ms(5); LCD_write_com(0x01); //显示清屏 delay_lcd_ms(5); LCD_write_com(0x06); //显示光标移动设置 delay_lcd_ms(5); LCD_write_com(0x0C); //显示开及光标设置 delay_lcd_ms(5); }
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!