我用的是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;
}
|