打印
[开源硬件]

【21ic分享赛】 基于51单片机的MP3点播器 续1

[复制链接]
1244|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
三、功能实现
除了硬件方面的设计,要实现相应的功能目标,软件的设计也是不可或缺的。为了更好地进行设计,先来了解一下整体的处理流程。
MP3点播器的处理流程为:
选择歌曲播放的方向(前2项)->选择歌曲->选择播放中的控制功能(后4项)->轮回处理
了解处理后,我们再看一看需要解决的任务,它主要包含3部分:
1)显示功能的设计
2)按键功能的设计
3)通讯功能的设计
在开发过程中,由于所用的单片机只是一个最小系统,使用是借用另一块带有RS232串口通讯功能的单片机来进行开发与测试的,其使用方式如图11所示。
11  外挂RS232串口通讯下载程序

1. 显示功能的设计
受OLED屏显示信息量的限制,在歌曲选择时,是随着选择来更换歌曲名称;而在播放控制时,是通过控制工具栏的符号闪动来提示当前供选择的功能项,其处理效果如图12所示。
图12功能项闪动提示效果

在显示方面,涉及的功能函数有:OLED 初始化函数、清屏函数、字符显示函数、数值显示函数汉字显示函数、及菜单显示函数等。
OLED 初始化函数如下:
void OLED_Init(void)
{        
    OLED_WR_Byte(0xAE,OLED_CMD);
        OLED_WR_Byte(0x00,OLED_CMD);
        OLED_WR_Byte(0x10,OLED_CMD);
        OLED_WR_Byte(0x40,OLED_CMD);  
        OLED_WR_Byte(0xB0,OLED_CMD);
        OLED_WR_Byte(0x81,OLED_CMD);
        OLED_WR_Byte(0xFF,OLED_CMD);  
        OLED_WR_Byte(0xA1,OLED_CMD);
        OLED_WR_Byte(0xA6,OLED_CMD);
        OLED_WR_Byte(0xA8,OLED_CMD);
        OLED_WR_Byte(0x3F,OLED_CMD);
        OLED_WR_Byte(0xC8,OLED_CMD);
        OLED_WR_Byte(0xD3,OLED_CMD);
        OLED_WR_Byte(0x00,OLED_CMD);
        OLED_WR_Byte(0xD5,OLED_CMD);
        OLED_WR_Byte(0x80,OLED_CMD);
        OLED_WR_Byte(0xD8,OLED_CMD);
        OLED_WR_Byte(0x05,OLED_CMD);
        OLED_WR_Byte(0xD9,OLED_CMD);
        OLED_WR_Byte(0xF1,OLED_CMD);
        OLED_WR_Byte(0xDA,OLED_CMD);
        OLED_WR_Byte(0x12,OLED_CMD);
        OLED_WR_Byte(0xDB,OLED_CMD);
        OLED_WR_Byte(0x30,OLED_CMD);
        OLED_WR_Byte(0x8D,OLED_CMD);
        OLED_WR_Byte(0x14,OLED_CMD);
        OLED_WR_Byte(0xAF,OLED_CMD);
}
清屏函数如下:
void OLED_Clear(void)  
{  
        u8 i,n;                    
        for(i=0;i<8;i++)  
        {  
                OLED_WR_Byte (0xb0+i,OLED_CMD);   
                OLED_WR_Byte (0x00,OLED_CMD);     
                OLED_WR_Byte (0x10,OLED_CMD);      
                for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
        }
}
在字符显示过程中,要有字符库的支持,以6*8点字模为例其结构如下:
const unsigned char code F6x8[][6] =               
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
。。。
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
。。。
}
字符显示函数如下:
void OLED_Clear(void)  
{  
        u8 i,n;                    
        for(i=0;i<8;i++)  
        {  
                OLED_WR_Byte (0xb0+i,OLED_CMD);   
                OLED_WR_Byte (0x00,OLED_CMD);     
                OLED_WR_Byte (0x10,OLED_CMD);      
                for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
        }
}

在字符显示过程中,要有字符库的支持,以6*8点字模为例其结构如下:
const unsigned char code F6x8[][6] =               
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
。。。
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
。。。
}
字符显示函数如下:
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{             
            unsigned char c=0,i=0;       
                c=chr-' ';               
                if(x>Max_Column-1){x=0;y=y+2;}
                if(Char_Size ==16)
                        {
                        OLED_Set_Pos(x,y);       
                        for(i=0;i<8;i++)
                        OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
                        OLED_Set_Pos(x,y+1);
                        for(i=0;i<8;i++)
                        OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
                        }
                        else
            {       
                                OLED_Set_Pos(x,y);
                                for(i=0;i<6;i++)
                                OLED_WR_Byte(F6x8[c][i],OLED_DATA);
                     }
}
数值显示函数如下:
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{                
        u8 t,temp;
        u8 enshow=0;                                                  
        for(t=0;t<len;t++)
        {
                temp=(num/oled_pow(10,len-t-1))%10;
                if(enshow==0&&t<(len-1))
                {
                        if(temp==0)
                        {
                                OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
                                continue;
                        }else enshow=1;
                }
                 OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
        }
}
与字符相同,汉字的显示也需要字库的支持,受存储空间的限制这里是自行构建了一个仅供菜单显示用的小字库,其结构如下:
unsigned char code Hzk[][32]={
//点(0) 播(1) 器(2) (3) (4)
{0x00,0x00,0xC0,0x40,0x40,0x40,0x7F,0x48,0x48,0x48,0x48,0xC8,0x08,0x08,0x00,0x00},
{0x80,0x40,0x37,0x04,0x04,0x14,0x64,0x04,0x14,0x64,0x04,0x07,0x10,0xE0,0x00,0x00},/*"",0*/
{0x10,0x10,0xFF,0x10,0x90,0x82,0x56,0x3A,0x12,0x7F,0x11,0x39,0x55,0x90,0x80,0x00},
{0x42,0x82,0x7F,0x01,0x00,0x00,0xFF,0x49,0x49,0x7F,0x49,0x49,0xFF,0x00,0x00,0x00},/*"",1*/
{0x80,0x80,0x9E,0x92,0x92,0x92,0x9E,0xE0,0x80,0x9E,0xB2,0xD2,0x92,0x9E,0x80,0x00},
{0x08,0x08,0xF4,0x94,0x92,0x92,0xF1,0x00,0x01,0xF2,0x92,0x94,0x94,0xF8,0x08,0x00},/*"",2*/
。。。
}
汉字显示函数如下:
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{                                  
        u8 t,adder=0;
        OLED_Set_Pos(x,y);       
    for(t=0;t<16;t++)
                {
                                OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
                                adder+=1;
       }       
                OLED_Set_Pos(x,y+1);       
        for(t=0;t<16;t++)
                {       
                                OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
                                adder+=1;
        }                                       
}
受程序存储空间的限制,在设计过程中是采用测试的方法来逐渐添加菜单内容的,在建到十首歌时已达到7K左右(STC89C528K芯片),就没再继续添加,估计还可以添加几首吧。
由于是采用小字库设计菜单,在使用时是按排列顺序来建立映射关系的,设计时出于方便是为每个菜单项设计了一个小函数以供调用,以“放心去飞”为例,其显示函数为:
void cd10()
{   // 放心去飞
        OLED_Clearp();   // 局部清除函数
        OLED_ShowCHinese(18,2,41);  // 放
        OLED_ShowCHinese(36,2,42);  // 心
        OLED_ShowCHinese(54,2,43);  // 去
        OLED_ShowCHinese(72,2,44);  // 飞
}
若想参考更全的OLED资料,可参考“中景园电子0.96OLED显示屏_C51系列_IIC_例程推荐”。


相关帖子

沙发
21ic小喇叭| | 2016-7-20 10:41 | 只看该作者
分享的都是大牛啊

使用特权

评论回复
板凳
jinglixixi|  楼主 | 2016-7-20 10:46 | 只看该作者

过奖了!多谢了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

446

主题

2675

帖子

37

粉丝