找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2220|回复: 0
打印 上一主题 下一主题
收起左侧

BASCOM AVR版简单SD卡播放器仿真

[复制链接]
跳转到指定楼层
楼主

提醒:由于SD卡周边电路欠缺此图只能仿真使用!如据此图做实物将损坏你的SD卡


源程序:

'---------------------------------------------------------------

'简单波形播放器(SD/MMC)<Wave1.0.bas>

'程序员:Behnam Zakizade

'>>>所有MMC接口子程序由:Ranjit Diol编写


'>非常感谢迪奥,他允许使用MMC代码

'编译器:BASCOM 1.11.9.1

'创建日期:2009年12月5

'版权所有:(C)2009wwwavr64com

'许可证:这是一个免费固件,不用于商业用途版本:1.00
'---------------------------------------------------------------
$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 64
$framesize = 64

'LCD
Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0
Config Lcd = 16 * 2
Cursor Off '光标关闭
Cls
'显示图形块
Deflcdchar 0 , 32 , 32 , 31 , 31 , 31 , 31 , 31 , 32        '第一个 #
Deflcdchar 1 , 32 , 32 , 18 , 26 , 30 , 26 , 18 , 32        '播放/暫停 >|
Deflcdchar 2 , 32 , 32 , 2 , 6 , 14 , 6 , 2 , 32            '返回 <<
Deflcdchar 3 , 32 , 32 , 8 , 12 , 14 , 12 , 8 , 32          '前进 >>
'PWM
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Prescale = 1

'常量
Const Msbl = 0

'变量
Dim Indat(512) As Byte                                      '内存缓冲区
Dim Dat As Byte
Dim Resp As Byte                              '捕获
Dim I As Word
Dim Addr As Long
Dim Address As Long                           '寻址的
Dim Fat As String * 5                         '文件分配表
Dim Firstaddr As Long                          '第一地址
Dim Play As Bit

'别名
Cs Alias Portc.5
Clk Alias Portc.3
Miso Alias Pinc.2                                           'Mcu输入 <- MMC
Mosi Alias Portc.4                                          'Mcu输出 -> MMC

'声明
Declare Sub Minit                                    'M初始化
Declare Sub Mread(byval Addr As Long)                 'M读取
Declare Sub Msearch                                  'M搜索
Declare Sub Mfirstfile                              'M第一个文件
Declare Sub Menu                                     '菜单

Config Pinc.5 = Output
Config Pinc.3 = Output
Config Pinc.4 = Output
Config Pinc.2 = Input
Waitms 300
Config Spi = Soft , Din = Pinc.2 , Dout = Portc.4 , Ss = Portc.5 , Clock = Portc.3
Spiinit

' 按键
Config Pind.6 = Input
Config Pind.7 = Input
Config Pinb.2 = Input
Config Pinb.3 = Input

'设置上拉
Portd.6 = 1
Portd.7 = 1
Portb.2 = 1
Portb.3 = 1

'别名
First_key Alias Pind.6
Play_key Alias Pind.7
Prev_key Alias Pinb.2
Next_key Alias Pinb.3

'_______________________________________________________________________________
'主程序从这里开始:
For I = 1 To 100
   Pwm1a = 0
   Waitms 1
   Pwm1a = 64
   Waitms 1
Next I

Cls : Lcd " Search Card..."                       '搜索SD卡。。。
Call Minit                                          '调用M 初始化
Call Msearch                                       '调用M搜索
Call Mfirstfile                                    '调用M第一个文件
Call Menu                                           ' 调用菜单

'Adrrr = 281600                                    '256MB微型的 SD FAT16 起始地址
'Adrrr = 265728                                    '1GB   微型的 SD FAT16 起始地址
'Adrrr = 396288                                    '1GB   数字硬盘 MMC FAT16 起始地址
'Adrrr = 2113024                                   '1GB   数字硬盘 MMC FAT32 起始地址

'FAT Addr
'Adrrr = 19968                                     '256 微型的 SD FAT16/32 地址
'Adrrr = 0                                         '1GB 微型的 SD FAT16/32 地址
'Adrrr = 130560                                    '1GB 数字硬盘 MMC FAT16/32 地址

Xloop:
Set Cs
Shiftout Mosi , Clk , Dat , Msbl      
'Mosi =         要输出数据的端口引脚的名称。 ( A , B , C , D , E , F ) ( 0 ~ 7 )
'Clk =                 时钟的端口引脚的名称。 (A, B, C, D, E, F) (0~7)
'Dat =         包含要输出的数据的变量名称。
'Msbl =         输出位方向和时钟边缘。 (0 到 3)

End
'_______________________________________________________________________________
'DIO提供的初始化SD/MMC[Compsys1.com]
Sub Minit
Set Cs
Dat = &HFF
For I = 1 To 10
  Shiftout Mosi , Clk , Dat , Msbl
Next I
Resp = 255
Reset Cs
Cmd0:
Dat = &H40
Shiftout Mosi , Clk , Dat , Msbl
Addr = &H00000000
Shiftout Mosi , Clk , Addr , Msbl
Dat = &H95
Shiftout Mosi , Clk , Dat , Msbl
While Resp <> &H01
Shiftin Miso , Clk , Resp , Msbl
Wend
Set Cs
Waitms 50
Reset Cs
Dat = &HFF
Cmd1:
While Resp <> &H00
Set Cs
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H41
Shiftout Mosi , Clk , Dat , Msbl
Addr = 0
Shiftout Mosi , Clk , Addr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Wend
Dat = &HFF
Set Cs
End Sub
'_______________________________________________________________________________
'Diol提供的读取SD/MMC扇区[Compsys1.com]
Sub Mread(byval Addr As Long)
Set Cs
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H51
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Addr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
While Resp <> 0
Shiftin Miso , Clk , Resp , Msbl
Wend
While Resp <> &HFE
Shiftin Miso , Clk , Resp , Msbl
Wend
Dim Stn As Byte , A As String * 20 , C As Byte , J1 As Byte
For I = 1 To 512
    Shiftin Miso , Clk , Resp , Msbl
    Indat(i) = Resp
    If Play = 1 Then
      Pwm1a = Resp
      Waitus 30
    End If
Next I
Shiftin Miso , Clk , Resp , Msbl
Shiftin Miso , Clk , Resp , Msbl
Set Cs
End Sub
'_______________________________________________________________________________
'Behnam提供的搜索SD/MMC的FAT表
Sub Msearch
   Address = 0
   Do
      Call Mread(address)
      For I = 1 To 512
         'M is First Char Of "MSDOS5.0" In FAT Sector
         If Indat(i) = "M" Then Exit Do
      Next I
      Address = Address + 512
      Home L : Lcd "Addr:" ; Address
   Loop
   Cls : Lcd "MMC OK"
   Lowerline
   Lcd "MMC FAT: "
   '------------------------ 如果FAT16,字节55到59包含“FAT16”字符串
   For I = 55 To 59
      Fat = Fat + Chr(indat(i))
   Next I
   If Fat = "FAT16" Then
      Lcd "FAT16"
   End If
   '------------------------ 如果FAT32,字节83到87包含“FAT32”字符串
   For I = 83 To 87
      Fat = Fat + Chr(indat(i))
   Next I
   If Fat = "FAT32" Then
      Lcd "FAT32"
   End If
   Wait 2
End Sub
'_______________________________________________________________________________
'Behnam提供的查找SD/MMC的第一个文件地址
Sub Mfirstfile
   Cls : Lcd " Search File..."
   Address = 0
   Do
      Call Mread(address)
      For I = 1 To 512
         '1是第一个文件扇区中“F1”的最后一个字符
         If Indat(i) = "1" And Indat(i -1) = "F" Then Exit Do
      Next I
      Address = Address + 512
      Home L : Lcd "Addr:" ; Address
   Loop
   Cls : Lcd "First File:"
   Lowerline
   Lcd Address
   Firstaddr = Address                                      'Copy FirstFile Addr
   Wait 2
End Sub
'_______________________________________________________________________________
Sub Menu
   Address = Firstaddr
   Play = 1
   Cls : Lcd "  Wave Player"
   Lowerline
   Lcd Chr(0) ; Spc(4) ; Chr(1) ; Spc(4) ; Chr(2) ; Spc(4) ; Chr(3)
   Do
      'Read Keys
      If Play_key = 0 Then                                  '暂停
         Waitms 300
         Do
            If Play_key = 0 Then Exit Do                    '播放
         Loop
         Waitms 300
      End If
      If First_key = 0 Then Address = Firstaddr             '第一个
      If Prev_key = 0 Then                                  '上一个
         If Address > Firstaddr Then Address = Address - 1048576
         Waitms 50
      End If
      If Next_key = 0 Then                                  'Next
         Address = Address + 1048576
         Waitms 50
      End If
      Call Mread(address)
      Address = Address + 512
   Loop
End Sub


工程文件用Proteus 8.9打开




51hei.png (3.75 KB, 下载次数: 117)

51hei.png

新建文件夹.zip

5.02 MB, 下载次数: 13, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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