我用的是C8051F350单片机,完成AD转换后需要将采集数据存储到SD卡用的是SPI模式,但是再初始化过程中返回命令总是不对,请哪位懂的,帮我看看,非常谢谢您!以下是我的代码:
#include <C8051F350.h> // SFR declarations
#include <stdio.h>
sfr16 TMR2RL = 0xCA; // Timer2 reload value
sfr16 TMR2 = 0xCC; // Timer2 counter
sfr16 ADC0DEC = 0x9A;
#define SYSCLK 24500000
#define MDCLK 2457600
#define OWR 20
#define BAUDRATE 9600//115200
#define SPI_CLOCK 500000
sbit CS=P0^6;
void Oscillator_Init (void);
void Port_Init (void);
void UART0_Init (void);
void ADC0_Init(void);
void SPI0_Init (void);
void Reset_SD_Card(void);
void Init_SD_Card(void);
void Write_SD_Card(unsigned long addr,unsigned char *Buffer);
void Delay(void);
void Init_Device (void);
unsigned char SPI_Read (void);
unsigned char Reset_R1,Init_comdata,Write_middle_R1,Write_R1;
unsigned char *data_tst;
void main()
{
unsigned i,j=0,k=0;
unsigned long Laddr=0x00000001;
char xdata sample[512];
PCA0MD&=~0X40;
Init_Device ();
/* printf("c");
do
{
Init_SD_Card();
Delay();
}
while(Init_comdata!=0x00); */
EA=1;
printf("\nMeasurements using the 24-bit ADC in C8051F350\n");
printf("\nCalibrating ...\n");
EIE1&=~0x08;
ADC0MD|=0x01;
while(!AD0CALC);
ADC0MD&=0x07;
printf("Calibration complete\n\n");
AD0INT=0;
ADC0MD=0x83;
// Reset_SD_Card();
while(1)
{
printf ("Collecting 512 samples...\n");
for (i = 0; i < 128; i++)
{
while(!AD0INT); // wait till conversion complete
AD0INT = 0; // clear AD0 interrupt flag
sample[j++]=ADC0H;
sample[j++]=ADC0M;
sample[j++]=ADC0L;
sample[j++]=0X00;
}
for(k=0;k<512;k++)
printf ("SAMPLE%d:%bx\n",k,sample[k]);
data_tst=sample;
Reset_SD_Card();
printf("a");
do
{
Init_SD_Card();
printf("b");
Delay();
}
while(Init_comdata != 0x00);
Write_SD_Card(Laddr,data_tst);
Laddr++;
AD0INT=0;
i=0;
}
}
void Init_Device (void)
{ Port_Init ();
Oscillator_Init ();
UART0_Init ();
ADC0_Init();
SPI0_Init();
}
void Oscillator_Init (void)
{
OSCICN = 0x83;
RSTSRC = 0x04;
}
void Port_Init (void)
{
P0MDOUT=0X55;
P0SKIP=0X40;
/* P1MDOUT=0Xff;
P1SKIP=0Xff;*/
XBR0=0X03;
XBR1=0X40;
}
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON |= 0x08; // T1M = 1; SCA1:0 = xx
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x01;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else if (SYSCLK/BAUDRATE/2/256 < 48) {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
} else {
while (1); // Error. Unsupported baud rate
}
TL1 = TH1; // Init Timer1
TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
}
void ADC0_Init (void)
{
ADC0CN=0x00;
ADC0CF=0x04;
ADC0CLK=(SYSCLK/MDCLK)-1;
ADC0DEC = ((unsigned long) MDCLK / (unsigned long) OWR /
(unsigned long) 128) - 1;
ADC0BUF = 0x00;
ADC0MUX = 0x28;
REF0CN |= 0x03;
ADC0MD=0x81;
while(AD0CALC != 1); // Wait until calibration is complete
EIE1 |= 0x08; // Enable ADC0 Interrupts
ADC0MD = 0x80; // Enable the ADC0 (IDLE Mode)
}
void SPI0_Init()
{
SPI0CFG = 0x70; // Enable the SPI as a Master ,SCK在空闲状态时处于高电平
//SPI0CFG = 0x50; // CKPHA = '0', CKPOL = '1'
SPI0CN = 0x01; // 3 wire Single Master, SPI enabled
// SPI clock frequency equation from the datasheet
SPI0CKR = (SYSCLK/(2*SPI_CLOCK))-1;
ESPI0 = 1; // Enable SPI interrupts
}
unsigned char SPI_Read (void)
{
SPIF = 0;
return SPI0DAT;
}
void SPI_ISR (void) interrupt 6
{
}
void Delay (void)
{
unsigned char count;
for (count = 100; count > 0; count--);
}
void Reset_SD_Card(void)
{
unsigned char i;
ESPI0 = 0; //关闭发送中断
CS = 1;
for(i=0;i<0x0f;i++) //输出74个以上时钟周期
{
SPI0DAT = 0xff; // Load the data into the buffer
while (TXBMT != 1); // Wait until the data is moved into XBMT buffer
}
Delay();
CS = 0; //开片选
Delay();
SPI0DAT = 0x40; //CMD0
while(TXBMT != 1);
Delay();
SPI0DAT = 0x00; //输出8*4个clocks
while(TXBMT != 1);
SPI0DAT = 0x00;
while(TXBMT != 1);
SPI0DAT = 0x00;
while(TXBMT != 1);
SPI0DAT = 0x00;
while(TXBMT != 1);
Delay();
SPI0DAT = 0x95; //crc
while(TXBMT != 1);
Delay();
SPI0DAT = 0xff; //8× multiples of 8 clocks Ncr
while(TXBMT != 1);
SPI0DAT = 0xff;
while(TXBMT != 1);
Delay();
Reset_R1 = SPI0DAT; //读接受数据缓冲区,清空接收数据缓冲区,这样让sd卡响应数据可以顺利接收
SPI0DAT = 0xff; //输出dummy时钟周期,让sd卡响应字节进入接受缓冲区
while(TXBMT != 1);
CS = 1; //关片选
Reset_R1 = SPI0DAT; //读出响应数据
SPI0DAT = 0xff;
while(TXBMT != 1);//确保操作完成
SPIF = 0; //清中断标志位
ESPI0 = 1; //开发送中断
}
//------------------------------------
//初始化 sd卡
//------------------------------------
void Init_SD_Card(void)
{
unsigned char i;
ESPI0 = 0; //关闭发送中断
/*SPI0DAT = 0xff;
while(TXBMT != 1);
SPI0DAT = 0xff;
while(TXBMT != 1);*/
CS = 0; //开片选
Delay();
SPI0DAT = 0x41; //CMD1
while(TXBMT != 1);
Delay();
SPI0DAT = 0x00; //输出8*4个clocks
while(TXBMT != 1);
SPI0DAT = 0x00;
while(TXBMT != 1);
SPI0DAT = 0x00;
while(TXBMT != 1);
SPI0DAT = 0x00;
while(TXBMT != 1);
Delay();
SPI0DAT = 0xff; //crc
while(TXBMT != 1);
Delay();
SPI0DAT = 0xff; //8× multiples of 8 clocks Ncr
while(TXBMT != 1);
SPI0DAT = 0xff;
while(TXBMT != 1);
Delay();
Init_comdata = SPI0DAT;
Delay();
i = SPI0DAT; //读接受数据缓冲区,清空接收数据缓冲区,这样让sd卡响应数据可以顺利接收
SPI0DAT = 0xff; //输出dummy时钟周期,让sd卡响应字节进入接受缓冲区
while(TXBMT != 1);
CS = 1; //关片选
Init_comdata = SPI0DAT;
SPI0DAT = 0xff;
while(TXBMT != 1);
SPIF = 0; //清中断标志位
ESPI0 = 1; //开发送中断
}
void Write_SD_Card(unsigned long addr,unsigned char *Buffer )
{
unsigned int i;
unsigned char CMD[6]={0x58,0x00,0x00,0x00,0x00,0xff};
unsigned char a,b,c,d;
addr=addr<<9;
a=((addr&0xff000000)>>24);
b=((addr&0x00ff0000)>>16);
c=((addr&0x0000ff00)>>8);
d=((addr&0x000000ff)>>0);
ESPI0=0;
CS = 0;
Delay();
SPI0DAT=0x58;
while(TXBMT!=1);
Delay();
SPI0DAT=a;
while(TXBMT!=1);
SPI0DAT=b;
while(TXBMT!=1);
SPI0DAT=c;
while(TXBMT!=1);
SPI0DAT=d;
while(TXBMT!=1);
Delay();
SPI0DAT=0xff;
while(TXBMT!=1);
Delay();
SPI0DAT = 0xff; //8× multiples of 8 clocks Ncr
while(TXBMT != 1);
SPI0DAT = 0xff;
while(TXBMT != 1);
Delay();
do{
Write_middle_R1=SPI0DAT;
SPI0DAT=0xff;
while(TXBMT!=1);
printf("SPI0DAT:%bx\n",Write_middle_R1);
}while(Write_middle_R1!=0x00);
Delay();
SPI0DAT = 0xff; //8×multiples of 8 clocks Nwr
while(TXBMT != 1);
SPI0DAT = 0xff;
while(TXBMT != 1);
Delay();
SPI0DAT = 0xfe; //start byte
while(TXBMT != 1);
for(i=0;i<512;i++)
{
SPI0DAT = *(Buffer++);
while(TXBMT != 1);
}
SPI0DAT = 0xff; //crc don't care
while(TXBMT != 1);
SPI0DAT = 0xff;
while(TXBMT != 1);
Delay();
do
{
Write_R1 = SPI0DAT;
SPI0DAT = 0xff; //输出dummy clocks,得到sd卡响应
while(TXBMT != 1);
}
while((Write_R1 & 0x1f) != 0x05);
SPI0DAT = 0xff; //8×multiples of 8 clocks
while(TXBMT != 1);
SPI0DAT = 0xff;
while(TXBMT != 1);
Delay();
CS = 1;
Delay();
SPI0DAT = 0xff;
while(TXBMT != 1);
SPIF = 0;
ESPI0 = 1;
}