📄 mp3.c
字号:
uint32 start_cluster;
uint32 current_cluster;
uint8 current_sector;
uint16 current_index;
}
[8]struct s_directory_node directory_node;
uint8 current_level;
//硬盘参数
uint32 disk_sector_size; //硬盘总空间(单位扇区)
uint16 sector_byte_size; //每扇区字节数
uint8 cluster_sector_size; //每簇的扇区数
uint8 FAT_number; //FAT表数目
uint32 FAT_sector_size; //每个FAT表占据的扇区数
uint32 FAT1_start_sector; //FAT1起始扇区号
uint32 FAT2_start_sector; //FAT2起始扇区号
uint32 cluster_start_sector; //数据簇的起始扇区号
public [512]uint8 buffer;
public bool is_ok;
}
//*******************************************************
//当前项信息
unit selected_item
{
//当前项的信息
public uint8 type;
public bool is_out; //是否在有效项目之外
public bool is_delete; //是否已被删除
public bool is_system_dir;//是否系统目录项(以句号开始)
public bool is_long_name;//是否长文件名
public bool is_file; //是否为文件
public bool is_directory;//是否为目录
public [9]uint8 base_name;
public [4]uint8 extend_name;
public uint8 attribute;
public uint32 start_cluster;
public uint32 length;
//文件属性常量, 用相与非零表示表示对应属性为真
public const uint8 READ_ONLY = 0b0000_0001;
public const uint8 HIDDEN = 0b0000_0010;
public const uint8 SYSTEM = 0b0000_0100;
public const uint8 DISK = 0b0000_1000;
public const uint8 DIRECTORY = 0b0001_0000;
public const uint8 FILE = 0b0010_0000;
//项目类型常量
public const uint8 NULL = 0x00;
public const uint8 DELETE = 0xe5;
public const uint8 SYSTEM_DIR = '.';
}
//*******************************************************
//SD卡元件类
unit SD_card
{
//=================================================
//初始化
public void init()
{
CS_ddr = high;
CS_port = high;
SCLK_ddr = high;
SCLK_port = low;
SD_DI_ddr = high;
SD_DI_port = high;
SD_DO_ddr = low;
SD_DO_port = high;
null_clock();
}
//=================================================
//sd卡复位
public bool reset()
{
uint8 retry = 0;
uint8 r1;
do {
null_clock();
r1 = write_command( 0, 0 );//发idle命令
++retry;
if( retry > 250 ) return false;//超时退出
}
while( r1 != 0x01 );
retry = 0;
do {
null_clock();
//r1 = write_command( 1, 0 );//发active命令
r1 = write_command( 55, 0 );//发active命令
r1 = write_command( 41, 0 );//发active命令
++retry;
if( retry > 250 ) {
return false;//超时退出
}
}
while( r1 != 0x00 );
r1 = write_command( 59, 0 );//关crc
r1 = write_command( 16, 512 );//设扇区大小512
return true;//正常返回
}
//=================================================
//读一个扇区
public bool read_block( uint32 sector, *uint8 buffer )
{
uint8 r1 = write_command( 17, sector << 9 );//读命令
if( r1 != 0x00 ) {
return false;
}
CS_port = low;
//等数据的开始
while( read_byte() != 0xfe ) {}
// for( uint16 i = 0; i < 512; ++i ) {
// buffer[i] = read_byte();
// }
*uint8 p = buffer;
loop( 250 ) {
*p = read_byte();
++p;
}
loop( 250 ) {
*p = read_byte();
++p;
}
loop( 12 ) {
*p = read_byte();
++p;
}
r1 = read_byte();//伪crc
r1 = read_byte();
CS_port = high;
return true;
}
//=================================================
//写一个扇区
public bool write_block( uint32 sector, *uint8 buffer )
{
uint8 r1 = write_command( 24, sector << 9 );//写命令
if( r1 != 0x00 ) {
return false;
}
CS_port = low;
null_clock();
write_byte( 0xfe ); //发开始符
for( uint16 i = 0; i < 512; ++i ) {
write_byte( buffer[i] );
}
write_byte( 0xff ); //伪CRC
write_byte( 0xff );
//判断是否成功
if( read_byte() & 0x1f != 0x05 ) {
CS_port = high;
return false;
}
//等待操作完
while( read_byte() == 0 ) {}
CS_port = high;
return true;
}
//=================================================
//sd卡写命令
uint8 write_command( uint8 cmd, uint32 arg )
{
write_byte( 0xff );
CS_port = low;
write_byte( cmd | 0x40 );//分别写入命令
write_byte( arg.24[uint8] );
write_byte( arg.16[uint8] );
write_byte( arg.8[uint8] );
write_byte( arg.0[uint8] );
write_byte( 0x95 );
uint8 r1;
uint8 retry = 0;
do {
++retry;
r1 = read_byte();
}
while( r1 == 0xff && retry < 100 ); //等待响应,
CS_port = high;
return r1;
}
//=================================================
//空时钟函数
void null_clock()
{
loop( 100 ) {
SCLK_port = high;
SCLK_port = low;
}
}
//=================================================
//写一个字节
void write_byte( uint8 data )
{
loop( 8 ) {
SD_DI_port = data.7;
SCLK_port = high;
SCLK_port = low;
data <<= 1;
}
}
//=================================================
//读一个字节
uint8 read_byte()
{
SD_DI_port = high;
uint8 data;
loop( 8 ) {
data <<= 1;
SCLK_port = high;
data.0 = SD_DO_pin;
SCLK_port = low;
}
return data;
}
//=================================================
bit SD_DO_port = @SD_card_config.SD_DO_port;
bit SD_DO_pin = @SD_card_config.SD_DO_pin;
bit SD_DO_ddr = @SD_card_config.SD_DO_ddr;
bit SCLK_port = @SD_card_config.SCLK_port;
//bit SCLK_pin = @SD_card_config.SCLK_pin;
bit SCLK_ddr = @SD_card_config.SCLK_ddr;
bit SD_DI_port = @SD_card_config.SD_DI_port;
//bit SD_DI_pin =@ SD_card_config.bit SD_DI_pin;
bit SD_DI_ddr = @SD_card_config.SD_DI_ddr;
bit CS_port = @SD_card_config.CS_port;
//bit CS_pin = @SD_card_config.CS_pin;
bit CS_ddr = @SD_card_config.CS_ddr;
}
//*******************************************************
//VS1003B MP3解码器
unit vs1003b
{
//初始化
public void init()
{
//spi初始化
vs_spi.init();
XDCS_ddr = high;
XDCS_port = high;
XCS_ddr = high;
XCS_port = high;
XRESET_ddr = high;
XRESET_port = high;
DREQ_ddr = low;
//硬件复位
XRESET_port = low;
time.delay_10ms( 10 );
XRESET_port = high;
time.delay_10ms( 10 );
//写mode寄存器
set( 0x00, 0x0800 );
//写时钟寄存器
set( 0x03, 0xc000 );
//设音量
set( 0x0b, 0x2828 );
}
//写数据,音乐数据
public void write_byte_data( uint8 data )
{
XDCS_port = low;
vs_spi.write_byte( data );
XDCS_port = high;
}
//写数据,音乐数据
public void write_buffer_data( *uint8 p )
{
XDCS_port = low;
loop( 32 ) {
uint8 data = *p;
vs_spi.write_byte( data );
++p;
}
XDCS_port = high;
}
//判断解码芯片是否忙
public bool is_busy()
{
return DREQ_pin == low;
}
//正弦波测试
public void test_sin()
{
set( 0x00, 0x0820 );
while( DREQ_pin == low ) {}
forever {
write_byte_data( 0x53 );
write_byte_data( 0xEF );
write_byte_data( 0x6E );
write_byte_data( 0x30 );
write_byte_data( 0x00 );
write_byte_data( 0x00 );
write_byte_data( 0x00 );
write_byte_data( 0x00 );
led.flash( 1 );
write_byte_data( 0x45 );
write_byte_data( 0x78 );
write_byte_data( 0x69 );
write_byte_data( 0x74 );
write_byte_data( 0x00 );
write_byte_data( 0x00 );
write_byte_data( 0x00 );
write_byte_data( 0x00 );
led.flash( 1 );
}
}
//写寄存器,参数,地址和数据
void set( uint8 addr, uint16 data )
{
XCS_port = low;
vs_spi.write_byte( 0x02 );
vs_spi.write_byte( addr );
vs_spi.write_byte( data.8[uint8] );
vs_spi.write_byte( data.0[uint8] );
XCS_port = high;
}
//读寄存器,参数 地址 返回内容
uint16 get( uint8 addr )
{
XCS_port = low;
vs_spi.write_byte( 0x03 );
vs_spi.write_byte( addr );
uint16 result;
result.8[uint8] = vs_spi.read_byte();
result.0[uint8] = vs_spi.read_byte();
XCS_port = high;
return result;
}
bit XDCS_port = @sfr.PORTC.5;
bit XDCS_ddr = @sfr.DDRC.5;
bit XCS_port = @sfr.PORTC.4;
bit XCS_ddr = @sfr.DDRC.4;
bit XRESET_port = @sfr.PORTA.7;
bit XRESET_ddr = @sfr.DDRA.7;
bit DREQ_pin = @sfr.PINC.6;
bit DREQ_ddr = @sfr.DDRC.6;
}
//*******************************************************
//SPI串行接口元件,高位在前,低位在后
unit vs_spi
{
//初始化
public void init()
{
SCK_ddr = high;
SCK_port = low;
MOSI_ddr = high;
MOSI_port = low;
MISO_ddr = low;
}
//写一个字节
public void write_byte( uint8 data )
{
loop( 8 ) {
MOSI_port = data.7;
SCK_port = high;
SCK_port = low;
data <<= 1;
}
}
//读一个字节
public uint8 read_byte()
{
MOSI_port = low;
uint8 data;
loop( 8 ) {
data <<= 1;
SCK_port = high;
data.0 = MISO_pin;
SCK_port = low;
}
return data;
}
bit SCK_port = @sfr.PORTA.4; //时钟线
bit SCK_ddr = @sfr.DDRA.4;
bit MISO_pin = @sfr.PINA.6; //读数据端口
bit MISO_ddr = @sfr.PINA.6;
bit MOSI_port = @sfr.PORTA.5; //写数据端口
bit MOSI_ddr = @sfr.DDRA.5;
}
//*******************************************************
//延时类
unit time
{
//延时1ms
//public void delay_1ms( uint8 data )
//延时10ms
public void delay_10ms( uint8 data )
{
loop( data ) loop( 40 ) loop( 250 ) {}
}
//延时100ms
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -