View previous topic :: View next topic |
Author |
Message |
di3e
Joined: 12 Apr 2008 Posts: 3
|
mmc_init & proteus |
Posted: Thu Sep 11, 2008 2:31 pm |
|
|
Hi all ,
I want to use mmc_spi for read and write to mmc ,
But mmc_init didn't return zero in proteus 7.2 sp2 ,
please help me ,Thanks a lot . |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Sep 11, 2008 2:52 pm |
|
|
You must be doing something wrong.
Sorry, but we can't read your mind so you need to provide more details:
- What is your compiler version number?
- Which PIC processor?
- Clock frequency?
- What voltage is your PIC running at?
- Which MMC driver are you using? If it is not a standard CCS library then post a link to the source.
- How did you connect the MMC card to the PIC?
- Do you have the pull-up resistors connected to the SDI and SDO lines? What value?
- etc. |
|
|
di3e
Joined: 12 Apr 2008 Posts: 3
|
|
Posted: Fri Sep 12, 2008 11:20 am |
|
|
Hi , Thank you ckielstra to answer.
I am using PCWHD compiler version 4.065 and PIC18F452 with a 20MHz external Oscillator.
I PIC running on 5 v
I use standard CCS library mmcsd.c
I am going to read and write ( a byte -- n bytes -- a block ) on MMC
connecting below
Code: |
Pin PIC
|
---
| |
| | 1k8
| |
---
|
|------ to MMC
|
---
| |
| | 3k3
| |
---
|
---
- |
Code:
Code: |
#include <18f452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
char c=0x00;
char Cmd=0x00;
int8 MMCBuffer[512];
int32 address=0;
#use fast_io(c)
#define MMCSD_PIN_SELECT PIN_C2
#define MMCSD_PIN_SCL PIN_C3
#define MMCSD_PIN_SDI PIN_C4
#define MMCSD_PIN_SDO PIN_C5
#include <mmcsd.c>
///////////////////////////////////////////////////////////////////////////////
#int_rda
void input_int(){
if(kbhit()){
c=getc();
if(c!=0x00) Cmd=toupper(c);
}
}
///////////////////////////////////////////////////////////////////////////////
void main() {
int16 f=0;
int16 size=512;
int8 col=0;
disable_interrupts(global);
disable_interrupts(int_rda);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
port_b_pullups(false);
set_tris_c(0b10010000);
enable_interrupts(global);
enable_interrupts(int_rda);
printf("\r\n\nCommands available:\r\n\n");
printf("[M] Init MMC Card\r\n");
printf("[R] Read MMC Card Block First\r\n");
do {
if(Cmd!=0x00) {
if(Cmd=='M') {
if(mmcsd_init()==0) printf("MMC init ok\r\n>");
else printf("MMC init fault\r\n>");
}
if(Cmd=='R') {
address=0;
for(f=0;f<=511;f++) MMCBuffer[f]=0;
size=511;
col=0;
if(mmcsd_read_block(address,size,&MMCBuffer[0])== 0) {
printf("\r\n>MMC read ok from Address %LX to %LX\r\n",address,address+size);
for(f=0;f<=511;f++){
printf("%X ",MMCBuffer[f]);
if(++col==16){
col=0;
printf("\r\n");
}
}
}
else printf("\n\rread fault\r\n>");
}
Cmd=0x00;
}
} while (TRUE);
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Sep 12, 2008 1:02 pm |
|
|
There is a bug in the spi setup in mmcsd.c of v4.065. Read my post in this thread.
Your hardware has a problem with the 3.3 to 5V conversion. The 5V to PIC with voltage divider will work, but the other way around the 3.3V to PIC won't. The SPI input pin C4 is of the Schmitt Trigger type and requires a minimum voltage of 0.7 * Vdd = 3.5V. You are out of specifications.
A simple solution is to lower the voltage of the PIC the PIC18F452 can be run stable at a voltage as low as 4.2V which lowers the Vih of pin C4 to 2.94V. Don't forget to adapt your voltage divider for the output to the MMC.
Or use the PIC18LF452 which can be run at the same voltage as the MMC card. Saves power and you can get rid of the voltage divider to the MMC.
You didn't answer my question on the pull-up resistors for the SDI and SDO lines. |
|
|
di3e
Joined: 12 Apr 2008 Posts: 3
|
|
Posted: Sat Sep 13, 2008 12:57 pm |
|
|
Excuse me, I forget to answer your last question, I don't use pull-up for the SDI and SDO lines.
I connect the DO of MMC to SDI pin of PIC directliy, But I use for other pins with voltage divider.
I changed that line of mmcsd.c that you point out it, But the compiler give me this error :
Option invalid Not valid for H/W. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Sep 15, 2008 5:36 pm |
|
|
di3e wrote: | I don't use pull-up for the SDI and SDO lines. | You should have 100k pull-ups on the SDI and CLK lines. The MMC card starts up in an open collector mode and without these pull-ups it won't work.
Quote: | I connect the DO of MMC to SDI pin of PIC directliy, But I use for other pins with voltage divider. | The voltage divider for the other pins is OK, but like I explained the direct connection from DO of the MMC to PIC is wrong. The high voltage level of the MMC is too low for a PIC running at 5V. Proteus doesn't care but a real PIC will fail. Use a real power level converter or lower the PIC voltage to 4.2V Even easier, use a LF version of the PIC that can run at 3.3V and no voltage conversion is required at all.
Quote: | I changed that line of mmcsd.c that you point out it, But the compiler give me this error :
Option invalid Not valid for H/W. | I don't have v4.065 but for me it compiles in both v4.057 and 4.077. You will get this error message if you changed the pin numbers so they don't map onto the SPI hardware pins. The configuration as you have posted above compiles for me. Code: | #define MMCSD_PIN_SELECT PIN_C2
#define MMCSD_PIN_SCL PIN_C3
#define MMCSD_PIN_SDI PIN_C4
#define MMCSD_PIN_SDO PIN_C5 |
I found an omission in the CCS driver. The CCS code does not send the MMC card startup sequence (a series of 74 or more clock pulses). In Proteus you can easily work around this by selecting the MMC module and disable the option 'Require SPI Init Sequence'. |
|
|
|