你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32L0方案秀】基于NUCLEO_L073的菜单式MP3点播器 精华

[复制链接]
jinglixixi 发布时间:2016-7-6 15:12
在各种基于ARM的作品中,图像显示功能的实现已经十分普遍,但实现音频播放功能的却不多。这里就以NUCLEO_L073为控制核心,介绍一种带中文菜单的MP3点播器,其组成结构如图1所示。
在整体结构中,NUCLEO_L073主要承担的任务有:按键判别处理、菜单显示、控制信号输出、串行指令发送等。
Mini MP3播放模块承担的任务有:接收控制信号、读取SDHC文件、音频变换处理及驱动处理等。该模块共有16个引脚,其外观如图3所示。
(注:在VCC和GND接L073开发板的+5V和GND引脚,ADKEY_1接L073的PC13即B1键的情况下,可简单测试歌曲的播放。在RX和TX分别与L073开发板的TX和RX 的情况下,也测试指令方式播放歌曲 。)
MP3播放模块在使用过程中有2种模式,即简单的独立操控模式和基于通讯的指令操控模式。
对于独立操控模式,只需配置几个小按键就可对它进行控制,所这些的操作有播放第一首、下一首、上一首、增加音量、减小音量等。在配置相应电阻的情况下,还可通过电位的变化来实现指定顺序播放。
对于指令操控模式,其操控方式要相对灵活,但需要有串行通讯来配合工作,其通讯的波特率为9600bps。
该模块各引脚的功能如下:
菜单显示是采用0.96’双色OLED显示屏,是一种无需背光自发光器件。该模块尽管体积小很小,但分辨率却达128*64对于采用IIC接口方式OLED,其引脚只有4个,所以很节省GPIO资源。对于双色的OLED显示屏,其上部的1/3为黄色,余下的2/3则为蓝色,其显示效果如图5所示。
为了实现中文菜单的显示,是采用构建小字库的方式完成的,所用的工具为PCtoLCD2002,其界面如图6所示。
在控制信号的发送过程中,即支持GPIO输出开关信号,也支持串口输出的指令信号。为了便于统一管理,在MP3播放模块上并没有直接连接按键,而是通过NUCLEO_L073按使用者的操作来发送信号。
除了硬件方面的设计,要实现相应的功能目标,软件的设计也是不可或缺的。
在显示方面,涉及的功能函数有:OLED 初始化函数、清屏函数、汉字显示函数、字符串显示函数及菜单显示函数等。
对于IIC接口的OLED其初始化函数如下:
  1. //  GND   GND
  2. //  VCC   5V/3.3v
  3. //  SCL   PA5
  4. //  SDA   PA7
  5. #define OLED_MODE 0
  6. #define SIZE 8
  7. #define XLevelL                0x00
  8. #define XLevelH                0x10
  9. #define Max_Column        128
  10. #define Max_Row                64
  11. #define        Brightness        0xFF
  12. #define X_WIDTH         128
  13. #define Y_WIDTH         64
  14. #define OLED_SCLK_Clr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET)  
  15. #define OLED_SCLK_Set() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET)   
  16. void OLED_Init(void)
  17. {         
  18. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);         
  19.         GPIO_InitTypeDef  GPIO_InitStruct;
  20.         __HAL_RCC_GPIOA_CLK_ENABLE();
  21.         GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;         
  22.         GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  23.    GPIO_InitStruct.Pull  = GPIO_PULLUP;
  24.         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  25.         HAL_GPIO_Init(GPIOA,   &GPIO_InitStruct);
  26.    OLED_SCLK_Set();
  27.    OLED_SDIN_Set();        
  28.    Delay_1ms(800);             //delay_ms(800);
  29.    OLED_WR_Byte(0xAE,OLED_CMD);//--display off
  30.         OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  31.         OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  32.         OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  
  33.         OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
  34.         OLED_WR_Byte(0x81,OLED_CMD); // contract control
  35.         OLED_WR_Byte(0xFF,OLED_CMD);//--128   
  36.         OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
  37.         OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
  38.         OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  39.         OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
  40.         OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
  41.         OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
  42.         OLED_WR_Byte(0x00,OLED_CMD);//
  43.         OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
  44.         OLED_WR_Byte(0x80,OLED_CMD);//
  45.         OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
  46.         OLED_WR_Byte(0x05,OLED_CMD);//
  47.         OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
  48.         OLED_WR_Byte(0xF1,OLED_CMD);//
  49.         OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
  50.         OLED_WR_Byte(0x12,OLED_CMD);//
  51.         OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
  52.         OLED_WR_Byte(0x30,OLED_CMD);//
  53.         OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
  54.         OLED_WR_Byte(0x14,OLED_CMD);//
  55.         OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
  56. }
复制代码
清屏函数如下:

复制代码
  1. void OLED_Clear(void)  
  2. {  
  3.         unsigned char i,n;                    
  4.         for(i=0;i<8;i++)  
  5.         {  
  6.                 OLED_WR_Byte (0xb0+i,OLED_CMD);   
  7.                 OLED_WR_Byte (0x00,OLED_CMD);      
  8.                 OLED_WR_Byte (0x10,OLED_CMD);        
  9.                 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
  10.         }
  11. }
复制代码
在字符显示方面,是使用程序数组中所存储的字模,并分为不同显示大小的规格,字符串显示函数如下:
  1. void OLED_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char Char_Size)
  2. {
  3.         unsigned char j=0;
  4.         while (chr[j]!='\0')
  5.         {                OLED_ShowChar(x,y,chr[j],Char_Size);
  6.                         x+=8;
  7.                     if(x>120){x=0;y+=2;}
  8.                         j++;
  9.         }
  10. }
复制代码
在汉字显示方面,是采用自行构建的小字库,因此在使用是按排列顺序来建立映射关系,具体的汉字显示函数如下:
  1. void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no)
  2. {                                 
  3.         unsigned char t,adder=0;
  4.         OLED_Set_Pos(x,y);        
  5.     for(t=0;t<16;t++)
  6.                 {
  7.                                 OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
  8.                                 adder+=1;
  9.       }        
  10.                 OLED_Set_Pos(x,y+1);        
  11.       for(t=0;t<16;t++)
  12.                         {        
  13.                                 OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
  14.                                 adder+=1;
  15.       }                                       
  16. }
复制代码
为了便于快捷地构建乐曲菜单,是将各首歌名分别建立一个函数来实现,以“莫斯科郊外的晚上”为例,其显示函数为:
  1. void cd2()
  2. {  // 莫斯科郊外的晚上
  3.         OLED_Clearp();     //   局部清除
  4.         OLED_ShowCHinese(18,2,3);  
  5.         OLED_ShowCHinese(36,2,4);   
  6.         OLED_ShowCHinese(54,2,5);   
  7.         OLED_ShowCHinese(72,2,6);   
  8.         OLED_ShowCHinese(90,2,7);   
  9.         OLED_ShowCHinese(108,2,8);   
  10.         OLED_ShowCHinese(18,4,9);   
  11.         OLED_ShowCHinese(36,4,10);  
  12. }
复制代码
MP3点播器的处理流程为:
选择歌曲播放的方向(前2项)->选择歌曲->选择播放中的控制功能(后4项)->轮回处理
由于在NUCLEO_L073开发板上只配置了一个供控制所用的按键,为了省去另加按键的麻烦,这里是以单按键的方式来执行选择处理,即短按为选择,长按为确认。
在点播过程中,主要分为两类操作,即歌曲的选择(可选上一首或下一首)和播放控制(暂停、退出、加大音量、减小音量)。
受OLED屏显示信息量的限制,在歌曲选择时,是随着选择来更换歌曲名称;而在播放控制时,是通过控制工具栏的符号闪动来提示当前供选择的功能项,其处理效果如图7所示。
菜单选择的程序代码如下:
  1. f=1;              //  进入菜单选择
  2. while(f)
  3. {
  4.         if(i==0) cd1();   // 雪绒花
  5.         if(i==1) cd2();   // 莫斯科郊外的晚上        
  6.         if(i==2) cd3();   // 等待
  7.         if(i==3) cd4();         // 鸿雁
  8.         if(i==4) cd5();   // 贝加尔湖畔
  9.         if(i==5) cd6();         // 春暖花开
  10.         if(i==6) cd7();   // 传奇
  11.         if(i==7) cd8();   // 她
  12.         if(i==8) cd9();   // 味道
  13.         if(i==9) cd10();         // 放心去飞
  14.    cdm();            // 功能键提示栏显示
  15.         while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)!=0);
  16.         HAL_Delay(6000);  //  长短按区分延时
  17.    if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)==0) f=0;
  18.    else
  19.    {
  20.    i++;
  21.         if(i>9)         i=0;        //  轮回处理
  22.    }
  23.   }
复制代码
播放控制的处理代码如下:
  1. cdm();   //  显示功能选择栏  
  2.    f=1;
  3.         while(f)
  4.         {
  5.         while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)!=0)
  6.         {  
  7.    //  产生当前功能选择项闪动效果
  8.         OLED_ShowCHinese(i*18,6,46);
  9.         HAL_Delay(200);        
  10.    cdm();
  11.         HAL_Delay(200);
  12.         }
  13.         HAL_Delay(700);
  14.    //  长短按区分处理
  15.         if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)==0)        f=0;
  16.         i++;
  17.         if(i>5)         i=0;   //  功能选择轮回处理
  18.         HAL_Delay(500);
  19.         }
复制代码
在指令控制的实现上,主要涉及串行通讯的初始化、指令生成与输出等函数。测试过程中,可通过串口助手来验证相应的指令功能。
常用的指令有:
播放_7E FF 06 0D 00 00 00 FE EE EF
暂停_7E FF 06 0E 00 00 00 FE ED EF
下一首_7E FF 06 01 00 00 00 FE FA EF
上一首_7E FF 06 02 00 00 00 FE F9 EF
播放的代码如下:
  1. void play()
  2. {
  3. //  定义指令内容
  4. unsigned cha play_cmd [10] =
  5. { 0X7E, 0xFF, 0x06, 0X0D, 00, 00, 00, 0xFE, 0xee, 0XEF};
  6.   sendCmd (play_cmd);
  7. }
复制代码
未来的改进方向,是采用TFT触摸屏来取代OLED屏显示,从而使菜单所列出的选项更丰富,操作也更便捷。此外,采用硬字库替代小字库也使菜单的更新更灵活。当然你要有承担造价会较大提升的心理准备哟!

图片1.png
图片2.png
图片3.png
图片4.png

模块引脚功能

模块引脚功能
图片6.png
图片7.png
a.jpg
图片8.png

评分

参与人数 1 ST金币 +20 收起 理由
zero99 + 20

查看全部评分

收藏 2 评论21 发布时间:2016-7-6 15:12

举报

21个回答
stary666 回答时间:2016-7-6 17:15:55
tvsat 回答时间:2016-7-6 18:34:09
不错,顶
哈佛祖安智 回答时间:2016-7-6 21:01:41
asssdz-382474 回答时间:2016-7-6 23:32:04
由零开始开发STM8.
jinglixixi 回答时间:2016-7-7 11:41:39

多谢了!
zero99 回答时间:2016-7-8 09:20:45
支持支持
jinglixixi 回答时间:2016-7-8 09:22:00

谢了!
长风破 回答时间:2016-7-9 09:07:23
不错,但是取模就有点费劲了
jinglixixi 回答时间:2016-7-9 10:44:37
长风破 发表于 2016-7-9 09:07
不错,但是取模就有点费劲了

板子上少了flash作为字库,否则用串口传一下就可以。
123下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版