?? 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 + -