最近假期在家里玩51单片机,看到有大神做了用51单片机和12864和SD卡模块来播放bad apple 【一个视频】觉得很厉害
自己就想也来尝试下,现在程序弄好了,SD卡程序是在网上找参考别人的。但是并没有用,也不懂错在哪里,问了别人
别人用这个程序是可以实现的,可是我自己就不行 想求各位大神解答一下。另外想问下SD卡模块的 MOSI,MISO是分别
对应DO和DI么?
目前程序烧进去,屏幕就显示乱码。插不插SD卡都是现实乱码
然后程序是这样。。。求大神帮看看哪里有错
#include <reg52.h>
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
uint i=0;
uchar ints; //初始化变速标志
sbit lcden=P2^7;
sbit lcdrw=P2^5;
sbit lcdrs=P2^6;
sbit rst=P2^4;
sbit psb=P2^2; //串/并方式控制
sbit cs =P1^7; //片选
sbit di =P1^6; //SD卡数据输入 mosi
sbit clk=P1^5; //时钟
sbit d0=P1^4; //SD卡数据输出 miso
uchar xdata table[1024]; //设置片外指针
//错误代码//
#define cmd0 0x01 //复位错误
#define cmd1 0x02 //初始化错误
#define sdw 0x03 //sd写错误
#define sdr 0x0f //sd读错误
void delay(uchar z) //LCD延时
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay2(uint z)
{
while(z--);
}
/*****************并行基本函数*******************/
void lcd_busy(void) //忙检测
{
uchar busy;
lcdrs=0;lcdrw=1;
do{
lcden=1;
delay2(16);
/*_nop_();
_nop_();*/
busy=P3;
delay2(15);
/*_nop_();
_nop_();*/
lcden=0;
}while(busy&0x80);
}
void write_com(uchar com)
{
lcd_busy();//测忙
lcdrs=0;
lcdrw=0;
P3=com;
lcden=1;
_nop_();
_nop_();
//delay2(1);
lcden=0;
}
void write_data(uchar date)
{
lcd_busy();//测忙
lcdrs=1;
lcdrw=0;
P3=date;
lcden=1;
_nop_();
_nop_();
//delay2(1);
lcden=0;
}
void init(void) //初始化函数
{
rst=1;
psb=1;
delay(10);
write_com(0x30);//基本指令集
delay(10);
write_com(0x0c);//显示ON,游标OFF,游标位置OFF
delay(10);
write_com(0x01);//清除显示
delay(10);
}
void T_display(uchar *p) //图片数据提取函数
{
uchar x,y,a,b,c;
//write_com(0x34); //关闭绘图功能
x=0x88;//设置水平坐标X
y=0x80;//设置垂直坐标Y
for(c=0;c<2;c++)
{
for(a=0;a<32;a++)
{
write_com(y+a);
write_com(x);
for(b=0;b<16;b++)
write_data(*p++); //写入8位数据
}
x=0x80;//转换半屏
}
//write_com(0x36); //打开绘图功能
//write_com(0x30);
}
void QP() //清除DDRAM的数据:送入0
{
uchar x,y,a,b,c;
x=0x80;
y=0x80;
write_com(0x34);//关闭绘图功能
for(a=0;a<2;a++)
{ for(b=0;b<32;b++)
{
write_com(y+b);
write_com(x);
for(c=0;c<16;c++)
write_data(0x00);
}
x=0x88;
}
write_com(0x36);//打开绘图功能
write_com(0x30);
}
//***************************************************************************************//
//*********************************spi驱动**********************************************//
void spi_w(uchar dat) //写数据
{
unsigned char i;
for(i=8;i;i--)
{
clk=0;
if(dat&0x80)
d0=1;
else
d0=0;
dat<<=1;
clk=1;
}
d0=1;
}
uchar spi_r(void) //读数据
{
unsigned char n,j;
for(j=8;j;j--)
{
clk=0;
delay2(40);
clk=1;
delay2(40);
n<<1;
if(di) n |= 1;
}
return (n);
}
//*********************************spi驱动**********************************************//
//***************************************************************************************//
//***************************************************************************************//
//*********************************SD卡驱动**********************************************//
uchar sd_com(uchar *com)
{
uchar i,temp,time=0;
cs=1; spi_w(0xff); cs=0;
for(i=0;i<0x06;i++) //写命令
{
spi_w(*com++);
}
spi_r();
do
{
temp=spi_r(); //读到有返回
time++;
} while((temp==0xff)&&(time<100));
return(temp);
}
uchar sd_reset()
{
uchar time,temp,i;
uchar cmd[]={0x40,0x00,0x00,0x00,0x00,0x95};
ints=1;//开启初始化延时
cs=1;
for(i=0;i<20;i++)//至少74个时钟
{spi_w(0xff);}
cs=0;
time=0;
do //写cmd0
{
temp=sd_com(cmd);
time++;
if(time>=200)
{return(0x01); }
}while(temp!=0x01);
cs=1;
spi_w(0xff);
return 0;
}
uchar sd_int()
{
uchar time,temp;
uchar cmd[]={0x41,0x00,0x00,0x00,0x00,0xff};
cs=0;
time=0;
do
{
temp=sd_com(cmd);
time++;
if(time==100)
{return(0x02);}
}while(temp!=0) ;
ints=0;
cs=1;
spi_w(0xff);
return 0;
}
uchar sd_r(unsigned long add,uchar *buf)
{
uchar time,temp;
uint j;
uchar cmd[]={0x51,0x00,0x00,0x00,0x00,0xff};//cmd17
add<<=9;// 等于add*512 扇区地址转换为字节地址
cmd[1]=((add&0xff000000)>>24);
cmd[2]=((add&0x00ff0000)>>16);
cmd[3]=((add&0x0000ff00)>>8);
cs=0;
time=0;
do
{
temp=sd_com(cmd);
time++;
if(time==100)
{return(1);}
} while(temp!=0); //说明命令写入成功
while(spi_r()!=0xfe);//读到数据的开头
for(j=0;j<512;j++)
{
*buf++ = spi_r();
}
spi_r();
spi_r();//读2个CRC
cs=1;
spi_w(0xff);
return (0);
}
//*********************************SD卡驱动**********************************************//
//***************************************************************************************//
void main()
{
uint pic;
unsigned long add=512;//定义扇区地址
sd_reset();//SD卡复位
sd_int(); //SD卡初始化
init(); //12864初始化
QP(); //12864清屏
for(pic=0;pic<8000;pic++) //一共xxx张图
{
sd_r(add++,table);
sd_r(add++,table+512);//读取两个扇区1024字节
write_com(0x36);//开启绘图
T_display(table);
if(pic<780)delay(45);
if(pic>780&&pic<1200)delay(50);
if(pic>1200&&pic<1600)delay(60);
if(pic>1600&&pic<2000)delay(50);
if(pic>2000&&pic<2300)delay(55);
if(pic>2300)delay(50);
if(pic)delay(60);
}
while(1);
}
此帖出自
小平头技术问答
一周热门 更多>