
	processor  16F690

	list      p=16F690           ; list directive to define processor
	#include <p16F690.inc>        ; processor specific variable definitions

	errorlevel  -302              ; suppress message 302 from list file


	__CONFIG   _CP_OFF & _CPD_OFF & _BOR_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _FCMEN_OFF & _IESO_OFF 

	radix  DEC

TRISB       EQU   0x86
INTCON      EQU   0x0B
Carry       EQU   0
Zero_       EQU   2
RP0         EQU   5
RP1         EQU   6
SSPBUF      EQU   0x13
TXREG       EQU   0x19
TRISC       EQU   0x87
SPBRG       EQU   0x99
ADCON1      EQU   0x9F
EEDATA      EQU   0x10C
EEADR       EQU   0x10D
EEDATH      EQU   0x10E
EEADRH      EQU   0x10F
TXIF        EQU   4
SSPM1       EQU   1
CKP         EQU   4
SSPEN       EQU   5
CREN        EQU   4
RX9         EQU   6
SPEN        EQU   7
RCIE        EQU   5
BF          EQU   0
CKE         EQU   6
SMP         EQU   7
BRGH        EQU   2
SYNC        EQU   4
TXEN        EQU   5
TX9         EQU   6
RD          EQU   0
EEPGD       EQU   7
CS          EQU   5
str         EQU   0x22
ps          EQU   0x23
d           EQU   0x2A
befF        EQU   0x23
AdrH        EQU   0x24
AdrL        EQU   0x26
befH        EQU   0x28
i           EQU   0x22
i_2         EQU   0x20
ci          EQU   0x24

	

  ; FILE D:\moi\16F877\MMC-Algem\mmc-Alg.c
			;
			;#include <D:\cc5\16F877.H>
			;// Speihersutz121345=aus,Debug11=aus,ProgrammFlash9=an,EEpromRead8=an,NiendervoltProgr7=aus
			;// NiederVoltReset6=an,EinschaltTimer3=an,WachDogTimer2=aus,Oszilator01=XC
			;#pragma config |= 0b.11.111101.11.00.10
			;#pragma bit CS @ PORTC.2 //Ausgang für Chip Select
			;
			;#pragma origin 100
	ORG 0x0005
			;//*********************************************************************
			;
			;void InitUSART()
			;{
	GOTO main
_const1
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF ci
	MOVLW .0
	BSF   STATUS,RP1
	MOVWF EEADRH
	BCF   STATUS,RP1
	RRF   ci,W
	ANDLW .127
	ADDLW .134
	BSF   STATUS,RP1
	MOVWF EEADR
	BTFSS STATUS,Carry
	GOTO  m001
	INCF  EEADRH,1
m001	BSF   STATUS,RP0
	BSF   STATUS,RP1
	BSF   EECON1,EEPGD
	BSF   EECON1,RD
	NOP  
	NOP  
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	BTFSC ci,0
	GOTO  m002
	BSF   STATUS,RP1
	MOVF  EEDATA,W
	ANDLW .127
	RETURN
m002	BCF   STATUS,RP0
	BSF   STATUS,RP1
	RLF   EEDATA,W
	RLF   EEDATH,W
	RETURN
	DW    0x31C9
	DW    0x1068
	DW    0x34E2
	DW    0x106E
	DW    0x274F
	DW    0x20
	DW    0x26CD
	DW    0x1043
	DW    0x274F
	DW    0x20
	DW    0x32CC
	DW    0x32F3
	DW    0x395F
	DW    0x39E5
	DW    0x2FF0
	DW    0x32C6
	DW    0x3668
	DW    0x3965
	DW    0x2980
	DW    0x3463
	DW    0x32F2
	DW    0x3169
	DW    0x395F
	DW    0x39E5
	DW    0x2FF0
	DW    0x32C6
	DW    0x3668
	DW    0x3965
	DW    0x20
	DW    0x31D3
	DW    0x3968
	DW    0x34E5
	DW    0x2FE2
	DW    0x32C6
	DW    0x3668
	DW    0x3965
	DW    0x20
InitUSART
			;BRGH=1;
	BSF   STATUS,RP0
	BCF   STATUS,RP1
	BSF   TXSTA,BRGH
			;//SPBRG=129;	// (9600 baud @ 20MHz input clock)
			;//SPBRG=64;		// (19200 baud @ 20MHz input clock)
			;//SPBRG=32;		// (38400 baud @ 20MHz input clock)
			;SPBRG=10;		// (115200 baud @ 20MHz input clock)
	MOVLW .129
	MOVWF SPBRG
			;SPEN = 1; 		// Set_Serial_Pins;
	BCF   STATUS,RP0
	BSF   RCSTA,SPEN
			;SYNC = 0;		// Set_Async_Mode;
	BSF   STATUS,RP0
	BCF   TXSTA,SYNC
			;TX9 = 0; 		// Set_8bit_Tx;
	BCF   TXSTA,TX9
			;RX9 = 0; 		// Set_8bit_Rx;
	BCF   STATUS,RP0
	BCF   RCSTA,RX9
			;CREN = 1; 		// Enable_Rx;
	BSF   RCSTA,CREN
			;TXEN = 1; 		// Enable_Tx;
	BSF   STATUS,RP0
	BSF   TXSTA,TXEN
			;RCIE=0;   		// Rx Interrupt aus
	BCF   PIE1,RCIE
			;}
	RETURN
			;//**********************************************************************
			;
			;void SerString(const char *str)	//Ein String seriell senden
			;{
SerString
			;char ps;
			;ps = *str;		// Pointer auf start des Strings ins ps
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  str,W				; str to W
	CALL  _const1
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF ps
			;while(ps>0)		// Pruefen ob String zu ende ist
m003	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  ps,1
	BTFSC STATUS,Zero_
	GOTO  m006
			;	{
			;	str++;				// Pointer auf nexte Zeihen erhoehen
	INCF  str,1
			;	if (ps== 0) break;	// Pruefen ob String zu ende ist
	MOVF  ps,1
	BTFSS STATUS,Zero_
	GOTO  m004
	GOTO  m006
			;	while(!TXIF);   	// Pruefen ob register TXREG leher ist
m004	BCF   STATUS,RP0
	BCF   STATUS,RP1
	BTFSC PIR1,TXIF
	GOTO  m005
	GOTO  m004
			;	TXREG =ps ;			// Datenbyte senden
m005	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  ps,W
	MOVWF TXREG
			;    ps = *str;			// Inhalt des ponters ins ps
	MOVF  str,W
	CALL  _const1
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF ps
			;	}
	GOTO  m003
			;}
m006	RETURN
			;//********************************************************************
			;
			;char SPI(char d)		// Ueber SPI-Schnittstelle
			;{						// senden
SPI
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF d
			;SSPBUF=d;
	MOVF  d,W
	MOVWF SSPBUF
			;while (!BF);			// 	Warten bis gesendet ist
m007	BSF   STATUS,RP0
	BCF   STATUS,RP1
	BTFSC SSPSTAT,BF
	GOTO  m008
	GOTO  m007
			;return SSPBUF;			// gleichzeitig empfangen
m008	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  SSPBUF,W
	RETURN
			;}
			;//**********************************************************************
			;
			;char Command(char befF,uns16 AdrH,uns16 AdrL,char befH )
			;{						// Ein Befehl zum MMC senden
Command
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF befH
			;char a;
			;SPI(0xFF);
	MOVLW .255
	CALL  SPI
			;SPI(befF);
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  befF,W
	CALL  SPI
			;SPI(AdrH.high8);
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  AdrH+1,W
	CALL  SPI
			;SPI(AdrH.low8);
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  AdrH,W
	CALL  SPI
			;SPI(AdrL.high8);
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  AdrL+1,W
	CALL  SPI
			;SPI(AdrL.low8);
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  AdrL,W
	CALL  SPI
			;SPI(befH);
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVF  befH,W
	CALL  SPI
			;SPI(0xFF);
	MOVLW .255
	CALL  SPI
			;return SPI(0xFF);		// Response als Rueckgabewert
	MOVLW .255
	GOTO  SPI
			;}
			;//**************************************************************************
			;
			;bit MMC_Init()
			;{
MMC_Init
			;// Init SPI
			;SMP=0;		// Input ist gueltig in der Mitte des Clock
	BSF   STATUS,RP0
	BCF   STATUS,RP1
	BCF   SSPSTAT,SMP
			;CKE=0;		// CKE=1;	// Fordere Flanke (steigende)
	BCF   SSPSTAT,CKE
			;CKP=1;		// CKP=0;	// Low ist Passiwe Zustand
	BCF   STATUS,RP0
	BSF   SSPCON,CKP
			;SSPM1=1;	// Geschwindigkeit f/64(312kHz), Master
	BSF   SSPCON,SSPM1
			;//SSPM0=1;	// Geschwindigkeit f/16(1,25MHz), Master
			;SSPEN=1;	// SPI Ein
;	BSF   SSPCON,SSPEN
			;
			;CS=1;		// MMC-Disabled
	BSF   PORTC,CS
			;
			;char i;		// Variablen
			;
			;//MMC in SPI-Modus starten, Reset
			;for(i=0; i < 10; i++)SPI(0xFF);
	CLRF  i
m009	MOVLW .10
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	SUBWF i,W
	BTFSC STATUS,Carry
	GOTO  m010
	MOVLW .255
	CALL  SPI
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	INCF  i,1
	GOTO  m009
			;CS=0;						// MMC-Enabled
m010	BCF   STATUS,RP0
	BCF   STATUS,RP1
	BCF   PORTC,CS
			;// CMD0
			;if (Command(0x40,0,0,0x95) !=1)goto Fehler ;
	MOVLW .0
	MOVWF befF
	CLRF  AdrH
	CLRF  AdrH+1
	CLRF  AdrL
	CLRF  AdrL+1
	MOVLW .149
	CALL  Command
	XORLW .1
	BTFSC STATUS,Zero_
	GOTO  m011
	GOTO  m023
			;
			;st:
			;// CMD1
			;if (Command(0x41,0,0,0xFF) !=0) goto st ;		//CMD1 solange wiederholen
m011	MOVLW .1
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF befF
	CLRF  AdrH
	CLRF  AdrH+1
	CLRF  AdrL
	CLRF  AdrL+1
	MOVLW .255
	CALL  Command
	XORLW .0
	BTFSC STATUS,Zero_
	GOTO  m012
	GOTO  m011
			;
			;// CID auslesen
			;if (Command(0x4A,0,0,0xFF) !=0) goto Fehler;
m012	MOVLW .10
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF befF
	CLRF  AdrH
	CLRF  AdrH+1
	CLRF  AdrL
	CLRF  AdrL+1
	MOVLW .255
	CALL  Command
	XORLW .0
	BTFSC STATUS,Zero_
	GOTO  m013
	GOTO  m023
			;for(i=0; i < 20; i++)
m013	BCF   STATUS,RP0
	BCF   STATUS,RP1
	CLRF  i
m014	MOVLW .20
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	SUBWF i,W
	BTFSC STATUS,Carry
	GOTO  m017
			;{
			;while(!TXIF);
m015	BCF   STATUS,RP0
	BCF   STATUS,RP1
	BTFSC PIR1,TXIF
	GOTO  m016
	GOTO  m015
			;TXREG =SPI(0xFF);
m016	MOVLW .255
	CALL  SPI
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF TXREG
			;}
	INCF  i,1
	GOTO  m014
			;
			;// CSD auslesen
			;if (Command(0x49,0,0,0xFF) !=0) goto Fehler;
m017	MOVLW .9
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF befF
	CLRF  AdrH
	CLRF  AdrH+1
	CLRF  AdrL
	CLRF  AdrL+1
	MOVLW .255
	CALL  Command
	XORLW .0
	BTFSC STATUS,Zero_
	GOTO  m018
	GOTO  m023
			;for(i=0; i < 20; i++)
m018	BCF   STATUS,RP0
	BCF   STATUS,RP1
	CLRF  i
m019	MOVLW .16
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	SUBWF i,W
	BTFSC STATUS,Carry
	GOTO  m022
			;{
			;while(!TXIF);
m020	BCF   STATUS,RP0
	BCF   STATUS,RP1
	BTFSC PIR1,TXIF
	GOTO  m021
	GOTO  m020
			;TXREG =SPI(0xFF);
m021	MOVLW .255
	CALL  SPI
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF TXREG
			;}
	INCF  i,1
	GOTO  m019
			;
			;// Set Lenge (Default ist 512 Byte)
			;//if (Command(0x50,0,16,0xFF) !=0) goto Fehler;	// 16 Byte-Mode für Lesen
			;
			;return 1;
m022	BSF   STATUS,Carry
	RETURN
			;Fehler:
			;return 0;
m023	BCF   STATUS,Carry
	RETURN
			;}
			;
			;
			;void main(void)
			;{
main
			;INTCON=0;				// Interrupts aus
	CLRF  INTCON
			;ADCON1=0x6;				// PortA Digital
	MOVLW .6
	BSF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF ADCON1
			;TRISC=0b.0101.1111;		// sck rb6-0, sdo rc7-0, CS rc5-0.
	MOVLW .95
	MOVWF TRISC
			;TRISB=0b.0010.0000;   	// RB7>TX, RB5<RX
	MOVLW .32
	MOVWF TRISB
			;uns16 i;
			;InitUSART();			// Serielle Datenuebertragung Initialisieren
	CALL  InitUSART
			;SerString("Ich bin ON ");					// Startmeldung
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	CLRF  str
	CALL  SerString
			;if (MMC_Init()) SerString("MMC ON ");		// Startmeldung
	CALL  MMC_Init
	BTFSS STATUS,Carry
	GOTO  m024
	MOVLW .12
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF str
	CALL  SerString
			;//**********************************************************************
			;
			;// Lesen  512 Byte-mode
			;
			;if (Command(0x51,0,512,0xFF) !=0) SerString("Lese_resp_Fehler");
m024	MOVLW .17
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF befF
	CLRF  AdrH
	CLRF  AdrH+1
	CLRF  AdrL
	MOVLW .2
	MOVWF AdrL+1
	MOVLW .255
	CALL  Command
	XORLW .0
	BTFSC STATUS,Zero_
	GOTO  m025
	MOVLW .20
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF str
	CALL  SerString
			;while(SPI(0xFF) != 0xFE);
m025	MOVLW .255
	CALL  SPI
	XORLW .254
	BTFSC STATUS,Zero_
	GOTO  m026
	GOTO  m025
			;for(i=0; i < 512; i++)
m026	BCF   STATUS,RP0
	BCF   STATUS,RP1
	CLRF  i_2
	CLRF  i_2+1
m027	MOVLW .2
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	SUBWF i_2+1,W
	BTFSC STATUS,Carry
	GOTO  m030
			;	{
			;	while(!TXIF);   			// Pruefen ob register TXREG leher ist
m028	BCF   STATUS,RP0
	BCF   STATUS,RP1
	BTFSC PIR1,TXIF
	GOTO  m029
	GOTO  m028
			;	TXREG =SPI(0xFF);			// Datenbyte senden
m029	MOVLW .255
	CALL  SPI
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF TXREG
			;	}
	INCF  i_2,1
	BTFSC STATUS,Zero_
	INCF  i_2+1,1
	GOTO  m027
			;SPI(0xFF);
m030	MOVLW .255
	CALL  SPI
			;SPI(0xFF);
	MOVLW .255
	CALL  SPI
			;//************************************************************************
			;
			;
			;// Schreiben  512 Byte-Mode
			;if (Command(0x58,0,512,0xFF) !=0) SerString("Schreib_resp_Fehler ");
	MOVLW .24
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF befF
	CLRF  AdrH
	CLRF  AdrH+1
	CLRF  AdrL
	MOVLW .2
	MOVWF AdrL+1
	MOVLW .255
	CALL  Command
	XORLW .0
	BTFSC STATUS,Zero_
	GOTO  m031
	MOVLW .37
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF str
	CALL  SerString
			;SPI(0xFF);
m031	MOVLW .255
	CALL  SPI
			;SPI(0xFF);
	MOVLW .255
	CALL  SPI
			;SPI(0xFE);
	MOVLW .254
	CALL  SPI
			;for(i=0; i < 512; i++)
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	CLRF  i_2
	CLRF  i_2+1
m032	MOVLW .2
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	SUBWF i_2+1,W
	BTFSC STATUS,Carry
	GOTO  m033
			;	{
			;	SPI('M');
	MOVLW .77
	CALL  SPI
			;	}
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	INCF  i_2,1
	BTFSC STATUS,Zero_
	INCF  i_2+1,1
	GOTO  m032
			;SPI(255);
m033	MOVLW .255
	CALL  SPI
			;SPI(255);
	MOVLW .255
	CALL  SPI
			;i=SPI(0xFF);
	MOVLW .255
	CALL  SPI
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF i_2
	CLRF  i_2+1
			;i &=0b.0001.1111;
	CLRF  i_2+1
	MOVLW .31
	ANDWF i_2,1
			;if (i != 0b.0000.0101) SerString("Schreib_Fehler ");
	MOVF  i_2,W
	XORLW .5
	BTFSS STATUS,Zero_
	GOTO  m034
	MOVF  i_2+1,1
	BTFSC STATUS,Zero_
	GOTO  m035
m034	MOVLW .58
	BCF   STATUS,RP0
	BCF   STATUS,RP1
	MOVWF str
	CALL  SerString
			;while(SPI(0xFF) !=0xFF);
m035	MOVLW .255
	CALL  SPI
	XORLW .255
	BTFSC STATUS,Zero_
	GOTO  m036
	GOTO  m035
			;
			;//**********************************************************************
			;while(1);				//hier bleibt Programm stehen
m036	GOTO  m036

	ORG 0x800
	DATA 0F72h
	
	END
