📄 mmc.c.txt
字号:
/* PIC MMC Interface Test http://www.captain.at/electronics/ Writes ASCII characters to the MMC, reads them back and sends the characters to the linux machine via the serial port. Use "serterm" for testing: # ./serterm baud=9600 baud=9600 listening... PIC online MMC online 0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcde fghijklmno0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmno01 23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmno0123456789:;<= >?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnoCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCC [more C's follow] exiting... Furthermore the PIC returns any character sent to it via the interrupt service routine. Use "ser" for testing: # ./ser baud=9600 baud=9600 written:ABC readport=ABC # Compile with CC5x: http://www.bknd.com/cc5x/ c:\picc\cc5x mmc.c -Ic:\picc\ -ammc.ASM -u CC5x runs nicely on Linux with "dosemu" http://www.dosemu.org/ Credit: SPI functions made by Michael Dworkin http://home.wtal.de/Mischka/MMC/*/#include <16F876.h>#include "int16CXX.H" // interrupt stuff#define CP_off |= 0x3F30#define LVP |= 128#pragma config CP_off,PWRTE=on,WDTE=off,FOSC=HS,BODEN=on,LVP#pragma bit CS @ PORTC.2 // output pin for chip select (MMC)#pragma rambank 0char sector1[64];int currentrambank;int counter;#pragma rambank 1char sector2[64];#pragma rambank 2char sector3[64];#pragma rambank 3char sector4[64];#pragma origin 4 // force interrupt service routine at address 4interrupt myInterrupt(void) // ISR{ int_save_registers char rec; if (RCIF) // USART interrupt ? { while(!TXIF) { // wait for serial register to be sent, if there is still something in there nop(); } rec = RCREG; // Get the received character
TXREG = rec; // write to serial register -> start transmission
RCIF = 0; // clear USART int flag } int_restore_registers}void InitUSART(){ PORTA = 0; PORTB = 0; PORTC = 0; BRGH = 1; // high speed serial mode SPBRG = 25; // Set 9600 baud for 4 MHz oscillator SYNC = 0; // Clear SYNC bit -> Set ASYNC Mode SPEN = 1; // Set serial port enable TX9 = 0; // 8-bit transmissions TXEN = 1; // Enable transmission RCIE = 1; // Rx interrupts are desired RX9 = 0; // 8-bit receptions CREN = 1; // Enable reception}
void initint() // init interrupts{ GIE = 1; // Set Global Interrupt Enable
PEIE = 1; // Set Peripheral Interrupt Enable
}void fillram() // fill RAM (sector1..4) with ASCII characters{ int i; int x; for (i=0;i<=63;i++) { x = i + 48; sector1[i] = x; sector2[i] = x; sector3[i] = x; sector4[i] = x; }}char SPI(char d) // send character over SPI{ SSPBUF = d; // send character while (!BF); // wait until sent return SSPBUF; // and return the received character}char Command(char befF,uns16 AdrH,uns16 AdrL,char befH ){ // sends a command to the MMC char a; SPI(0xFF); SPI(befF); SPI(AdrH.high8); SPI(AdrH.low8); SPI(AdrL.high8); SPI(AdrL.low8); SPI(befH); SPI(0xFF); return SPI(0xFF); // return the last received character}bit MMC_Init() // init SPI{ SMP = 0; // input is valid in the middle of clock CKE = 0; // rising edge is data capture CKP = 1; // high value is passive state SSPM1 = 1; // speed f/64(312kHz), Master SSPEN = 1; // enable SPI CS = 1; // disable MMC char i; // start MMC in SPI mode for(i=0; i < 10; i++)SPI(0xFF); // send 10*8=80 clock pulses CS=0; // MMC-Enabled if (Command(0x40,0,0,0x95) !=1) goto mmcerror; // Reset MMCst: // if there is no MMC, prg. loops here if (Command(0x41,0,0,0xFF) !=0) goto st; return 1;mmcerror: return 0;}void serialterminate() { // terminate sent string!!! while(!TXIF); TXREG = 0x0d; while(!TXIF); TXREG = 0x0a;}void SerString(const char *str) // send string via RS232{ char ps; ps = *str; // pointer of start of string into ps while(ps>0) // test if end of string is reached { str++; // set pointer to next char if (ps== 0) break; // test if end of string is reached while(!TXIF); // test if TXREG empty TXREG = ps ; // send character ps = *str; // content of pointer into ps } serialterminate();}bit writeramtommc() // write RAM (sector1..4) to MMC{ // 512 byte-write-mode if (Command(0x58,0,512,0xFF) !=0) { SerString("MMC: write error 1 "); return 1; } SPI(0xFF); SPI(0xFF); SPI(0xFE); uns16 i; // write ram sectors to MMC for (i=0;i<=63;i++) { SPI(sector1[i]); } for (i=0;i<=63;i++) { SPI(sector2[i]); } for (i=0;i<=63;i++) { SPI(sector3[i]); } for (i=0;i<=63;i++) { SPI(sector4[i]); } for (i=0;i<256;i++) { // fill rest with 'C' SPI('C'); } SPI(255); // at the end, send 2 dummy bytes SPI(255); i = SPI(0xFF); i &= 0b.0001.1111; if (i != 0b.0000.0101) { SerString("MMC: write error 2 "); return 1; } while(SPI(0xFF) != 0xFF); // wait until MMC is not busy anymore return 0;}bit sendmmc() // send 512 bytes from the MMC via the serial port{ uns16 i; // 512 byte-read-mode if (Command(0x51,0,512,0xFF) !=0) { SerString("MMC: read error 1 "); return 1; } while(SPI(0xFF) != 0xFE); // wait for 0xFE - start of any transmission for(i=0; i < 512; i++) { while(!TXIF); // wait until TXREG is empty TXREG = SPI(0xFF); // get MMC byte and send via RS232 } serialterminate(); SPI(0xFF); // at the end, send 2 dummy bytes SPI(0xFF); return 0;}void main(void)
{ InitUSART(); // initialize serial port initint(); // initialize interrupts ADCON1=0x6; // PortA Digital // set ports for I/O TRISC = 0b.1101.0011; // sck rc3-0, sdo rc5-0, CS rc2-0. TRISB = 0b.0000.0010; // RB2>TX, RB1>RX SerString("PIC online "); // start message// SerString(0x00); // start message // init MMC and send message if ok if (MMC_Init()) SerString("MMC online "); fillram(); // fill the RAM with ASCII characters writeramtommc(); // write RAM to MMC sendmmc(); // send 512 bytes of the MMC via serial port
while(1) { nop(); nop(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -