标题:
求代码 单片机控制MMC存储卡读写测试源程序+Proteus仿真文件
[打印本页]
作者:
LittleGenius
时间:
2019-3-13 19:23
标题:
求代码 单片机控制MMC存储卡读写测试源程序+Proteus仿真文件
K1:从开始位置开始写入0x00-0xFF, 0x00-0xFF(512字节)
K2:从第512字节位置开始写入512个随机字节
K3:读取前512个字节并显示
K4:读取后512个字节并显示
操作过程中可尝试"热插拨"MMC卡,观察运行效果
MMC存储卡仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
(35.55 KB, 下载次数: 47)
下载附件
2019-3-14 03:38 上传
0.png
(6.84 KB, 下载次数: 54)
下载附件
2019-3-14 03:38 上传
单片机控制MMC存储卡源程序如下:
//-----------------------------------------------------------------
// 名称: MMC卡块读写程序
//-----------------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <absacc.h>
#define INT8U unsigned char
#define INT16U unsigned int
#define INT32U unsigned long
//SPI接口存储器引脚定义
sbit CS = P3^2; //片选
sbit DI = P3^3; //串行数据输入
sbit DO = P3^4; //串行数据输出
sbit CLK = P3^5; //串行时钟控制脚
//MMC卡使能与禁止操作
#define MMC_CS_EN() CS = 0
#define MMC_CS_DI() CS = 1
//MMC卡操作命令帧(6字节,48位)
INT8U cmd[6] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
extern void delay_ms(INT16U);
//块字节读写缓冲
#define Block_Date &XBYTE[0x0000]
#define delay_10us() {_nop_();_nop_();_nop_();_nop_();_nop_();\
_nop_();_nop_();_nop_();_nop_();_nop_();}
//-----------------------------------------------------------------
// 打开SPI
//-----------------------------------------------------------------
void OpenSPI() { CS = 1; CLK = 0; }
//-----------------------------------------------------------------
// 从当前地址读取一字节数据
//-----------------------------------------------------------------
INT8U getcSPI()
{
}
//-----------------------------------------------------------------
// 向当前地址写入一字节数据
//-----------------------------------------------------------------
void putcSPI(INT8U dat)
{
}
//-----------------------------------------------------------------
// MMC命令帧清0
//-----------------------------------------------------------------
void clear_cmd_frame()
{
}
//-----------------------------------------------------------------
// 写MMC命令
//-----------------------------------------------------------------
INT8U MMC_Write_Command(INT8U *cmd_frame)
{
}
//-----------------------------------------------------------------
// MMC初始化
//-----------------------------------------------------------------
INT8U MMC_Initialise()
{
}
//-----------------------------------------------------------------
// 从指定的块地址读取单个块字节数据
//-----------------------------------------------------------------
INT8U MMC_Read_Block(INT32U address)
{
INT16U i;
clear_cmd_frame(); //命令帧清0
cmd[0] = 0x51; //设置CMD17(0x51....0xFF)(读单个块)
cmd[5] = 0xFF;
address = address<<9; //地址<<9位,取512的整数倍
cmd[1] = address>>24; //将address分解到
cmd[2] = address>>16; //四字节的命令帧参数中
cmd[3] = address>>8;
cmd[4] = address>>0;
if(MMC_Write_Command(cmd) != 0x00) return 0; //发送CMD17
while(getcSPI() != 0xFE) _nop_(); //等待数据接受开始(0xFE)
for(i = 0;i < 512; i++) //读取块数据(512字节)
XBYTE[i] = getcSPI();
getcSPI();getcSPI(); //取走2字节的CRC
return 1;
}
//-----------------------------------------------------------------
// 向指定的块地址开始写入单个块字节数据
//-----------------------------------------------------------------
INT8U MMC_Write_Block(INT32U address)
{
INT16U i,Dout;
clear_cmd_frame(); //命令帧清0
cmd[0] = 0x58; //设置CMD24(0x58....0xFF)(写单个块)
cmd[5] = 0xFF;
address = address<<9; //地址<<9位,取512的整数倍
cmd[1] = address>>24; //将address分解到
cmd[2] = address>>16; //四字节的命令帧参数中
cmd[3] = address>>8;
cmd[4] = address>>0;
if(MMC_Write_Command(cmd) != 0x00) return 0; //发送CMD24
putcSPI(0xFF); //发送填冲字节
putcSPI(0xFE); //发送数据开始标志0xFE
//将块读写缓冲Block_bytes中的512字节数据写入MMC
for(i = 0;i < 512; i++) putcSPI(XBYTE[i]);
putcSPI(0xFF); //写入2字节CRC(未计算)
putcSPI(0xFF);
Dout = getcSPI() & 0x1F; //读取返回数据中的低5位
if(Dout != 0x05) return 0; //如果未能读到XXX0 0101则写入失败
while(getcSPI() == 0x00) _nop_(); //忙等待
return 1;
}
复制代码
//-----------------------------------------------------------------
// 名称: MMC存储卡测试
//-----------------------------------------------------------------
// 说明: 本例运行时,按下K1将向MMC卡第0块写入512个有序字节,按下K2时
// 将向第1块写入512个随机字节,按下K3与K4时将分别读取并通过
// 虚拟终端显示这些字节数据.
//
//-----------------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <absacc.h>
#define INT8U unsigned char
#define INT16U unsigned int
#define INT32U unsigned long
//定义按键操作
#define K1_DOWN() !(P1 & (1<<0))
#define K2_DOWN() !(P1 & (1<<2))
#define K3_DOWN() !(P1 & (1<<4))
#define K4_DOWN() !(P1 & (1<<6))
//MMC相关函数
extern void OpenSPI();
extern INT8U MMC_Initialise();
extern INT8U MMC_Read_Block(INT32U address);
extern INT8U MMC_Write_Block(INT32U address);
//串口相关函数
extern void Init_USART();
extern void PutChar(char c);
extern void PutStr(char *s);
INT8U OP = 0; //当前按键操作代号
INT8U ERROR_Flag = 1; //MMC卡操作错误标识(为1表示正常,为0表示出错)
//-----------------------------------------------------------------
// 延时函数
//-----------------------------------------------------------------
void delay_ms(INT16U x) {INT8U t; while(x--) for(t = 0; t<120; t++);}
//-----------------------------------------------------------------
// 以十六进制形式显示所读取的字节
//-----------------------------------------------------------------
void Show_Byte_by_HEX(INT32U Len)
{
INT32U i; char s[] = " ";//字符串初始为三个空格
for (i = 0; i < Len; i++)
{
}
PutStr("\r--------Finished!--------\r");
}
//-----------------------------------------------------------------
// 向串口输出一个字符
//-----------------------------------------------------------------
void PutChar(INT8U c) { SBUF = c; while (TI == 0); TI = 0; }
//------------------------------------------------------------------
// 串口输出字符串
//------------------------------------------------------------------
void PutStr(char *s) { while (*s) PutChar(*s++); }
//-----------------------------------------------------------------
// 串口配置
//-----------------------------------------------------------------
void Init_USART()
{
}
//-----------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------
void main()
{
INT32U i,j;
//SPI,USART初始化
OpenSPI(); Init_USART(); delay_ms(100);
//初始化MMC
PutStr("Initialise MMC, Please Waiting.....");
ERROR_Flag = MMC_Initialise();
if (ERROR_Flag) PutStr("OK!\r\r"); else PutStr("ERROR!\r\r");
//提示进行K1-K4操作
PutStr("Plase Press K1,K2,K3 or K4 to Play MMC Test...\r\r");
//设置随机种子
srand(300);
while(1)
{ while (P1 == 0xFF); //未按键则等待-------------------------
if (K1_DOWN()) { delay_ms(10); if (K1_DOWN()) OP = 1; }
else if (K2_DOWN()) { delay_ms(10); if (K2_DOWN()) OP = 2; }
else if (K3_DOWN()) { delay_ms(10); if (K3_DOWN()) OP = 3; }
else if (K4_DOWN()) { delay_ms(10); if (K4_DOWN()) OP = 4; }
//如果上次MMC出错则重新初始化SPI接口与MMC卡
if (ERROR_Flag == 0) //------------------------------------
{
}
//根据按键操作代号分别进行操作,因为上述可能的重新初始化会耗费较多时间,
//如果在这里仍用K1~K4的DOWN判断,按键可能已经释放,从而导致判断失效.
//因此这里使用的是提前获取的按键操作代号
if (OP == 1) //--------------------------------------------
{
}
else if (OP == 2) //---------------------------------------
{
}
else if (OP == 3) //---------------------------------------
{
}
else if (OP == 4) //---------------------------------------
{
}
next: while (P1 != 0xFF); //等待释放按键-----------------
}
}
复制代码
所有资料51hei提供下载:
50 MMC存储卡测试.zip
(33.82 KB, 下载次数: 39)
2019-3-13 19:23 上传
点击文件名下载附件
作者:
linuxcso
时间:
2019-3-14 09:25
代码不完整,还要找配套的书才可以
作者:
rzh98
时间:
2020-4-17 16:17
请问楼主,mmc映像文件怎么生成的呢
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1