 // Serielle Datenübertragung bei  4MHz
 // (9600,n,8,1) 9600 Baud, kein Paritätsbit ,8 Bit,1 Stop-Bit
 //
 // Michael Dworkin
 // 07.02.2003
 // Compiler CC5x

 void pause(void)
 {
 char ZAEHL ;
 char tau ;
 tau=0x1F;
 	#asm
		movf	tau,w				; Pause von ein Bit-Dauer
		movwf	ZAEHL				; (104)32*3=96+4=100mks
wdh1	decfsz	ZAEHL,f
		goto	wdh1
	#endasm
 }

void pause1(void)
 {
 char ZAEHL ;
 char tau ;
 tau=0xF;
 	#asm
		movf	tau,w		; Start-Pause Halbe Bit-Dauer
		movwf	ZAEHL		; 34 mks
wdh2	decfsz	ZAEHL,f
		goto	wdh2
	#endasm
 }

void senden(char DATAUS)
{
char BIT ;
	#asm
		movlw	08				; 8 Bit
		movwf	BIT				; Bitzaehler mit 8 laden
		comf 	DATAUS,f		; Zusendende Byte Invertieren(weil kein hardwahre Invertor da ist)
		bsf		Opin			; Startbit = 1
		call	pause
wdh4	rrf		DATAUS,f		; Register mit Daten wird rechts rotiert(ganz rechte Bit wird in Carry geschoben)
		btfss	STATUS,Carry	; Carrybit pruefen
		goto	setzen			; Carrybit = 0: Setzen ueberspriengen
		bsf		Opin			; Carrybit = 1: Seriele AusgangsPin setzen (5V)
		goto	weiter
setzen	bcf		Opin			; Seriele Pin ruecksetzen (0V)
weiter	call	pause			; warte 64 mks
		decfsz	BIT,f			; Bitzaehler runterzaehlen
		goto	wdh4			; Wiederholen 8 mal
		bcf		Opin			; Stoppbit = 0, einstellen stopbit
		call	pause			; warte 64 mks
		nop
	#endasm
}

char empfang(void)
{
char DATAUS;
char BIT;
	#asm

strtbit		btfss	Ipin		; Ueberpruefen auf Start-bit = 0
			goto	strtbit		; warte bis es 1 wird
			call	pause1		; warte Halbe Bit-Dauer damit Werterfassung in der mitte des impulses passiert
			btfss	Ipin		; Start-bit immer noch = 0, alles von anfang(2 prüfung des startimpulses
			goto	strtbit		; is dafuer, damit kein zufaelige Impuls der Einleseforgang startet)
			movlw 	08			;
			movwf	BIT			; Bitzaehler mit 8 laden
			clrf	DATAUS		; Variable leern
empfg		call	pause		; warten 64 mks (damit sind wir in der mitte des Datenbits)
			rrf		DATAUS,f	; Rechts Schieben
			bsf		DATAUS,7	; Immer Bit7 setzen
			btfss	Ipin
			bcf		DATAUS,7	; falls am Eingang Bit=0, Bit7 ruecksetzen
			decfsz	BIT,f		; 8 Bits abzaehlen
			goto	empfg		; Wenn noch nicht abgezaehlt,naechste Bit empfangen
			call 	pause		; Warten wegen Stoppbits
			comf	DATAUS,f	; Inwertiren empfangene Byte
		#endasm
 return (DATAUS);
}

void SerString(const char *__putstr)	// Funktion zum senden eines Strings
{
 char __ps;								// Variable definieren

 __ps = *__putstr;						// Physiche Variablenadresse wird geändert
										// __ps zeigt auf Stringanfang in Programmspeicher
  while(__ps>0)							// solande Zeichen(in String) keine 0 Wert hat
   {
    __putstr++;							// Zeiger auf nächste Zeichen des Strings setzen
    if (__ps== 0) break;				// Ein String hat am ende eine Zeichen mit Wert 0
   senden(__ps);						// Zeichen senden
    __ps = *__putstr;					// __ps kriegt Zeiger auf nächste Zeichen (sehe 3 Zeilen höcher)
   }									// Um diese unterprogramm zu verstehen muss mann Pointer kennen.
}

