Schulprojekt:Prototypenbau/Informatik/V24

C-Programmierung

Serielle Schnittstelle mit PIC16F690 Bearbeiten

//--------------------------------------------------------------------------------
// RS232.c  Serielle Schnittstelle mit PIC16F690
//            Interner Takt 4 Mhz
//
// Autor:    emotivator
// Date:      26.Dezember 2007.
// -------------------------------------------------------------------------------
//
//  Funktion: Test des 16F690 UART (Universal Asynchronous Receiver Transmitter)
//  
//
//  Entwicklungsumgebung: MPLAB IDE V7.62
//                        Knudsen  CC5X compiler version 3.3
//                        Programmer: PICKit 2
//
//  Hardware: PIC 16F690 PICKit2. + Pegelwandler Max232
//
// -------------------------------------------------------------------------------
//
//  Schaltplan:
//
//  +----+------------+---------------------+---- VDD (Voltage Drain Drain)
//       |                                  |   
//       |        pic16F690                 |   
//       |   +--------U----------+          |   
//  +5V  +---|(01)VDD    Vss (20)|---+GND   |
//           |(02)CLKIN  RA0 (19)|-  |      |
//           |(03)CLKOUT RA1 (18)|-  |      | 
//           |(04)MCLR   RA2 (17)|   |      |         
//           |(05)RC5    RC0 (16)|-  |      | +-----U----+ 
//          -|(06)RC4    RC1 (15)|-  |      +-|  max232  |
//          -|(07)RC3    RC2 (14)|   |        |(16)      |  DB9
//          -|(08)RC6    RB4 (13)|   |        |          |
//           |(09)RC7    RX  (12)|------<-----|(12)  (13)|--<-- TXD -- 3
//         |-|(10)TX     RB6 (11)|   |        |          |
//         | +-------------------+   |        |          |
//         +---------------------------->-----|(11)  (14)|-->-- RXD -- 2
//                                   |        +-----|----+
//  +----------------+---------------+--------------+-- GND (Ground)-- 5
//
// ------------------------------------------------------------------------




#pragma  config  &= ~0b11.1111.1111.1111        // all OFF
#pragma  config  |=  0b11.0011.1111.0100

#pragma bit LED0 @ PORTC.0;
#pragma bit LED1 @ PORTC.1;
#pragma bit LED2 @ PORTC.2;

typedef  bit         BOOL, boolean;             // boolean variable type(s)
#define  FALSE       0                          // pic: off, low
#define  TRUE        1                          // pic: on, high

// ===============================================================
//   M A I N 
//
//	 Asynchrones Datensenden:
//	 S1.) SPBRGH:SPBRG Register zum Baudrateneinstellen BRGH und BRG16
//   	 S2.) Clear SYNC Bit und Setze SPEN
//	 S3.) TXIE wenn Interrupt erwünscht
//	 S4.) TX9 wenn 9 Bit Modus
//	 S5.) TXEN setzen um Senden zu erlauben
//	 S6.) Falls 9tes Bit dann in TX9D setzen
//	 S7.) Daten in TXREG stellen
//	 S8.) GIE und PEIE setzen wenn Interrupt erwünscht 
//
//	 Asynchroner Datenempfang:
//	 1.) SPBRGH:SPBRG Register zum Baudrateneinstellen BRGH und BRG16
//     2.) Clear SYNC Bit und Setze SPEN
//	 3.) RCIE wenn Interrupt erwünscht
//	 4.) RX9 wenn 9 Bit Modus
//	 5.) CREN setzen um Empfang zu erlauben
//	 6.) Wenn Emfang fertig dann wird RCIF gesetzt und Interupt ausgelöst
//	 7.) RCSTA lesen um Fehler festzustellen
//	 8.) Daten aus RCREG auslesen
//	 9.) falls Fehler CREN 0 setzen
//	10.) GIE und PEIE setzen wenn Interrupt erwünscht 
//    Programm gibt Text PIC16F690 am Terminal mit 9600 Baud aus
//    Durch Eingabe von a, b, c werden LEDs eingeschaltet,
//    mit d ausgeschaltet.
// ===============================================================
void main(void) 
{
  char   i;                  	// Zaehlvariable
  char   rcvbuf;
  char   buffer[20];           	// local I/O buffer
  const  char *welcome = "\n\rPIC16F690 RS232\n\r";       // welcome!

  INTCON  = 0;              // all interrupt bits off
  PIR1    = 0;              // clear interruptflags before enable interrupt
  PIE1    = 0;              // disable peripheral interrupts
 
  PORTA   = 0;              // all ports zero
  PORTB   = 0;              //  ..
  PORTC   = 0b0000.0000;  
  TRISA   = 0b0010.0100;    // IN: RA5/MCLR
  TRISB   = 0b0011.0000;    // IN: RB 4,5
  TRISC   = 0b1111.1000;    //PORTC 3Bits als output
  ANSEL	  = 0;	    //Digital Pins
  ANSELH  = 0;		    //Wichtig ! Digital Pin RB5 RX

//S3.) TXIE wenn Interrupt erwünscht
  TXIE    = FALSE;          	// enable UART transmit Interrupt
//S4.) TX9 wenn 9 Bit Modus
  TX9     = FALSE;				//(9-Bit transmit enable Bit)
//S5.) TXEN setzen um Senden zu erlauben
  TXEN    = TRUE;             	// enable UART transmit
// 1.) SPBRGH:SPBRG Register zum Baudrateneinstellen   BRGH und BRG16
  BRGH    = TRUE;              	// baudrate class      
  BRG16   = FALSE;
  SPBRG   = 25;                	// baudrate clock divisor 9600 Baud
//   2.) Clear SYNC Bit und Setze SPEN 
  SYNC    = FALSE;             	// async mode
  SPEN    = TRUE;               // enable UART (Serial Port Enable Bit)
//	 3.) RCIE wenn Interrupt erwünscht
  RCIE    = FALSE;             	// enable receive interrupts    
//	 4.) RX9 wenn 9 Bit Modus
  RX9     = FALSE;				//(9-Bit receive enable Bit)                  
//	 5.) CREN setzen um Empfang zu erlauben
  CREN    = TRUE;               // Continous receive enable Bit
//	10.) GIE und PEIE setzen wenn Interrupt erwünscht 
  PEIE    = FALSE;            	// enable peripheral interrupts
  GIE     = FALSE;              // globally enable interrupts    
  //-----------------------------------------------------------
    rcvbuf=0;                
    for (i=0; welcome[i] != '\0'; )      // Text ausgeben
    {
       if (TRMT == TRUE)			//Sender frei
        {
          TXREG = welcome[i];
	      i=i+1;
        }      
    }    
 //--------------------------------------------------------------
  for (;;) 					     // forever
  {                    
  //	 6.) Wenn Emfang fertig dann wird RCIF gesetzt und Interupt ausgelöst
    if (RCIF == TRUE)
    {                            
    //	 7.) RCSTA lesen um Fehler festzustellen
      if (OERR == TRUE) 
	    {                    		// overrun, reset UART
       CREN = FALSE;                     // disable UART
       CREN = TRUE;                      // re-enable UART 
       LED1 = TRUE;
      }                                  // discard pending bytes 
      if (FERR == TRUE) 
      {                    // framing error (break?)
       CREN = FALSE;                     // disable UART
       CREN = TRUE;                      // re-enable UART 
       LED1 = TRUE;
      }
      else 
      {                                  // data without errors
       rcvbuf = RCREG;                   
      }
     }
    if (rcvbuf != 0)
        {
          if (TRMT == TRUE)
           {
             TXREG = rcvbuf;
	         if (rcvbuf=='a') LED0=TRUE;
			 if (rcvbuf=='b') LED1=TRUE;
			 if (rcvbuf=='c') LED2=TRUE;
			 if (rcvbuf=='d') PORTC   = 0b0000.0000; 
			 rcvbuf=0;
           }
        }   
    }
}