seriele communicatie in c. 16f877a en 16f627a

Alle vragen m.b.t digitale schakelingen m.b.v. losse i.c's
en oplossingen m.b.v. PIC processoren.
Plaats reactie
Gebruikersavatar
cheeta
Berichten: 514
Lid geworden op: do 7 okt 2004, 21:16
Locatie: . .. .. .. .. .. .. .

seriele communicatie in c. 16f877a en 16f627a

Bericht door cheeta »

Als beginner met software programmeren wil ik een seriele communicatie opstarten nu heb ik uit een oud project van school nog het een en ander bruikbare kunnen filteren. Maar kom er niet meer uit hoe ik hier data wegschrijf en ontvang aan de andere kant.

ook is dit duplex en zoek ik simplex.

Code: Selecteer alles

#include <system>
#pragma DATA 0x2007, 0x3F3A    //Stel in op de externe klok
#pragma CLOCK_FREQ 20000000  //Stel de freq in op 20Mhz

//De Variabelenen
char L = 0;						//De PWM teller
char Lr = 255;					//Helderheid van Rode Led
char Lg = 225;					//Helderheid van Groene Led
char Lb = 80;					//Helderheid van Blauw Led

char Data;
char Da;						//Data packet A
char Db;						//Data packet B
char Dc;						//Data packet C
char Dd;						//Data packet D
char De;						//Data packet E
char Df;						//Data packet F
char Dg;						//Data packet G
char Dn = 0;					//De volgende (next 8 data bits.

char temp;

//Defines
#define ID 00101000b   

//Begin van programma
void main ()
{
	      //76543210
	trisa = 00111111b;      //Invoer servo signalen 6x
	trisb = 00000000b;      //Uitvoer lichtfuncties 8x
	trisc = 00001111b;		//Invoer vanuit MS12 set 4x
	trisd = 00111111b;		//Invoer vanuit MS12 set 6x
	trise = 00000111b;		//AD pooten inlezen potmeters 3x
			
	cmcon = 0x07;           //Zet comparators uit

    
//Serieel interface
    set_bit(rcsta,SPEN);    	//Zet seriele poort aan
    clear_bit(txsta,SYNC);  	//Zet communicatie op asynchroon
    set_bit(txsta,BRGH);    	//Hoge snelheid
    spbrg = 129;             	//9600 baud
    clear_bit(txsta,TXEN);    	//Ontvangen uit
    set_bit(rcsta,CREN);    	//Verzenden aan
    clear_bit(rcsta,RX9);   	//Stel in op 8 bits
    set_bit(pie1,RCIE);   		//Zet interrupt aan
    set_bit(intcon,PEIE);  	 	//Laat ook de peripheral interrupt doorkomen

    set_bit(intcon,GIE);    	// en zet reageren op interrupts aan 
	
	while(1)
	{
		set_bit(portb,5);
		delay_ms(150);
		clear_bit(portb,5);
		delay_ms(500);
//		Lb = Da;

	}
}

//PWM programma
void interrupt()
{
	
//Seriele poort afhandeling
	if(test_bit(pir1,RCIF))				//Kijk voor serieel intrupt
    {
        //Serieel otnvangen afhdeling
        clear_bit(pir1,RCIF);
        char data;                      //Maak karakter data aan
        if(test_bit(pir1,RCIF))			//Controleer of er nog data is in de buffer
		{
			if(test_bit(rcsta,FERR))	//Check op een framing error
			{
				temp = rcreg;			//Lees karakter uit om volgende karakter te krijgen
			}
			else
			{
				if(Dn==0)
				{
					rcreg = Data;
					if(Data&11111000b==ID)
					{
						Dn = Data & 00000111b;
					}
				
				}
				if(Dn>0)
				{
					switch(Dn) 
					{
						case 1:		
							Da = rcreg;
							Dn = 0;			
							break;
							
						case 2:		
							Db = rcreg;
							Dn = 0;			
							break;
							
						case 3:		
							Dc = rcreg;
							Dn = 0;			
							break;
							
						case 4:		
							Dd = rcreg;
							Dn = 0;			
							break;
							
						case 5:		
							De = rcreg;
							Dn = 0;			
							break;
							
						case 6:		
							Df = rcreg;
							Dn = 0;			
							break;
						
						case 7:		
							Dg = rcreg;
							Dn = 0;			
							break;
							
						default:
							Dn = 0;
							break;

					}
				}				
			}
			if(test_bit(rcsta,OERR))		//Controleer over er een overrun plaats vindt
			{
				clear_bit(rcsta,CREN); 		//Zo ja reset ontvanger
				set_bit(rcsta,CREN);
			}
		}
	}
}
is er iemand die een eventuele toelichting of voorbeeld kan geven?

Edit:
inmiddels mijn eigen code gemaakt op basis van bovenstaande code en de documentatie.

Zendpic 16f877A.

Code: Selecteer alles

#include <system>
#pragma DATA 0x2007, 0x3F3A    //Stel in op de externe klok
#pragma CLOCK_FREQ 20000000  //Stel de freq in op 20Mhz

char byte;
void sendbyte(char byte);

void main () //begin van het programma

{

// Basis instellingen poorten
//			76543210
	trisa = 00111111b;		//Porta alles ingang
	trisb = 00000000b;		//Portb alles uitgang
	trisc = 01001111b;		//Portc 4x ingang, 1x tx, 3x uitgang
	trisd = 00111111b;		//Portd 6x ingang, 2x uitgang
	trise = 00000111b;		//Porte 3x A/D ingang
	
	porta = 0;				//Porta alles uit
	portb = 0;				//Portb alles uit
	portc = 0;				//Portc alles uit
	portd = 0;				//Portd alles uit
	porte = 0;				//Porte alles uit
	
//Configuratie Seriele poort transmitter
//

	clear_bit(txsta,SYNC);	//instellen op asynchroon
	set_bit(txsta,BRGH);	//instellen op hoge snelheid
	set_bit(rcsta,SPEN);	//Seriele poort aanzetten
	spbrg = 129;			//baudrate instellen op 9600
	
	set_bit(txsta,TXEN); 	//zet verzending aan
	clear_bit(txsta,TX9);	//8 bits verzending
	
	while(1)
	{
		set_bit(portb,5);	//keep alive led flash.
		delay_ms(150);
		clear_bit(portb,5);
		delay_ms(500);
		
		if (!test_bit(portc,0))
		{
			byte = 00000110b;
			sendbyte(byte);
			set_bit(portb,4);
			delay_ms(150);
			clear_bit(portb,4);
			delay_ms(500);
		}
		else
		{
			clear_bit(portb,4);
			delay_ms(750);
		}
	}
}
	
// de functie sendbyte verstuurt de byte "byte" die als optie is meegegeven.
void sendbyte(char byte)
{
		while(!(test_bit(txsta,TRMT)));		//wacht zolang bit TMRT 0 is.
			
		//stuur nu de data (byte)	
		txreg = byte;
}
Ontvangst pic 16f627A

Code: Selecteer alles

#include <system>
#pragma DATA 0x2007, 0x3f2A		//16F627 met externe 20mhz kristal
#pragma CLOCK_FREQ 20000000		//Kloksnelheid 20Mhz

char data = 0;
void interrupt();

void main()		//begin van programma
{

char i;

// Basis instellingen poorten
//			76543210
	trisa = 11100000b;		//Porta alles uitgang / 2x kristal
	trisb = 00000010b;		//Portb 7x uitgang / 1x RX
	
	porta = 0;				//Porta alles uit
	portb = 0;				//Portb alles uit

//Configuratie Seriele poort
//
set_bit(rcsta,CREN);	//Zet de ontvanger aan
set_bit(pie1,RCIE);		//Zet de interrupt voor het ontvangen aan]
set_bit(intcon,PEIE);	//Laat ook de peripheral interrupts doorkomen
set_bit(intcon,GIE);	//En zet het reageren op interrupts aan	

while(1)
	{
		set_bit(porta,0);
		delay_ms(150);
		clear_bit(porta,0);
		delay_ms(500);

		if (data == 00000110b;)
		{
			for(i = 0; i < 5; i++)
			{
				set_bit(porta,1);
				delay_ms(150);
				clear_bit(porta,1);
				delay_ms(150);
			}
		}
		else
		{
			set_bit(porta,2);
			delay_ms(500);
			clear_bit(porta,2);
			delay_ms(500);
		}
	}
}
	
void interrupt(void)
{
	char data;
	if(test_bit(pir1,RCIF))
	{
		//check op een framing error
		if(test_bit(rcsta,FERR))
		{
			//Lees rcreg alleen uit om het volgende karakter te krijgen
			data = rcreg;
		}
		else
			data = rcreg;
			//hier komt de afhandelingscode
			//de ontvangen data staat in variabele "data"
	}
	//handel een eventuele overrun error af
	if(test_bit(rcsta,OERR))
	{
		//reset de ontvanger
		clear_bit(rcsta,CREN);
		set_bit(rcsta,CREN);
	}
}	
Ik meet op de scoop wel een puls vanuit mijn tx poort op de 877 zodra ik poort c,0 laag maak.

echter doet mijn 627 hier nog niets mee?

waar ga ik fout of wat doe ik fout?

-----------------
Als ik ga kijken naar de overrun flag dan wordt deze wel geaktiveerd. Echter kan ik geen reactie krijgen uit de door de data verstuurde signaal.

wat doe ik fout?
mail: cheeta [AT} derbi-club *PUNT! com
msn: awinius {AT! derbi-club ^PUNT# com
Gebruikersavatar
cheeta
Berichten: 514
Lid geworden op: do 7 okt 2004, 21:16
Locatie: . .. .. .. .. .. .. .

Bericht door cheeta »

inmiddels wel werkend gekregen maar nog niet stabiel.

dit is de ontvanger
http://pastebin.com/f34faaa03

dit is de zender
http://pastebin.com/f130d5518

echter lijkt het erop dat data2 met regelmaat corrupt raakt aangezien portb = data; niet goed uitgevoerd wordt. (data2 = 00000001b

wat zou inhouden dat portb,0 hoog wordt en de led zou moeten knipperen. echter dit gebeurt niet altijd. (50% van de gevallen).

de andere data1 wordt wel 99% van de gevallen keurig uit gevoerd door het knipper ledje.
mail: cheeta [AT} derbi-club *PUNT! com
msn: awinius {AT! derbi-club ^PUNT# com
Plaats reactie