搜索
bottom↓
回复: 1008

小玩意,单片AT89C2051 + SD卡 + 3310LCD = 音乐播放器

  [复制链接]

出0入0汤圆

发表于 2011-1-9 09:32:22 | 显示全部楼层 |阅读模式
这个小玩意,采用 ATMEL 的传统51MCU作主控制芯片,加上SD卡和显示屏,就可以作简单的音乐播放器了,虽然音质不怎么样,不过作为DIY还是蛮有乐趣,希望大家喜欢。
没有采用FAT文件系统,只是按扇区读取SD卡,由于2051资源有限,改为4051有望可以操作FAT,但目前程序还在不断完善中。
128byte怎样读取512byte的扇区数据?可以采用边读边播放的方式,就能解决。音乐文件是32KHz取样率的WAV文件,所以和HIFI就沾不上边了。
程序是用C来编写,以方便交流,资料整理中,完善后再上传。


(原文件名:0001.jpg)


(原文件名:0002.jpg)


(原文件名:0003.jpg)


(原文件名:0004.jpg)


(原文件名:SD_player.PNG)

下面是测试用的HEX文件,由于部分显示数据在SD卡中,所以SD卡需要存入一个特别的文件,然后把格式为32KHZ,8bit,单声的WAV文件存入即可。
点击此处下载 ourdev_609987T97WV4.rar(文件大小:2K) (原文件名:sdcard.rar)

还是有就视频文件,顺便听听音质。
点击此处下载 ourdev_609986DT65P1.avi视频文件大小:5.82M) (原文件名:SD_player.wmv.avi)

程序已更新于80楼

出0入0汤圆

发表于 2011-1-9 09:38:15 | 显示全部楼层
牛人。

出0入0汤圆

发表于 2011-1-9 09:39:03 | 显示全部楼层
厉害 顶一下

出0入0汤圆

发表于 2011-1-9 09:39:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-9 09:49:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-9 10:00:35 | 显示全部楼层
ding!

出0入12汤圆

发表于 2011-1-9 10:03:13 | 显示全部楼层
我还以为是MP3......原来是WAV

出0入0汤圆

发表于 2011-1-9 10:07:21 | 显示全部楼层
马克

出0入4汤圆

发表于 2011-1-9 10:12:38 | 显示全部楼层
make

出0入0汤圆

发表于 2011-1-9 10:15:51 | 显示全部楼层
终于逮着楼主了,我想问下,你那个2个IO驱动1602的例子,我改动到了ATtiny13上,GCC编译,但是用Protues无论如何也没有显示,用示波器观察电容充放电发现τ值过小,特求助于你,望能解答,谢谢

出0入0汤圆

发表于 2011-1-9 10:19:08 | 显示全部楼层
新年强帖,膜拜

出0入0汤圆

发表于 2011-1-9 10:30:39 | 显示全部楼层
真是狠,卵上都能雕出花来,不错.做个记号

出0入0汤圆

发表于 2011-1-9 11:08:57 | 显示全部楼层
不愧是牛仔 总有新的东东

出0入0汤圆

发表于 2011-1-9 11:29:45 | 显示全部楼层
回复【9楼】renpeng009 大鹏集成
终于逮着楼主了,我想问下,你那个2个io驱动1602的例子,我改动到了attiny13上,gcc编译,但是用protues无论如何也没有显示,用示波器观察电容充放电发现τ值过小,特求助于你,望能解答,谢谢
-----------------------------------------------------------------------

那个两个口驱动LCD1602的电路
我在PIC16F917上用三口做个
(只是在PROTEUS上做的)
没有问题
估计是你的延时有问题
个人感觉延时要把握好
刚开始我也是现实不出来
不过我从新计算延时后
就显示出来了

(原文件名:PIC16F917-I/O驱动LCD1602.png)

出0入0汤圆

发表于 2011-1-9 11:32:33 | 显示全部楼层
楼主又用2051做出了意想不到的作品,牛!很期待开源

出0入0汤圆

发表于 2011-1-9 11:33:17 | 显示全部楼层
佩服!

出0入0汤圆

发表于 2011-1-9 11:35:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-9 11:53:20 | 显示全部楼层
mk

出0入90汤圆

发表于 2011-1-9 12:29:12 | 显示全部楼层
牛人再现!!!!!!!!!!!!!!!!!!!

出0入0汤圆

发表于 2011-1-9 12:31:36 | 显示全部楼层
哇...牛
我想问下,用个快一点的mcu能不能解码mp3呢?比如stc的1t系列加上32M的晶振?

出0入0汤圆

发表于 2011-1-9 12:33:38 | 显示全部楼层
Cowboy出品,必属精品。mark一下

出0入0汤圆

发表于 2011-1-9 12:34:56 | 显示全部楼层
ding

出0入0汤圆

发表于 2011-1-9 12:41:43 | 显示全部楼层
抬头看精品

出0入0汤圆

发表于 2011-1-9 12:47:26 | 显示全部楼层
这是今天我见过的最好贴,思路新奇!
这么一个没什么资源的IC能作出MY3,并没用DAC,真的了不起!

出50入4汤圆

发表于 2011-1-9 12:47:52 | 显示全部楼层
开源,期待

出0入0汤圆

发表于 2011-1-9 12:52:54 | 显示全部楼层
牛人,佩服啊

出0入0汤圆

发表于 2011-1-9 13:06:51 | 显示全部楼层
我用C8051F330也做过一个,带FAT32文件系统,裁剪的文件系统,SD卡中放入WAV文件就可以按83的文件名播放。512的XDATA我就用来读SD卡,也只能读一个播放一个,要是有1024就好了,一个读SD卡,一个作播放缓冲,两个缓冲轮着换。
20K采样以上的WAV不用低通滤波也能用PWM播放出音质不错的歌曲,我试过44.1KHz,8bit采样,音质很好,但20K以下的就有很大的电流音,应该是PWM的高低电平变化引起的,20K以上人耳听不到

出5入190汤圆

发表于 2011-1-9 13:12:41 | 显示全部楼层
挺不错的

出0入0汤圆

发表于 2011-1-9 14:21:01 | 显示全部楼层
回复【楼主位】cowboy
-----------------------------------------------------------------------

我也有一块3310,做的真不错,期待上传源程序!

出0入0汤圆

发表于 2011-1-9 14:22:17 | 显示全部楼层
等待zl的程序ing..

出0入0汤圆

发表于 2011-1-9 14:31:30 | 显示全部楼层
cowboy历来就是小成本大制作的成功大导演!!!!!!!!!

出0入0汤圆

发表于 2011-1-9 15:22:15 | 显示全部楼层
连洞洞板都省了  果然是牛!

出0入0汤圆

发表于 2011-1-9 15:29:39 | 显示全部楼层
回复【31楼】freedestiny 小梁
连洞洞板都省了  果然是牛!
-----------------------------------------------------------------------

出0入0汤圆

发表于 2011-1-9 15:39:17 | 显示全部楼层
太厉害了...

出0入0汤圆

发表于 2011-1-9 15:48:55 | 显示全部楼层
厉害啊

出0入0汤圆

发表于 2011-1-9 16:11:29 | 显示全部楼层
mark 高手

出0入0汤圆

发表于 2011-1-9 17:43:44 | 显示全部楼层

出0入0汤圆

发表于 2011-1-9 17:58:17 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-9 18:20:53 | 显示全部楼层
牛人

出0入0汤圆

发表于 2011-1-9 18:36:54 | 显示全部楼层
太牛了。顶一个

出0入0汤圆

发表于 2011-1-9 18:41:17 | 显示全部楼层
牛…

出0入0汤圆

发表于 2011-1-9 19:00:53 | 显示全部楼层
这电池像是DV上用的

出0入0汤圆

发表于 2011-1-9 19:18:58 | 显示全部楼层
真简洁,强!

出0入0汤圆

发表于 2011-1-9 19:25:20 | 显示全部楼层
牛人

出0入0汤圆

发表于 2011-1-9 19:28:04 | 显示全部楼层
楼主能说一下怎么边读边播嘛?期待楼主开源。

出0入0汤圆

发表于 2011-1-9 20:23:01 | 显示全部楼层
超级牛人, 顶一个

出5入8汤圆

发表于 2011-1-9 20:34:43 | 显示全部楼层
牛人,膜拜中

出0入0汤圆

发表于 2011-1-9 20:35:59 | 显示全部楼层
厉害,学习。。。

出0入0汤圆

发表于 2011-1-9 20:36:50 | 显示全部楼层
总是搞那么嗨的东西 - -

顶!

出0入0汤圆

发表于 2011-1-9 20:42:39 | 显示全部楼层
精品

出0入0汤圆

发表于 2011-1-9 21:04:37 | 显示全部楼层
牛气!Mark!

出0入0汤圆

发表于 2011-1-9 21:05:37 | 显示全部楼层
牛,怎么做到的?

出0入0汤圆

发表于 2011-1-9 21:06:52 | 显示全部楼层
强烈要求楼主开源啊!!顶

出0入0汤圆

发表于 2011-1-9 21:07:44 | 显示全部楼层
刷新了上百遍还是不见ZL开源...

出0入0汤圆

发表于 2011-1-9 21:15:10 | 显示全部楼层
记号~~

出0入0汤圆

发表于 2011-1-9 21:16:35 | 显示全部楼层
在单片机脚上焊这么多贴片电阻 也是水平啊 而且焊点还不错啊

出0入134汤圆

发表于 2011-1-9 21:22:06 | 显示全部楼层
回复【19楼】shenrongze  寻寻觅觅
哇...牛
我想问下,用个快一点的mcu能不能解码mp3呢?比如的1t系列加上32m的晶振?
-----------------------------------------------------------------------

某人说 STM32硬解MP3都还要看它的程序效率。。。。

出0入0汤圆

发表于 2011-1-9 21:26:32 | 显示全部楼层
这个也快置顶了,哈哈,那个vga还没弄懂呢

出0入0汤圆

发表于 2011-1-9 21:31:30 | 显示全部楼层
牛仔 语出必惊人啊。

出0入0汤圆

发表于 2011-1-9 21:38:02 | 显示全部楼层
顶啊,厉害,真想知道是怎么实现的。

出0入0汤圆

发表于 2011-1-9 21:54:15 | 显示全部楼层
Cowboy出品,厉害

出0入0汤圆

发表于 2011-1-9 22:37:24 | 显示全部楼层
回复【57楼】elecfun 熊
回复【19楼】shenrongze  寻寻觅觅
哇...牛
我想问下,用个快一点的mcu能不能解码mp3呢?比如的1t系列加上32m的晶振?
-----------------------------------------------------------------------
某人说 stm32硬解mp3都还要看它的程序效率。。。。
-----------------------------------------------------------------------

软解吧?硬解不是直接操控vs1053之类的解码芯片就好了吗?

出0入0汤圆

发表于 2011-1-9 22:43:52 | 显示全部楼层
强啊,期待!

出0入0汤圆

发表于 2011-1-9 23:00:23 | 显示全部楼层
回复【62楼】shenrongze 寻寻觅觅
回复【57楼】elecfun 熊
回复【19楼】shenrongze  寻寻觅觅  
哇...牛  
我想问下,用个快一点的mcu能不能解码mp3呢?比如的1t系列加上32m的晶振?  
-----------------------------------------------------------------------  
某人说 stm32硬解mp3都还要看它的程序效率。。。。
-----------------------------------------------------------------------
软解吧?硬解不是直接操控vs1053之类的解码芯片就好了吗?
-----------------------------------------------------------------------

敢问各位大侠,何谓“硬解”何谓“软解”?请赐教

出0入0汤圆

发表于 2011-1-9 23:02:49 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-1-9 23:18:54 | 显示全部楼层
靠,牛人一个,特别是看了楼主那几个手指头输入1602的控制指令显示内容的视频,一绝吧!!

出0入0汤圆

发表于 2011-1-9 23:35:41 | 显示全部楼层
牛人再次出現

出0入0汤圆

发表于 2011-1-10 00:12:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-10 00:23:02 | 显示全部楼层
回复【64楼】believe0815
敢问各位大侠,何谓“硬解”何谓“软解”?请赐教
-----------------------------------------------------------------------

硬解,用专用的硬件解码,再通过mcu控制它
软件,直接用mcu写程序解

出50入0汤圆

发表于 2011-1-10 00:36:28 | 显示全部楼层
做个记号,上班后研究一下

出0入0汤圆

发表于 2011-1-10 01:27:19 | 显示全部楼层
lz非常牛,一定境界了,能去钻研小东西,把小东西做到绝了,顶~~~~

出0入0汤圆

发表于 2011-1-10 07:16:23 | 显示全部楼层
乖乖

出0入0汤圆

发表于 2011-1-10 08:01:16 | 显示全部楼层

出0入0汤圆

发表于 2011-1-10 08:10:12 | 显示全部楼层
精品

出0入0汤圆

发表于 2011-1-10 08:27:36 | 显示全部楼层
真不错

佩服

膜拜下

学习去

出0入0汤圆

发表于 2011-1-10 08:57:31 | 显示全部楼层
牛!期待中!

出0入0汤圆

发表于 2011-1-10 09:20:37 | 显示全部楼层
偶滴神啊!

出0入0汤圆

 楼主| 发表于 2011-1-10 09:34:45 | 显示全部楼层
昨天外出,没有回贴,看来大家对这个也蛮有兴趣。

出0入0汤圆

发表于 2011-1-10 09:35:47 | 显示全部楼层
80楼在哪..

出0入0汤圆

 楼主| 发表于 2011-1-10 09:37:19 | 显示全部楼层
这是未经整理的程序,有点乱,凑合着看,有时间再进一步改进。
SD部分是修改于本坛的一个贴子
----------------------------------------------------------
添加部分注释,提高可读性

#include <reg51.h>
#include <INTRINS.H>
#include <MATH.H>
#include "LCD_3310.H"
#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long

/************ 定义管脚 *************/
sbit DOUT = P3^0;  //SD卡数据输出
sbit CLK  = P3^1;  //SD卡时钟输入
sbit DIN  = P3^2;  //SD卡数据输入
sbit CS   = P3^3;  //SD卡片选使能


/************ 全局变量 ************/                                                                                                                       
uchar pbuf[64]; //数据缓冲区
uchar p;        //播放缓冲区指针
uchar px;       //频谱显示的X坐标

code ulong Track[17] =
{   //0x15000,0x58000   SD卡中各声音文件的首址,以后打算把这些数据放在SD卡的特定配置文件中再读入。
    0xd7800-0x8a00,0x76b800-0x8a00,0xedc000-0x8a00,0x1752800-0x8a00,0x1F08000-0x8a00,
    0x2569800-0x8a00,0x2EDB800-0x8a00,0x3480000-0x8a00,0x3BFA800-0x8a00,
    0x41EB000-0x8a00,0x48EF000-0x8a00,0x508A000-0x8a00,0x59AE800-0x8a00,
    0x60AF000-0x8a00,0x6878000-0x8a00,0x6DBE000-0x8a00,0x7525800-0x8a00,
};

/******* SD访问错误码的定义 *******/
#define INIT_CMD0_ERROR   0X01
#define INIT_CMD1_ERROR   0X02
#define READ_BLOCK_ERROR  0X03
#define WRITE_BLOCK_ERROR 0X04

/********* 通用延时函数 ***********/
void delay(uint i)
{
    while(i--);
}

/******** SD写入一个字节 **********/
void spi_write(uchar x)
{   //不采用循环结构是为了提高处理速度
    DIN = x & 0x80;
    CLK = 0;
    CLK = 1;
    DIN = x & 0x40;
    CLK = 0;
    CLK = 1;
    DIN = x & 0x20;
    CLK = 0;
    CLK = 1;
    DIN = x & 0x10;
    CLK = 0;
    CLK = 1;
    DIN = x & 0x08;
    CLK = 0;
    CLK = 1;
    DIN = x & 0x04;
    CLK = 0;
    CLK = 1;
    DIN = x & 0x02;
    CLK = 0;
    CLK = 1;
    DIN = x & 0x01;
    CLK = 0;
    CLK = 1;
}

/******* SD慢速写入一个字节 ********/
void spi_write_low_speed(uchar x)
{
    uchar i;
    for(i = 8; i; --i)
    {
        DIN = x & 0x80;
        x <<= 1;
        CLK = 0;
        delay(1);
        CLK = 1;
        delay(1);
    }
}

/*********** SD读入一字节 ***********/
uchar spi_read(void)
{   //利用51串口的同步移位功能,以达了最高的读度2MHz CLK
    RI = 0;
    while(RI == 0);
    return SBUF;
}

/******** SD慢速读入一字节 **********/
uchar spi_read_low_speed(void)
{
    uchar temp,i;
    for(i = 8; i; --i)
    {
        CLK = 0;
        delay(1);
        temp <<= 1;
        if(DOUT) temp++;
        CLK = 1;
        delay(1);
    }
    return temp;
}

/******** 发送一组SD命令 ************/
uchar write_cmd(uchar data *pcmd)
{
    uchar temp,time=0,i;
    for(i = 0; i<6; i++) //一条命令都是6个字节,形参用指针,
    {                    //指向6个字节命令,
        spi_write(pcmd);
    }
    do                   //看看写进去没有,通过so管脚
    {
        temp = spi_read();
        time++;
    }                    //一直到读到的不是0xff或超时,退出去
    while(temp==0xff && time<100);
    return temp;
}

/****** 慢速发送一组SD命令 **********/
uchar write_cmd_low_speed(uchar *pcmd)
{
    uchar temp,time=0,i;
    for(i=0;i<6;i++)    //一条命令都是6个字节,形参用指针,
    {                   //指向6个字节命令,
        spi_write_low_speed(pcmd);
    }
    do                  //看看写进去没有,通过so管脚
    {
        temp = spi_read_low_speed();
        time++;
    }                   //一直到读到的不是0xff或超时,退出去
    while(temp==0xff && time<100);
    return temp;
}

/********* SD卡 激活,复位 *********/
uchar sd_reset(void)
{
    uchar time,temp,i;
    uchar pcmd[6]={0x40,0x00,0x00,0x00,0x00,0x95};
    CS = 1;
    for(i = 0; i < 0x0f; i++) //复位时,至少要72个时钟周期,
    {                         //现在是,15*8=120个clk
        spi_write_low_speed(0xff);
    }
    CS = 0;
    time=0;
    do
    {
        temp = write_cmd_low_speed(pcmd);
        time++;
        if(time > 100) return INIT_CMD0_ERROR;
    }
    while(temp != 0x01);      //校验码是0x01,表示写入成功
    CS = 1;
    spi_write_low_speed(0xff);//时序上要求补8个clk
    return 0;                 //返回0,写入成功
}

/************ SD卡初始化 ************/
uchar sd_init(void)
{
    uchar time, temp;
    uchar pcmd[6] = {0x41,0x00,0x00,0x00,0x00,0xff};
    CS = 0;
    time = 0;
    do
    {
        temp = write_cmd_low_speed(pcmd);
        time++;
        if(time > 100) return INIT_CMD1_ERROR;
    }            
    while(temp != 0x00);
    CS = 1;
    spi_write_low_speed(0xff);
    return 0;
}


/******* 读取一扇区的点阵图像 *********/
uchar sd_read_bmp(uchar data *ad)
{
    uchar temp, time, x, pcmd[6];
    uint j = 0;
    pcmd[0] = 0x51;
    pcmd[1] = *ad;
    pcmd[2] = *(++ad);
    pcmd[3] = *(++ad);
    pcmd[4] = 0;
    pcmd[5] = 0xff;

    CS = 0;
    time = 0;
    do
    {
        temp = write_cmd(pcmd);
        if(++time > 100)
        {
            CS = 1;
            return READ_BLOCK_ERROR;
        }
    }
    while(temp != 0);
                               //等待SD卡回应
    while(spi_read() != 0x7f); //0xfe,51的串口移位是LSB优先,所以结果高低位倒置
    for (j = 0; j < 504; j++)  //3310的分辨率为 84 * 48,总计用504字节
    {
        LCD3310_write_dat(spi_read());
    }
    for (x = 0; x < 10; x++) spi_read(); //略过8字节数据和2字节CRC
    spi_write(0xff);
    CS = 1;
    return 0;
}


/******* 读取一扇区的声音数据 *********/
uchar sd_read_sector(uchar data *ad)
{
    uchar temp, time, pcmd[6];
    uint j = 0;
    pcmd[0] = 0x51;
    pcmd[1] = *ad;
    pcmd[2] = *(++ad);
    pcmd[3] = *(++ad);
    pcmd[4] = 0;
    pcmd[5] = 0xff;

    CS = 0;
    time = 0;
    do
    {
        temp = write_cmd(pcmd);
        if(++time > 100)
        {
            CS = 1;
            return READ_BLOCK_ERROR;
        }
    }
    while(temp != 0);
    //等待SD回应的时间有点长,所以在这里插入显示模拟的频谱图
    temp = pbuf[16];         //随便挑一个数据显示
    LCD3310_set_XY(px,5);    //设定显示位置
    px += 6;
    if (px >= 39) px = 0;
    if (temp & 0x80) temp ^= 0x80; //求得声音振幅
    else temp = 0x80 - temp;
    temp = Level[temp>>4];         //不同幅度对应不同的谱线图案
    LCD3310_write_dat(temp);
    LCD3310_write_dat(temp);
    LCD3310_write_dat(temp);

    while(spi_read() != 0x7f);//0xfe,51的串口移位是LSB优先,所以结果高低位倒置

    while(1)     //读取512字节数据
    {
        RI = 0;_nop_(); pbuf[j++ & 63] = SBUF; //为求快速,不用函数调用
        RI = 0;_nop_(); pbuf[j++ & 63] = SBUF; //直接启动串口移入
        RI = 0;_nop_(); pbuf[j++ & 63] = SBUF; //连续读四字节
        RI = 0;_nop_(); pbuf[j++ & 63] = SBUF;
        if(j >= 512) break;
        while((((uchar)j - p) & 63) > 55);     //检测播放进度,
    }                                          //如果缓冲区接近溢出,先暂停等待
    spi_read();//略过 crc
    spi_read();//略过 crc
    spi_write(0xff);//SD 时序要求补8个脉冲
    CS = 1;
    return 0;
}


/**************************** 主程序 *******************************/
int main(void)
{
    uchar key,n,Count,Min,Sec;
    ulong addr;  // SD 的扇区地址

    P1   = 0x80; // DAC 输出中点电压
    RI   = 1;
    REN  = 1;
    TMOD = 0x02;
    TH0  = 256 - 62.5;  //定时器设定约为 32KHz,和WAV文件取样率对应
    ET0  = 1;
    EA   = 1;
    px   = 0;
    n    = 64;
    do pbuf[--n] = 0x80; while(n); //填充播放缓冲区
    delay(65535);

    LCD3310_init();
    LCD3310_set_XY(0,0);
    LCD3310_write_cmd(0x22);       //设定LCD扫描顺序
    sd_reset();
    sd_init();
    addr = 0x4f400;
    sd_read_bmp((uchar) &addr);    //显示欢迎画面
    while (D_C == 1) ;
    while (D_C == 0) ;             //等待按键
    delay(65535);
   
    //==============  main loop ==================
    while(1)  //循环播放所有曲目
    {
        TR0 = 0;
        LCD3310_write_cmd(0x22);
        LCD3310_set_XY(0,0);
        addr = 0x4f600 + ((uint)n<<9);
        sd_read_bmp((uchar) &addr); //显示歌名、歌手
        LCD3310_write_cmd(0x20);
        TR0  = 1;
        p    = 0xd0;
        Min  = 0;
        Sec  = 0;
        Count= 0;
        for (addr = Track[n]; addr < Track[n+1];)//播放第n曲
        {
            //============ 按键处理 ===============
            key = (key >> 2) | (P3 & 0x30); //仅一句的扫键函数,包括扫描和消抖
            if (key == 0x03)                //键码为03是播放/暂停键
            {
                LCD3310_set_XY(78,5);
                TCON ^= 0x10;               //TR0 取反
                if (TR0) LCD3310_print(11); //显示播放符号
                else     LCD3310_print(12); //显示暂停符号
            }      
            else if (key == 0x2b)           //键码为2b是前一曲
            {
                if ((Min || (Sec & 0xf0))) n--;//10秒后跳本曲开始
                else n -= 2;                   //10秒内跳前一曲
                break;
            }
            else if (key == 0x17)           //键码为17是后一曲
                break;

            //======== 读一扇区数据或暂停 =========
            if (TR0 == 0) {delay(2000); continue;}
            sd_read_sector((uchar) &addr);
            addr += 512;

            //=========== 播放时间计数 ============
            Count += 2;
            if (Count >= 125)
            {
                Count -= 125;
                Sec++;
                if ((Sec & 0x0f) > 9)
                {
                    Sec += 6;
                    if (Sec >= 0x60)
                    {
                        Sec = 0;
                        Min++;
                        if ((Min & 0x0f) > 9)
                        {
                            Min += 6;
                            if (Min > 0x60) Min = 0;
                        }
                    }
                 }
             }

             //======= 分时间片显示时间/标志 ========
             switch (Count & 14)
             {
                 case 2:
                 LCD3310_set_XY(44,5);
                 LCD3310_print(Min>>4);//分钟十位
                 break;

                 case 4:
                 LCD3310_set_XY(50,5);
                 LCD3310_print(Min&15);//分钟个位
                 break;

                 case 6:
                 LCD3310_set_XY(56,5);
                 LCD3310_print(10);    //分隔符
                 break;

                 case 8:
                 LCD3310_set_XY(62,5);
                 LCD3310_print(Sec>>4);//秒十位
                 break;

                 case 10:
                 LCD3310_set_XY(68,5);
                 LCD3310_print(Sec&15);//秒个位
                 break;

                 case 12:
                 LCD3310_set_XY(78,5);
                 if (Count & 0x40) LCD3310_print(13); //闪动播放符号
                 else LCD3310_print(11);
             }
        }
        n++;       //下一曲
        n &= 15;   //这个SD卡只有16首歌
    }//while(1);
}//main()

void timer0 (void) interrupt 1 using 1
{
    if (TL0 & 1) _nop_(); //消除中断响应时间不一致,造成的频率抖动
    P1  = pbuf[++p & 63]; //输出一个声音数据
}

修改原因:加入注释

出0入0汤圆

 楼主| 发表于 2011-1-10 09:39:00 | 显示全部楼层
这是3310 LCD 部分


#include <reg51.h>
#include <INTRINS.H>

sbit SDIN = P3^2; //P3^2
sbit SCLK = P3^4;
sbit D_C  = P3^5;
sbit SCE  = P3^7;

code unsigned char Font[70] =
{
   0x3E, 0x51, 0x49, 0x45, 0x3E ,  // 0
   0x00, 0x42, 0x7F, 0x40, 0x00 ,  // 1
   0x42, 0x61, 0x51, 0x49, 0x46 ,  // 2
   0x21, 0x41, 0x45, 0x4B, 0x31 ,  // 3
   0x18, 0x14, 0x12, 0x7F, 0x10 ,  // 4
   0x27, 0x45, 0x45, 0x45, 0x39 ,  // 5
   0x3C, 0x4A, 0x49, 0x49, 0x30 ,  // 6
   0x01, 0x71, 0x09, 0x05, 0x03 ,  // 7
   0x36, 0x49, 0x49, 0x49, 0x36 ,  // 8
   0x06, 0x49, 0x49, 0x29, 0x1E ,  // 9
   0x00, 0x00, 0x36, 0x36, 0x00 ,  // :
   0x7f, 0x3e, 0x1c, 0x08, 0x00 ,  // >
   0x3e, 0x3e, 0x00, 0x3e, 0x3e ,  // ||
   0x00, 0x00, 0x00, 0x00, 0x00 ,  //" "
};   

code unsigned char Level[8] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,};

extern void delay(unsigned int i);

void LCD3310_write_cmd(unsigned char cmd)
{
    D_C  = 0;
    SCLK = 0;
    SCE  = 0;
    delay(3);
        SDIN = cmd & 0x80;
        SCLK = 1;
        SDIN = cmd & 0x40;
        SCLK = 0;
        SCLK = 1;
        SDIN = cmd & 0x20;
        SCLK = 0;
        SCLK = 1;
        SDIN = cmd & 0x10;
        SCLK = 0;
        SCLK = 1;
        SDIN = cmd & 0x08;
        SCLK = 0;
        SCLK = 1;
        SDIN = cmd & 0x04;
        SCLK = 0;
        SCLK = 1;
        SDIN = cmd & 0x02;
        SCLK = 0;
        SCLK = 1;
        SDIN = cmd & 0x01;
        SCLK = 0;
        SCLK = 1;
    D_C  = 1;
    SDIN = 1;
    SCE  = 1;
}

void LCD3310_write_dat(unsigned char dat)
{
//    D_C  = 1;
    SCLK = 0;
    SCE  = 0;
    delay(3);
        SDIN = dat & 0x80;
        SCLK = 1;
        SDIN = dat & 0x40;
        SCLK = 0;
        SCLK = 1;
        SDIN = dat & 0x20;
        SCLK = 0;
        SCLK = 1;
        SDIN = dat & 0x10;
        SCLK = 0;
        SCLK = 1;
        SDIN = dat & 0x08;
        SCLK = 0;
        SCLK = 1;
        SDIN = dat & 0x04;
        SCLK = 0;
        SCLK = 1;
        SDIN = dat & 0x02;
        SCLK = 0;
        SCLK = 1;
        SDIN = dat & 0x01;
        SCLK = 0;
        SCLK = 1;
    D_C  = 1;
    SDIN = 1;
    SCE  = 1;
}

void LCD3310_init(void)
{
    LCD3310_write_cmd(0x21);
    LCD3310_write_cmd(0xd7);
    LCD3310_write_cmd(0x06);
    LCD3310_write_cmd(0x20);
    LCD3310_write_cmd(0x0c);
}

void LCD3310_set_XY(unsigned char x,unsigned char y)
{
    if (x >= 84) return;
    if (y >= 6)  return;
    LCD3310_write_cmd(0x80 | x);
    LCD3310_write_cmd(0x40 | y);
}

void LCD3310_print(unsigned char n)
{
    n = (n << 2) + n;
    LCD3310_write_dat(Font[n]);
    LCD3310_write_dat(Font[++n]);
    LCD3310_write_dat(Font[++n]);
    LCD3310_write_dat(Font[++n]);
    LCD3310_write_dat(Font[++n]);
}

出0入0汤圆

发表于 2011-1-10 09:44:44 | 显示全部楼层
...

出0入0汤圆

发表于 2011-1-10 09:49:03 | 显示全部楼层
收藏

出0入0汤圆

发表于 2011-1-10 09:59:12 | 显示全部楼层
果然利害,好好

出0入0汤圆

发表于 2011-1-10 10:03:06 | 显示全部楼层
膜拜!顶一下~

出0入0汤圆

发表于 2011-1-10 10:04:02 | 显示全部楼层
再增加一个DA输出,能否做成立体声? 用AT89C52芯片

出0入0汤圆

发表于 2011-1-10 10:10:21 | 显示全部楼层
牛人!膜拜!

出0入0汤圆

发表于 2011-1-10 10:11:19 | 显示全部楼层
厉害。

出0入0汤圆

发表于 2011-1-10 10:24:27 | 显示全部楼层
牛人,厉害。

出0入0汤圆

发表于 2011-1-10 10:40:08 | 显示全部楼层
强贴。膜拜

出0入0汤圆

发表于 2011-1-10 10:45:54 | 显示全部楼层
兄台真乃神人!能否讲解一下是怎么实现的呢

出0入0汤圆

发表于 2011-1-10 10:46:19 | 显示全部楼层
果然好作品!

出0入0汤圆

发表于 2011-1-10 11:01:43 | 显示全部楼层
3310显示那些频谱是假的吧?没节奏啊...

出0入0汤圆

发表于 2011-1-10 11:07:42 | 显示全部楼层
又见楼主,牛人啊。。。

出0入0汤圆

发表于 2011-1-10 11:17:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-10 11:19:31 | 显示全部楼层
lz的内存卡貌似悲剧了,以后杂用啊?

出0入0汤圆

发表于 2011-1-10 11:33:52 | 显示全部楼层
靠,你太厉害了。

要是让我设计一个这个东东,会很复杂的。

出0入0汤圆

发表于 2011-1-10 11:51:47 | 显示全部楼层
很厉害,很崇拜!老大为何不直接把工程整个打包传上来呢????

出0入0汤圆

发表于 2011-1-10 12:01:26 | 显示全部楼层
请问,老大,你这个屏多少钱买的啊???

出0入0汤圆

发表于 2011-1-10 12:20:24 | 显示全部楼层
厉害!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 15:40

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表