问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何用51单片机通过模拟SPI总线协议读写U盘?或者其他的协议也可以,只要能后操作U盘

发布网友 发布时间:2022-05-27 09:46

我来回答

3个回答

热心网友 时间:2023-10-15 08:54

/*-----------------------------------------------

------------------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include<9325TP.h>
//=============================================================
//定义SD卡需要的4根信号线
sbit SD_CLK = P1^1;
sbit SD_DI = P1^2;
sbit SD_DO = P1^0;
sbit SD_CS = P1^3;
//===========================================================
//定义按键端口
sbit KEY = P3^2;
//===========================================================
//定义512字节缓冲区,注意需要使用 xdata关键字
unsigned char xdata DATA[75]={0};
unsigned char xdata DATA1[75]={0};

//===========================================================
//写一字节到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<len;count++) SdWrite(*Block++);

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 ERROR\n");
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;
}

//=======================================================================
//从SD卡指定地址读取数据,一次最多512字节
unsigned char SdReadBlock(unsigned char *Block, unsigned long address,int len)
{
unsigned int count;
//Block size is 512 bytes exactly
//First Lower SS

//printf("MMC_read_block\n");

SD_CS=0;
//Then send write command
SdCommand(0x11,address,0xff);

if(SdResponse()==00)
{
//command was a success - now send data
//start with DATA TOKEN = 0xFE
while(SdRead()!=0xfe);

for(count=0;count<len;count++) *Block++=SdRead();

for(;count<512;count++) SdRead();

//data block sent - now send checksum
SdRead();
SdRead();
//Now read in the DATA RESPONSE token
SD_CS=1;
SdRead();
return 1;
}
//printf("Command 0x11 (Read) was not received by the MMC.\n");
return 0;
}
/********************************************************************
* 名称 : Com_Init()
* 功能 : 初始化串口程序,晶振11.0592, 波特率9600
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Init(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
//============================================================
//主程序
main()
{

unsigned long AddTemp=262144;//SD卡地址第一个数据物理地址初始值,可以用winhex查看,这里是512扇区,512x512=262144,根据实际SD卡内容更改
unsigned char i;
unsigned char *p;
CS=1;
delayms(5);
RES=0;
delayms(5);
RES=1;
delayms(5);
SdInit(); //SD卡初始化
Com_Init();
for(i=0;i<75;i++)
{
DATA1[i]=i;
}

SdWriteBlock(DATA1, AddTemp, 75);
SdReadBlock(DATA, AddTemp, 75);
p= DATA;
while(1)
for(i=0;i<75;i++)
{
SBUF = *p+48;
while(!TI) //如果发送完毕,硬件会置位TI
{
_nop_();
}
p++;
TI = 0; //TI清零
delayms(500);
}
}

《9325TP.h》
/*-----------------------------------------------
名称:写彩屏
公司:上海浩豚电子科技有限公司
网站:www.doflye.net
编写:师访
日期:2009.12
修改:无
内容:320x240像素、16位BMP图片的HEX数据,依次写到屏上,还原图片
注意事项:
------------------------------------------------*/
#include"reg52.h"
//============================================================
//根据芯片资料定义
#define WINDOW_XADDR_START0x0050 // Horizontal Start Address Set
#define WINDOW_XADDR_END0x0051 // Horizontal End Address Set
#define WINDOW_YADDR_START0x0052 // Vertical Start Address Set
#define WINDOW_YADDR_END0x0053 // Vertical End Address Set
#define GRAM_XADDR 0x0020 // GRAM Horizontal Address Set
#define GRAM_YADDR 0x0021 // GRAM Vertical Address Set
#define GRAMWR 0x0022 // memory write

//=============================================================
//定义液晶屏接口
sbit CS=P2^2;//片选
sbit RES=P2^1;//复位
sbit RS=P2^4;//数据/命令选择
sbit RW=P2^5;
//数据口使用P0
//====================================================//
//函数声明
void ILI9325_Initial(void);
void Write_Cmd_Data(unsigned char x, unsigned int y);
void Write_Cmd(unsigned char DH,unsigned char DL);
void Write_Data(unsigned char DH,unsigned char DL);
void delayms(unsigned int tt);
void Write_Data_U16(unsigned int y);
static void LCD_SetPos(unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1);
void ClearScreen(unsigned int bColor);

//===============================================================
//清屏
void ClearScreen(unsigned int bColor)
{
unsigned int i,j;
LCD_SetPos(0,240,0,320);//320x240
for (i=0;i<320;i++)
{

for (j=0;j<240;j++)
Write_Data_U16(bColor);
}
}

//===============================================================
//写命令数据

void Write_Cmd_Data (unsigned char x,unsigned int y)
{
unsigned char m,n;
m=y>>8;
n=y;
Write_Cmd(0x00,x);
Write_Data(m,n);

}

//==============================================================
//写16位数据
void Write_Data_U16(unsigned int y)
{
unsigned char m,n;
m=y>>8;
n=y;
Write_Data(m,n);

}
//=============================================================
//写命令

void Write_Cmd(unsigned char DH,unsigned char DL)
{

CS=0;
RS=0;

P0=DH;
RW=0;
RW=1;

P0=DL;

RW=0;
RW=1;
CS=1;
}

//===================================================================
//写数据

void Write_Data(unsigned char DH,unsigned char DL)
{

CS=0;

RS=1;
P0=DH;
RW=0;
RW=1;

P0=DL;
RW=0;
RW=1;
CS=1;
}

//============================================================
//延时程序
void delayms(unsigned int count)
{
int i,j;
for(i=0;i<count;i++)
{
for(j=0;j<260;j++);
}
}

//=============================================================
//液晶初始化

void ILI9325_Initial(void)
{

delayms(50); //根据不同晶振速度可以调整延时,保障稳定显示
Write_Cmd_Data(0x0001,0x0100);
Write_Cmd_Data(0x0002,0x0700);
Write_Cmd_Data(0x0003,0x1030);
Write_Cmd_Data(0x0004,0x0000);
Write_Cmd_Data(0x0008,0x0207);
Write_Cmd_Data(0x0009,0x0000);
Write_Cmd_Data(0x000A,0x0000);
Write_Cmd_Data(0x000C,0x0000);
Write_Cmd_Data(0x000D,0x0000);
Write_Cmd_Data(0x000F,0x0000);
//power on sequence VGHVGL
Write_Cmd_Data(0x0010,0x0000);
Write_Cmd_Data(0x0011,0x0007);
Write_Cmd_Data(0x0012,0x0000);
Write_Cmd_Data(0x0013,0x0000);
//vgh
Write_Cmd_Data(0x0010,0x1290);
Write_Cmd_Data(0x0011,0x0227);
//delayms(100);
//vregiout
Write_Cmd_Data(0x0012,0x001d); //0x001b
//delayms(100);
//vom amplitude
Write_Cmd_Data(0x0013,0x1500);
//delayms(100);
//vom H
Write_Cmd_Data(0x0029,0x0018);
Write_Cmd_Data(0x002B,0x000D);

//gamma
Write_Cmd_Data(0x0030,0x0004);
Write_Cmd_Data(0x0031,0x0307);
Write_Cmd_Data(0x0032,0x0002);// 0006
Write_Cmd_Data(0x0035,0x0206);
Write_Cmd_Data(0x0036,0x0408);
Write_Cmd_Data(0x0037,0x0507);
Write_Cmd_Data(0x0038,0x0204);//0200
Write_Cmd_Data(0x0039,0x0707);
Write_Cmd_Data(0x003C,0x0405);// 0504
Write_Cmd_Data(0x003D,0x0F02);
//ram
Write_Cmd_Data(0x0050,0x0000);
Write_Cmd_Data(0x0051,0x00EF);
Write_Cmd_Data(0x0052,0x0000);
Write_Cmd_Data(0x0053,0x013F);
Write_Cmd_Data(0x0060,0xA700);
Write_Cmd_Data(0x0061,0x0001);
Write_Cmd_Data(0x006A,0x0000);
//
Write_Cmd_Data(0x0080,0x0000);
Write_Cmd_Data(0x0081,0x0000);
Write_Cmd_Data(0x0082,0x0000);
Write_Cmd_Data(0x0083,0x0000);
Write_Cmd_Data(0x0084,0x0000);
Write_Cmd_Data(0x0085,0x0000);
//
Write_Cmd_Data(0x0090,0x0010);
Write_Cmd_Data(0x0092,0x0600);
Write_Cmd_Data(0x0093,0x0003);
Write_Cmd_Data(0x0095,0x0110);
Write_Cmd_Data(0x0097,0x0000);
Write_Cmd_Data(0x0098,0x0000);
Write_Cmd_Data(0x0007,0x0133);

//Write_Cmd_Data(0x0022);//
}

//===============================================================
//定义坐标
static void LCD_SetPos(unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1)
{
Write_Cmd_Data(WINDOW_XADDR_START,x0);
Write_Cmd_Data(WINDOW_XADDR_END,x1);
Write_Cmd_Data(WINDOW_YADDR_START,y0);
Write_Cmd_Data(WINDOW_YADDR_END,y1);
Write_Cmd_Data(GRAM_XADDR,x0);
Write_Cmd_Data(GRAM_YADDR,y0);
Write_Cmd (0x00,0x22);//LCD_WriteCMD(GRAMWR);
}

热心网友 时间:2023-10-15 08:54

您可以看看西安达泰电子的USB118AD 提供TTL串口和SPI口。可以对U盘进行读写操作。

热心网友 时间:2023-10-15 08:55

您给的分也太少了。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
找专业防水队做完还漏水怎么维权 法院会受理房屋漏水造成的纠纷吗? 巴西龟最长活多久,家养!!! 养胃的药最好的是什么啊 婴儿积食发烧不愿吃药怎么办 板门穴位在哪个部位 手机设置放偷看的方法? 凝结水回收器生产厂家? 个人账户养老金预测公式:现有5万元,缴费20年,能领多少钱? 临沂比较有名的男装品牌 床要多高才合适 侦探公司能不能通过就能查到别人半年的聊天记录 请问,同一个二台手机怎样能看到另一台手机微信的聊天记录? 手腕的厉害 不能弯 还有个疙瘩怎么回事? 14岁孩子手腕上有一个疙瘩是怎么会事 手腕上长了个疙瘩,大概快有一年了,这是什么,怎么处理 联邦快递在安徽六安市的分部的联系电话是多少? 安徽合肥庐阳区速尔快递联系电话是多少 安徽五河县有申通快递吗电话是多少 怎么收费的上门吗 安徽淮南的EMS物流的电话号码 安徽新华学院磨店这边的顺丰快递电话是多少 裕安区固镇镇韵达快递公司位置在哪里电话号码是多少? 计算机三级具体考什么内容?什么时候考? 安徽省宿州市萧县杜楼镇申通快递联系电话是多少 计算机三级考试时间 安徽省马鞍山市韵达快递电话号码是多少啊? 安徽省、淮南市,申通快递公司的电话号码? 安徽省合肥市瑶海区芳邻家园菜鸟快递站电话号码多少呢 安徽阜南申通快递电话号码 急!请问安徽省宣城市几个快递公司的电话号码! 床要怎么样安朝什么方向 什么螺旋藻最好? 螺旋藻哪个品牌好?有什么建议的吗? 螺旋藻有那些品牌比较好? 丽江螺旋藻什么牌子最好? 螺旋藻的牌子 是程海的好还是绿A的好? 魏汝注册过商标吗?还有哪些分类可以注册? 关于螺旋藻 康大夫的和程海牌以及程海湖牌的哪个好? 和姓中有没有名人,都是做什么的? 早晨,妈妈给我准备一杯牛奶, 两个鸡蛋. 600字作文 绿A和汤臣倍健的螺旋藻哪个效果好?你们知道这两个品牌吗? 河北秦皇岛SEO魏汝要是哪个 山东省阳谷县魏氏族谱上最后五位的字辈 是 承、汝、全、奕、良,有和我们相同的吗? 妈妈为我准备早餐的细节描写 姓和的历史人物 平利县的行政区划 笔记本一摔,就黑屏了额! 宏基 求大家帮帮忙.. 岳飞手下的哪个悍将在第二次北伐的时候,勇猛不亚于张飞? 世界伟人排名前100位 魏杞和魏征什么关系? 是一个族的不?