发个44b0的SD驱动(软件模拟SPI接口)
typedef unsigned charboolean; /* 布尔变量 */typedef unsigned charuint8; /* 无符号8位整型变量 */
typedef signed charint8; /* 有符号8位整型变量 */
typedef unsigned short uint16; /* 无符号16位整型变量 */
typedef signed short int16; /* 有符号16位整型变量 */
typedef unsigned int uint32; /* 无符号32位整型变量 */
typedef signed int int32; /* 有符号32位整型变量 */
typedef float fp32; /* 单精度浮点数(32位长度) */
typedef double fp64; /* 双精度浮点数(64位长度)
#define R00
#define R11
#define R1b 2
#define R23
#define R34
uint32 loop_time;
uint8rep;
#definenop() do{;}while(0);
#defineCS_PIN 6//RS VD4
#defineDI_PIN 7//RW VD6
#defineSD_CS_PORT rPDATE
#defineSD_CS_DDR_PORT rPCONE
#defineSD_CS_PUP_PORT rPUPE
#defineSD_DI_PORT rPDATE
#defineSD_DI_DDR_PORT rPCONE
#defineSD_DI_PUP_PORT rPUPE
#defineDO_PIN 12//EN VD5
#defineCLK_PIN 13//RS VD4
#defineSD_DO_PORT rPDATC
#defineSD_DO_DDR_PORT rPCONC
#defineSD_DO_PUP_PORT rPUPC
#defineSD_CLK_PORT rPDATC
#defineSD_CLK_DDR_PORT rPCONC
#defineSD_CLK_PUP_PORT rPUPC
#define CS_LOW() SD_CS_PORT&= ~(1<< CS_PIN)
#define CS_HIGH()SD_CS_PORT|= (1<< CS_PIN)
#define DI_LOW() SD_DI_PORT&= ~(1<< DI_PIN)
#define DI_HIGH()SD_DI_PORT|= (1<< DI_PIN)
#define CLK_LOW()SD_CLK_PORT &= ~(1<< CLK_PIN)
#define CLK_HIGH() SD_CLK_PORT |= (1<< CLK_PIN)
#define DO() SD_DO_PORT & (0x01<<DO_PIN)
#define _400KHZ_ 128
#define _10MHZ_1
//-----------------------------------------------------------
//延时
static void loop(uint32 i)
//-----------------------------------------------------------
{
while (i--)
{
;//nop();
}
}
//-----------------------------------------------------------
//发送一字节数据
static void SPI_send(uint8 cmd)
//-----------------------------------------------------------
{
uint8 i;
uint8 MASK[] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
for (i = 0; i < 8; i++)
{
CLK_LOW();
if (cmd & MASK)
DI_HIGH();
else
DI_LOW();
loop(loop_time);
CLK_HIGH();
}
}
//-----------------------------------------------------------
//接收一字节数据
static uint8 SPI_receive(void)
//-----------------------------------------------------------
{
uint8 i;
uint8 ret = 0;
uint8 MASK[] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
for (i = 0; i < 8; i++)
{
CLK_LOW();
loop(loop_time);
if (DO())
ret |= MASK;
CLK_HIGH();
}
return ret;
}
//-----------------------------------------------------------
//发送命令
static uint8 SendCommand(uint8 cmd, uint32 arg, uint8 ACK)
//-----------------------------------------------------------
{
uint8 status;
uint8 i;
uint8 len;
SPI_send(cmd|0x40);
SPI_send(arg>>24);
SPI_send(arg>>16);
SPI_send(arg>>8);
SPI_send(arg);
SPI_send(0x95);
switch (ACK)
{
case R0:
return 1;
case R1:
len=1;
break;
case R2:
len=2;
break;
case R3:
len=5;
break;
default:
return 0;
break;
}
for (i = 0; i < 100; i++)
{
status = SPI_receive();
if (!(status & 0x80))
break;
}
if (i >= 100)
{
SPI_send(0xff);
return 0;
}
rep = status;
for (i = 1; i < len; i++)
{
rep = SPI_receive();
}
SPI_send(0xff);
return 1;
}
//-----------------------------------------------------------
static void Reset(void)
//-----------------------------------------------------------
{
CS_LOW();
SendCommand(0x00,0x00,R0);
CS_HIGH();
}
//-----------------------------------------------------------
static uint32 IsSD(void)
//-----------------------------------------------------------
{
uint32 i;
CS_LOW();
for (i = 0; i < 1000; i++)
{
SendCommand(55,0x0000,R1);
SendCommand(41,0x0000,R1);
if (!rep)
break;
loop(200);
}
CS_HIGH();
return i != 100;
}
//-----------------------------------------------------------
static uint32 IsMMC(void)
//-----------------------------------------------------------
{
uint32 i;
CS_LOW();
for (i = 0; i < 1000; i++)
{
SendCommand(1, 0x0000, R1);
if (!rep)
break;
loop(200);
}
CS_HIGH();
return i != 100;
}
//-----------------------------------------------------------
int SD_erase(uint32 sector,uint8 *buff)
//-----------------------------------------------------------
{
CS_LOW();
if (!SendCommand(32,sector<<9,R1)||!SendCommand(33,sector<<9,R1)||!SendCommand(38,0x0000,R1))
{
CS_HIGH();
return 0;
}
while (!DO())
SPI_send(0xff);
CS_HIGH();
return 1;
}
uint32 SD_read(uint32 sector,uint8 *buff)
{
uint32 i;
CS_LOW();
if (!SendCommand(17,sector<<9,R1))
{
CS_HIGH();
//UART_puts("readerr1");
return 0;
}
for (i = 0; i < 100; i++)
{
if (SPI_receive() == 0xfe)
break;
}
if (i >= 100)
{
CS_HIGH();
//UART_puts("readerr2");
return 0;
}
for (i = 0; i < 512; i++)
{
*buff++ = SPI_receive();
}
SPI_receive();
SPI_receive();
SPI_send(0xff);
CS_HIGH();
//UART_puts("readOK");
return 1;
}
uint32 SD_write(uint32 sector,uint8 *buff)
{
uint32 i;
CS_LOW();
SendCommand(24,sector<<9,R1);
SPI_send(0xfe);
for (i = 0; i < 512; i++)
SPI_send(buff);
SPI_send(0xff);
SPI_send(0xff);
for (i = 0; i < 100; i++)
{
rep = SPI_receive();
if (!rep)
break;
}
if (i >= 100)
{
//UART_puts("writeerr1");
return 0;
}
while (!DO())
SPI_send(0xff);
CS_HIGH();
//UART_puts("writeOK");
//下面其实是复位
loop_time =_400KHZ_;
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
IsSD();
loop_time=_10MHZ_;
//完
return 1;
}
void SD_install(void)
{
loop_time =_400KHZ_;
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
SPI_send(0xff);
Reset();
if (!IsSD()&&!IsMMC())
{
//UART_puts("unknown card type!\n");
return;
}
//UART_puts("SD/MMC card found!\n Now loading SD/MMC driver......\n");
loop_time=_10MHZ_;
}
void SD_init(void)
{
uint32 temp;
temp = rPCONC;
temp &= 0xf0ffffff;
temp |= 0x04000000;
rPCONC = temp;
temp = rPCONE;
temp &= 0xffff0fff;
temp |= 0x00005000;
rPCONE = temp;
SD_install();
}
/*
一直想在自己的44b0开发板上,挂个SD卡,再上个FAT文件系统,
郁闷的是,44B0没有多媒体卡的接口,也没SPI接口,只能通过用IO软件模拟SPI接口,比较慢,不过还是可以用的
在论坛下了个在AVR上的用IO软件模拟SPI接口的程序,可惜调不通,后来在网上找到了个PC版的,改了下接口,调通了
不过,在我的SD卡上,也不知道为什么,写完一个扇区后要复位才可以再读扇区,不然会出现错误
有44b0的朋友帮忙下,能否建立个FAT文件系统
*/ 支持一下.. ding 44B0的I/O速度太慢了,前几天我也是44B0用软件模拟SPI,用示波器看了下,全速的情况下SCK的频率也只有400KHZ左右 请问S3C44B0X的SIO口不能当作SPI口用吗???,我现在正在用S3C44B0X SIO+MCP2515 SPI扩展CAN接口,但是没调通,很郁闷 mark S3C44B0X的SIO口能当作SPI,S3C44B0X SIO+MCP2515 SPI扩展CAN接口,是可以的 您那个AVR上的用IO软件模拟SPI接口的程序在哪? 好的,谢谢了, 抄袭别人的东西请注明来源
页:
[1]