找回密码
 立即注册

QQ登录

只需一步,快速开始

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

miniSD卡片区读写框架(128Mb的)

[复制链接]
跳转到指定楼层
楼主
ID:51090 发表于 2014-9-17 23:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
sd卡驱动直接使用飞利浦官网提供的驱动库函数进行少许修改,使用三线spi协议传输,由于mega16已经使用到了唯一的spi口进行下载,为不影响sd卡正常读取,只好用PORTC口禁用jtag功能用来模拟spi口,不过速度不会很快,读取以及写入均会通过串口送向串口调试助手进行实时观看sd卡的读写情况

<<MAIN>

#include<iom16v.h>
#include<macros.h>
#include"define.h"
#include"delay.h"
#include"led_driver.h"
#include"spi_mmc.h"
#include"UART0.h"
#include"system_task.h"
#include"hand_driver.h"
#include"sd_rw_com_test.c"
#include"init.h"
void main()
{
system_init();
my_test();
//write_all();

<<<实物图>>>



图片



read_all();
while(1)
{
staple_task();
only_task();
}
}


<<SYSTEM_TASTK_H>>
#ifndef _system_task_H
#define _system_task_H
uchar LIFT_spk=0;
uchar LIFT_tx=0;
uchar LIFT_key1=0;
uchar LIFT_adc=0;
uchar send_data=0;
uchar key_flag=0;
void only_task()
{
if(key_flag)
{
if(key_flag==1)if(task_flag>0){task_flag--;LIFT_spk=1;}else LIFT_spk=4;
if(key_flag==2)if(task_flag<8){task_flag++;LIFT_spk=1;}else LIFT_spk=4;
switch(key_flag+task_flag*10)
{
case 1:break;
case 2:break;
case 13:data_1[task_flag]=--send_data;LIFT_spk=1;break;
case 14:data_1[task_flag]=++send_data;LIFT_spk=1;break;
}
key_flag=0;
}
////////////////////
if(LIFT_adc)
{
LIFT_adc=0;
}
/////////////////////
if(LIFT_spk)
{
speaker(LIFT_spk);
LIFT_spk=0;
}

}
void staple_task()
{
display();
diskey();
}
#endif

<<<仿真图>>>

图片


<<DEFINE.H>>
#ifndef _define_H
#define _define_H
//////////////////////////////////////////////
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//////////////////////////////////////////////
#define WEI_L PORTD&=~BIT(7)
#define WEI_H PORTD|=BIT(7)
#define DULA_L PORTD&=~BIT(6)
#define DULA_H PORTD|=BIT(6)
#define SPK_O PORTC|=BIT(6)
#define SPK_C PORTC&=~BIT(6)
#define LASER_O PORTD|=BIT(3)
#define LASER_C PORTD&=~BIT(3)
//////////////////////////////////////////////////////////////////
////////////////////////////////
#define CS_O PORTC|=BIT(0)
#define CS_C PORTC&=~BIT(0)
////////////////////////////////
#define DO_open DDRC&=~BIT(5)
#define DO_data PINC&0x20
////////////////////////////////
#define DI_O PORTC|=BIT(1)
#define DI_C PORTC&=~BIT(1)
/////////////////////////////////
#define SCK_O PORTC|=BIT(4)
#define SCK_C PORTC&=~BIT(4)
/////////////////////////////////
/////////////////全局标志////////////////////////////
uint time_best=0;
int task_flag=0;
////////////////////////////////////////////
#endif

<<HAND_DRIVER>>

/***********************************************************************/
/* This file is part of the uVision/ARM development tools */
/* Copyright ICCAVR with tongjinlv 20012-20012 */
/***********************************************************************/
/* */
/* ADC.H: Header file for AT ATmega16 / ATmega16 */
/* ATmega16 / ATmega16 */
/* ATmega16 */
/* */
/***********************************************************************/
#ifndef _hang_driver_H
#define _hand_driver_H
void speaker(uchar timeout)
/*系统蜂鸣器*/
{
SPK_O;
while(timeout--)display();
SPK_C;
}
void system_speaker(uchar made_speaker)
/*系统蜂鸣器工作模式*/
{

}
void diskey()
{ uchar key_data;
DDRC|=BIT(7);
PORTC&=~BIT(7);
if((PINA&0XFE)!=0XFE)
{
key_data=PINA;
if(!(key_data&0x80))
{
while(!(PINA&0x80))display();
key_flag=1;
}
if(!(key_data&0x40))
{
while(!(PINA&0x40))display();
key_flag=2;
}
if(!(key_data&0x20))
{
while(!(PINA&0x20))display();
key_flag=3;
}
if(!(key_data&0x10))
{
while(!(PINA&0x10))display();
key_flag=4;
}
////////////////////////////////////
if(task_flag>8)task_flag=8;
if(task_flag<0)task_flag=0;
}
}
#endif

<<DELAY_H>>

/***********************************************************************/
/* This file is part of the uVision/ARM development tools */
/* Copyright ICCAVR with tongjinlv 20012-20012 */
/***********************************************************************/
/* */
/* ADC.H: Header file for AT ATmega16 / ATmega16 */
/* ATmega16 / ATmega16 */
/* ATmega16 */
/* */
/***********************************************************************/
#ifndef _delay_H
#define _delay_H
void delay(uint z_temp)
{
z_temp*=z_temp;
while(z_temp--);
}
void delay_ms(uint z_temp)
{
uint x_temp,y_temp;
for(x_temp=z_temp;x_temp>0;x_temp--)
for(y_temp=120;y_temp>0;y_temp--);
}
void delay_us(uint z_temp)
{
while(z_temp--);
}
void Delay(int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
void inerDelay_us(char n)
{
for(;n>0;n--);

}
#endif

<<INIT.H>>

/***********************************************************************/
/* This file is part of the uVision/ARM development tools */
/* Copyright ICCAVR with tongjinlv 20012-20012 */
/***********************************************************************/
/* */
/* ADC.H: Header file for AT ATmega16 / ATmega16 */
/* ATmega16 / ATmega16 */
/* ATmega16 */
/* */
/***********************************************************************/
#ifndef _INIT_H
#define _INIT_H
void system_init()
{
MCUCSR|=BIT(7);
MCUCSR|=BIT(7);
////////关闭jtag////////////////////////////////////////
DDRB=0XFF;
DDRC=0XFF;
DDRA=0X00;
PORTA|=0XFe;
//PORTA=0XFF;
DDRC&=~BIT(7);
DO_open;
DDRD|=BIT(3)|BIT(6)|BIT(7);
///////端口初始化////////////////////////////////////////////////
UART0_Init ();
}
#endif

<<LED_DRIVER>>

/***********************************************************************/
/* This file is part of the uVision/ARM development tools */
/* Copyright ICCAVR with tongjinlv 20012-20012 */
/***********************************************************************/
/* */
/* ADC.H: Header file for AT ATmega16 / ATmega16 */
/* ATmega16 / ATmega16 */
/* ATmega16 */
/* */
/***********************************************************************/
#ifndef _led_driver_H
#define _led_driver_H
uchar tab_cc[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar tab_ca[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xD8,0x80,0x90};
uchar tab_ua[]={0xC0,0xCF,0xA4,0x86,0x8B,0x92,0x90,0xC7,0x80,0x82,0xff,0xc8,0x87,0xce};
uchar data_6[6];
uchar task_logo[8]={11,12,13};
uchar data_3[3]={12,44,55};
uint data_1[9]={0,0,0,0,0,0,0,0,0};
void display()
{
uchar i;
for(i=0;i<6;i++)
{
WEI_L;
DULA_H;
PORTB=tab_ua[data_6[i]];
DULA_L;
PORTB=BIT(i);
WEI_H;
delay(1);
data_6[0]=task_flag;
data_6[1]=task_flag+11;
data_6[2]=data_1[task_flag]%10000/1000;
if(!data_6[2])data_6[2]=10;
data_6[3]=data_1[task_flag]%1000/100;
data_6[4]=data_1[task_flag]%100/10;
data_6[5]=data_1[task_flag]%10;
PORTB=0x00;
}
}
#endif

<<SD_READ_WRITE.H>>

/*----------------------------------------------------------------------
* Name: SPI_MMC.H
* Purpose: SPI mode MMC card interface driver
* Version: V1.03
* Copyright (c) 2005 Philips Semiconductor. All rights reserved.
*---------------------------------------------------------------------*/
#ifndef __SPI_MMC_H__
#define __SPI_MMC_H__
#define MMC_CMD_SIZE 6
#define MMC_DATA_SIZE 256 /* 16-bit in size, 512 bytes */
#define MAX_TIMEOUT 0xFF
#define IDLE_STATE_TIMEOUT 1
#define OP_COND_TIMEOUT 2
#define SET_BLOCKLEN_TIMEOUT 3
#define WRITE_BLOCK_TIMEOUT 4
#define WRITE_BLOCK_FAIL 5
#define READ_BLOCK_TIMEOUT 6
#define READ_BLOCK_DATA_TOKEN_MISSING 7
#define DATA_TOKEN_TIMEOUT 8
#define SELECT_CARD_TIMEOUT 9
#define SET_RELATIVE_ADDR_TIMEOUT 10
uchar MMCWRData[MMC_DATA_SIZE];
uchar MMCRDData[MMC_DATA_SIZE];
uchar MMCCmd[MMC_CMD_SIZE];
uchar MMCStatus = 0;
char SPI_RW(char data)
{
char i,temp=0;
for(i=0;i<8;i++)
{
if(data & 0x80)DI_O;
else DI_C;
data = (data << 1);
temp<<=1;
SCK_O;
if(DO_data)temp++;
SCK_C;
}
return(temp);
}
void SPI_Send(uchar *buf, uint Length )
{
uint i;
for(i = 0; i < Length; i++)
{
SPI_RW(*buf++);
}
}
void SPI_Receive(uchar *buf, uint Length )
{
uint i;
for ( i = 0; i < Length; i++ )
{
*buf = SPI_RW(0xff);
buf++;
}
}
uchar SPI_ReceiveByte( void )
{
uchar data;
data=SPI_RW(0xff);
return ( data );
}
int mmc_response( unsigned char response)
{
uint count = 0xFFF;

while( (SPI_ReceiveByte() != response) && count )
{
count--;
}
if ( count == 0 )return 1;
else return 0;
}
int mmc_init()
{
uint i;
for(i=0;i<MMC_DATA_SIZE;i++)
{
MMCWRData[i] = i;
MMCRDData[i] = ~i;
}
MMCStatus = 0;
CS_O;
for(i=0; i<10; i++)
{
MMCRDData[i] = 0xFF;
}
SPI_Send( MMCRDData, 10 );
CS_C;

MMCCmd[0] = 0x40;
MMCCmd[1] = 0x00;
MMCCmd[2] = 0x00;
MMCCmd[3] = 0x00;
MMCCmd[4] = 0x00;
MMCCmd[5] = 0x95;
SPI_Send( MMCCmd, MMC_CMD_SIZE );
if( mmc_response(0x01) == 1 )
{
MMCStatus = IDLE_STATE_TIMEOUT;
CS_O;
return MMCStatus;
}
CS_O;
SPI_ReceiveByte();
CS_C;
i = MAX_TIMEOUT;
do
{
MMCCmd[0] = 0x41;
MMCCmd[1] = 0x00;
MMCCmd[2] = 0x00;
MMCCmd[3] = 0x00;
MMCCmd[4] = 0x00;
MMCCmd[5] = 0xFF;
SPI_Send( MMCCmd, MMC_CMD_SIZE );
i--;
} while ( (mmc_response(0x00) != 0) && (i>0) );
if ( i == 0 )
{
MMCStatus = OP_COND_TIMEOUT;
CS_O;
return MMCStatus;
}
CS_O;
SPI_ReceiveByte();
CS_C;
MMCCmd[0] = 0x50;
MMCCmd[1] = 0x00;
MMCCmd[2] = 0x00;
MMCCmd[3] = 0x02;
MMCCmd[4] = 0x00;
MMCCmd[5] = 0xFF;
SPI_Send( MMCCmd, MMC_CMD_SIZE );
if( (mmc_response(0x00))==1 )
{
MMCStatus = SET_BLOCKLEN_TIMEOUT;
CS_O;
return MMCStatus;
}
CS_O;
SPI_ReceiveByte();
return 0;
}
/*
int mmc_write_block(uint block_number)
{
uint varl, varh;
uchar Status;
CS_C;
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);
MMCCmd[0] = 0x58;
MMCCmd[1] = varh >> 0x08;
MMCCmd[2] = varh & 0xFF;
MMCCmd[3] = varl >> 0x08;
MMCCmd[4] = varl & 0xFF;
MMCCmd[5] = 0xFF;
SPI_Send(MMCCmd, MMC_CMD_SIZE );
if((mmc_response(0x00))==1)
{
MMCStatus = WRITE_BLOCK_TIMEOUT;
CS_O;
return MMCStatus;
}
MMCCmd[0] = 0xFE;
SPI_Send( MMCCmd, 1 );
SPI_Send( MMCWRData, MMC_DATA_SIZE );
MMCCmd[0] = 0xFF;
MMCCmd[1] = 0xFF;
SPI_Send( MMCCmd, 2 );
Status = SPI_ReceiveByte();
if ( (Status & 0x0F) != 0x05 )
{
MMCStatus = WRITE_BLOCK_FAIL;
CS_O;
return MMCStatus;
}
if(mmc_wait_for_write_finish()==1)
{
MMCStatus = WRITE_BLOCK_FAIL;
CS_O;
return MMCStatus;
}

CS_O;
SPI_ReceiveByte();
return 0;
} */
int mmc_read_block(uint block_number)
{
uint Checksum;
uint varh,varl;
CS_C;
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);
MMCCmd[0] = 0x51;
MMCCmd[1] = varh >> 0x08;
MMCCmd[2] = varh & 0xFF;
MMCCmd[3] = varl >> 0x08;
MMCCmd[4] = varl & 0xFF;
MMCCmd[5] = 0xFF;
SPI_Send(MMCCmd, MMC_CMD_SIZE );
if((mmc_response(0x00))==1)
{
MMCStatus = READ_BLOCK_TIMEOUT;
CS_O;
return MMCStatus;
}
if((mmc_response(0xFE))==1)
{
MMCStatus = READ_BLOCK_DATA_TOKEN_MISSING;
CS_O;
return MMCStatus;
}
SPI_Receive( MMCRDData, MMC_DATA_SIZE );
Checksum = SPI_ReceiveByte();
Checksum = Checksum << 0x08 | SPI_ReceiveByte();
CS_O;
SPI_ReceiveByte();
return 0;
}
int mmc_write_block(uint block_number)
{
uint varl, varh;
uchar Status;

CS_C; /* clear SPI SSEL */

/* block size has been set in mmc_init() */
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);

/* send mmc CMD24(WRITE_SINGLE_BLOCK) to write the data to MMC card */
MMCCmd[0] = 0x58;
/* high block address bits, varh HIGH and LOW */
MMCCmd[1] = varh >> 0x08;
MMCCmd[2] = varh & 0xFF;
/* low block address bits, varl HIGH and LOW */
MMCCmd[3] = varl >> 0x08;
MMCCmd[4] = varl & 0xFF;
/* checksum is no longer required but we always send 0xFF */
MMCCmd[5] = 0xFF;
SPI_Send(MMCCmd, MMC_CMD_SIZE );

/* if mmc_response returns 1 then we failed to get a 0x00 response */
if((mmc_response(0x00))==1)
{
MMCStatus = WRITE_BLOCK_TIMEOUT;
CS_O; /* set SPI SSEL */
return MMCStatus;
}

/* Set bit 0 to 0 which indicates the beginning of the data block */
MMCCmd[0] = 0xFE;
SPI_Send( MMCCmd, 1 );

/* send data, pattern as 0x00,0x01,0x02,0x03,0x04,0x05 ...*/
SPI_Send( MMCWRData, MMC_DATA_SIZE );

/* Send dummy checksum */
/* when the last check sum is sent, the response should come back
immediately. So, check the SPI FIFO MISO and make sure the status
return 0xX5, the bit 3 through 0 should be 0x05 */
MMCCmd[0] = 0xFF;
MMCCmd[1] = 0xFF;
SPI_Send( MMCCmd, 2 );
Status = SPI_ReceiveByte();

if ( (Status & 0x0F) != 0x05 )
{
MMCStatus = WRITE_BLOCK_FAIL;
CS_O; // set SPI SSEL
return MMCStatus;
}

/* if the status is already zero, the write hasn't finished
yet and card is busy */
if(mmc_wait_for_write_finish()==1)
{
MMCStatus = WRITE_BLOCK_FAIL;
CS_O; /* set SPI SSEL */
return MMCStatus;
}

CS_O; /* set SPI SSEL */
SPI_ReceiveByte();
return 0;
}

int mmc_wait_for_write_finish( void )
{
uint count = 0xFFFF;
uchar result = 0;
while( (result == 0) && count )
{
result = SPI_ReceiveByte();
count--;
}
if ( count == 0 ) return 1;
else return 0;
}
#endif

<<UART0.H>>

/***********************************************************************/
/* This file is part of the uVision/ARM development tools */
/* Copyright ICCAVR with tongjinlv 20012-20012 */
/***********************************************************************/
/* */
/* ADC.H: Header file for AT ATmega16 / ATmega16 */
/* ATmega16 / ATmega16 */
/* ATmega16 */
/* */
/***********************************************************************/
#ifndef _uart0_h_
#define _uart0_h_
#define Crystal 8000000 //晶振8MHZ
#define Baud 9600 //波特率
void UART0_Init ()
{
DDRD|=BIT(1);
DDRD&=~BIT(0);
PORTD|=0X03;
UCSRB = 0x00; //禁止发送和接收
UCSRA = 0x02; //倍速异步模式USX=1
UCSRC = 0x06; //0000 0110,UCSZ1=1,UCSZ0=1
UBRRL=(Crystal/8/(Baud+1))%256; //若为正常异步模式USX0=0则位
//(Crystal/16/(Baud+1))%256
UBRRH=(Crystal/8/(Baud+1))/256; //参见ATMAGE16使用手册
UCSRB = 0x18; //允许发送和接收
}
uchar UART0_GetByte(void)
{
while(!(UCSRA&(1<<RXC)));
return UDR;
}
void UART0_GetStr (uchar *s, uint n)
{

}
void UART0_SendByte (uint dat)
{
while(!(UCSRA&(1<<UDRE)));
UDR=dat;
}
void UART0_SendStr(uchar const *s)
{
while(*s)
{
UART0_SendByte(*s);
s++;
}
}
void IRQ_UART0 (void)
{

}
#endif

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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