基于51单片机的SD卡读卡器MMC存储器

最新更新时间:2022-03-05来源: eefocus关键字:51单片机  SD卡读卡器 手机看文章 扫描二维码
随时随地手机看文章

硬件设计

在这里插入图片描述

程序设计

#include


#define F_OSC  11059200//晶振平率Hz

#define F_BAUD 9600

#define RELOAD 256-F_OSC/12/32/F_BAUD

#define CR 0x0D        //回车


//定义SD卡需要的4根信号线

sbit SD_CLK = P1^4;

sbit SD_DI  = P1^6;

sbit SD_DO  = P1^5;

sbit SD_CS  = P1^7;


unsigned char xdata DATA[512];

//定义512字节缓冲区,注意需要使用 xdata关键字



//===========================================================

//写一字节到SD卡,模拟SPI总线方式

void SdWrite(unsigned char n)

{


    unsigned char i;

    

    for(i=8;i;i--)

    {

        SD_CLK=0;

        SD_DI=(n&0x80);

        n<<=1;

        SD_CLK=1;

        }

        SD_DI=1; 

    } 

//===========================================================

//从SD卡读一字节,模拟SPI总线方式

unsigned char SdRead()

{

    unsigned char n,i;

    for(i=8;i;i--)

    {

        SD_CLK=0;

        SD_CLK=1;

        n<<=1;

        if(SD_DO) n|=1;

    

    }

    return n;

}

//============================================================

//检测SD卡的响应

unsigned char SdResponse()

{

    unsigned char i=0,response;

    

    while(i<=8)

    {

        response = SdRead();

        if(response==0x00)

        break;

        if(response==0x01)

        break;

        i++;

    }

    return response;

//================================================================

//发命令到SD卡

void SdCommand(unsigned char command, unsigned long argument, unsigned char CRC)

{


    SdWrite(command|0x40);

    SdWrite(((unsigned char *)&argument)[0]);

    SdWrite(((unsigned char *)&argument)[1]);

    SdWrite(((unsigned char *)&argument)[2]);

    SdWrite(((unsigned char *)&argument)[3]);

    SdWrite(CRC);

}

//================================================================

//初始化SD卡

unsigned char SdInit(void)

{

    int delay=0, trials=0;

    unsigned char i;

    unsigned char response=0x01;

    

    SD_CS=1;

    for(i=0;i<=9;i++)

    SdWrite(0xff);

    SD_CS=0;

    

    //Send Command 0 to put MMC in SPI mode

    SdCommand(0x00,0,0x95);

    

    

    response=SdResponse();

    

    if(response!=0x01)

    {

        return 0;

    } 


    while(response==0x01)

    {

        SD_CS=1;

        SdWrite(0xff);

        SD_CS=0;

        SdCommand(0x01,0x00ffc000,0xff);

        response=SdResponse();

    } 


    SD_CS=1;

    SdWrite(0xff);

    return 1; 

}

//================================================================

//往SD卡指定地址写数据,一次最多512字节

unsigned char SdWriteBlock(unsigned char *Block, unsigned long address,int len)

{

    unsigned int count;

    unsigned char dataResp;

    //Block size is 512 bytes exactly

    //First Lower SS

    

    SD_CS=0;

    //Then send write command

    SdCommand(0x18,address,0xff);

    

    if(SdResponse()==00)

    {

        SdWrite(0xff);

        SdWrite(0xff);

        SdWrite(0xff);

        //command was a success - now send data

        //start with DATA TOKEN = 0xFE

        SdWrite(0xfe);

        //now send data

        for(count=0;count        

        for(;count<512;count++) SdWrite(0);

        //data block sent - now send checksum

        SdWrite(0xff); //两字节CRC校验, 为0XFFFF 表示不考虑CRC

        SdWrite(0xff);

        //Now read in the DATA RESPONSE token

        dataResp=SdRead();

        //Following the DATA RESPONSE token

        //are a number of BUSY bytes

        //a zero byte indicates the MMC is busy

        

        while(SdRead()==0);

        

        dataResp=dataResp&0x0f; //mask the high byte of the DATA RESPONSE token

        SD_CS=1;

        SdWrite(0xff);

        if(dataResp==0x0b)

        {

        //printf("DATA WAS NOT ACCEPTED BY CARD -- CRC ERRORn");

        return 0;

        }

        if(dataResp==0x05)

        return 1;

        

        //printf("Invalid data Response token.n");

        return 0;

    }

    //printf("Command 0x18 (Write) was not received by the MMC.n");

    return 0;

}


文件仅供参考


链接:https://pan.baidu.com/s/1h3ZnGUPP5o_8_NsVMwVQuA

提取码:4ebs

关键字:51单片机  SD卡读卡器 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic559205.html

上一篇:基于51单片机的多点8路温度采集系统
下一篇:基于51单片机的智能温控风扇

推荐阅读

51单片机流水灯控制(5种方法)
实现流程: 1. 新建一个工程(新项目) 2. 查看原理图确定需求(流水灯)对应LED引脚在单片机上的哪个引脚 3. 编写程序(通过查看原理图可以看到我们需要控制整个P2口以控制8个LED灯) 4. 编译程序,下载程序至开发板 5. 查看效果(调试)进制转换表(因为单片机首先处理的是十六进制的数据,所以我们需要将二进制控制需求转换成十六进制去写代码):控制代码:#include <REGX52.H> //头文件#include "Delay.h"#include "intrins.h"/* -----------------------------------------
发表于 2022-09-29
<font color='red'>51单片机</font>流水灯控制(5种方法)
51单片机 定时器时钟
1.main.c注:Sec,Min,Hour可不进行赋值#include <REGX52.H>#include "Delay.h"#include "LCD1602.h"#include "Timer0.h"unsigned char Sec=55,Min=59,Hour=23;void main(){ LCD_Init(); Timer0Init(); LCD_ShowString(1,1,"Clock:"); LCD_ShowString(2,1," : :"); while(1) { LCD_ShowNum(2
发表于 2022-09-28
51单片机 按键控制LED流水灯模式
1.将之前文件中Delay.c.h复制过来,进行添加2.模块化编程3.main.c#include <REGX52.H>#include "Timer0.h"#include "Key.h"#include <INTRINS.H>unsigned char KeyNum,LEDMode;void main(){ P2=0xFE; Timer0Init(); while(1) { KeyNum=Key(); if(KeyNum==1) { LEDMode++; if(LEDMode>=2)LEDMode=0; } } }void Timer0_Routi
发表于 2022-09-28
<font color='red'>51单片机</font> 按键控制LED流水灯模式
51单片机 LCD1602调试工具
本章博客讲述的是关于LCD1602的调试,使用它是为了更加直观的表示出代码所要实现的功能1.首先,需要添加两份驱动文件到新建的工程中来,再插入到新建的工程中来将其复制到新建文件的同一目录下,在进行添加2.写出以下代码进行编译查看效果#include <REGX52.H>#include "LCD1602.h"void main(){ LCD_Init(); LCD_ShowChar(1,1,'A'); LCD_ShowString(1,3,"Hello"); LCD_ShowNum(1,9,123,3); //高位补零,如果最后一位是2则显示23 LCD_
发表于 2022-09-28
<font color='red'>51单片机</font> LCD1602调试工具
51单片机 模块化编程
了解模块化编程1.首先了解一下传统方式编程和模块化编程传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路 模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等2. 模块化编程注意事项.c文件:函数、变量的定义.h文件:可被外部调用的函数、变量的声明任何自定义的变量、函数在调用前必须有定义或声明(同一个.c)使用到的自定义函数的.c文件必须添加到工程参
发表于 2022-09-28
<font color='red'>51单片机</font> 模块化编程
51单片机 动态数码管显示
本章博客写的内容主要围绕动态数码管显示,动态数码管显示与静态数码管显示比较稍有变化,主要在添加延时函数这点上1.首先将上一章节使用子函数方法的代码复制过来将Nixie( , )移到下方while循环中(因为要实现效果为动态的)void main(){ while(1) { Nixie(1,1); Nixie(2,2); Nixie(3,3); }}编译下载后效果为:对于这种效果要进行消影的处理因为单片机编译处理顺序是按照:位选 段选 (清零),位选 段选 ,位选 段选由上一段的段选到下一部分的位选需要进行清零处理接下来主要进行:增添延时函数和清零处理2.在STC-ISP中生成相应的延时函数,函数时间为1ms,并对其进行灵活修改,
发表于 2022-09-28
<font color='red'>51单片机</font> 动态数码管显示

推荐帖子

【晒样片】+第一次申请TI样片!
哈哈,第一次申请TI的样片,既然成功了,是不是有些小激动,平时用TI的launchpad,还有MSP430F5529的开发板。一直没去申请过样片,这次申请的样片,虽然现在用不到,但可以研究研究,毕竟是第一次嘛!先发个帖子,到时候研究研究相关文档!不多说,先上各种流程图吧! 有童鞋说申请失败,估计是个人相关单位和信息的原因吧,因为本人处于高校,相对好申请一些。PS:我申请了两份样片哇! 下面晒出有EMAIL通知的发货信息哇,还有顺丰快递单的信息,另外还有样片的的图片。 我申请的样片有以
xueyongchao8805 TI技术论坛
适用于便携应用的超薄扬声器
大多数用户都希望能使用既轻薄又寿命长的产品。一种新型扬声器技术(陶瓷扬声器)能使这种梦想成真。制造商可以用这种扬声器制造出像信用卡那样薄的产品。陶瓷与压电扬声器与传统的动圈扬声器有很大的差异。它们表现为一个容性负载,而不是阻性负载。它们需要较高的电压驱动,而不是大电流。传统动圈扬声器的厚度在4mm以上,陶瓷扬声器的厚度只有0.7mm。重量经常低于1g,功耗只有不到5mW。压电扬声器的工作原理压电陶瓷扬声器的工作原理与动圈扬声器完全不同,压电陶瓷扬声器不需要磁铁或线圈。当在压电
fighting 模拟电子
飞思卡尔智能电网解决方案
传一个freescale智能电网的解决方案,他们提供了完整的芯片,和参考设计飞思卡尔智能电网解决方案
bluehacker NXP MCU
有没有在单片之间用红外线通信的? 进来说说方案~~~~~~
我自己搭了个简单的,发送管直接接IO,收接用三极管放大一次,好像能接收,不过数据不正确........郁闷中....... 高手进来说说通常都怎样弄的吧.....有没有在单片之间用红外线通信的?进来说说方案~~~~~~
jiangaayjake 嵌入式系统
求一个单片机型号
需求如下: 1、IO口能直接驱动蜂鸣器,马达; 2、只需要7个IO口; 3、常见的烧录方式。 麻烦大家了。 之前找了一个AT89LP213,各方面都很适合,买了之后硬是没找到怎么烧录... 大概是新手的原因吧,谢谢大家了。 求一个单片机型号
白衣渡江 单片机
请教大麦盒子中的一个电源芯片
上边的那个UP10,芯片上写着CU3ZL(alldatasheetcn.com和ICkey上找了,没有),6脚的 旁边电容式220,电感是4R7,(应该是5v转成3.3v吧) 大麦盒子输入电压5v2A,里边有4个使用UP10的相同的模块(照片中就有3个) CPU是Amlogic8726-MXCortex-A9(百度说的,不确定) 实在没办法了,希望大牛提供点线索,谢谢 请教大麦盒子中的一个电源芯片
lidonglei1 电源技术
小广播
设计资源 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved