// Example_1.C
//
// Continually flashes an LED on PORTD.4 in bursts of five flashes and writes a
// '!' to the serial LCD.
//
// Illustrates the use of ser_init(), ser_char(), delay_10us and delay_ms()
//
// copyright, Peter H. Anderson, Baltimore, MD, April 9, '08
//

#case

#device PIC16F887 *=16 ICD=TRUE

#include <defs_887.h>

void flash(byte num_flashes);
void ser_char(char ch);
void ser_init();
void delay_10us(byte t);
void delay_ms(long t);


void main(void)
{
   OSCCON = 0x61;
   ser_init();
   printf(ser_char, "?f");
   while(1)
   {
     flash(5);
     printf(ser_char, "!");
     delay_ms(3000);
   }
}

void flash(byte num_flashes)
{
   byte n;
   for (n=0; n<num_flashes; n++)
   {
     trisd0 = 0;        // be sure bit is an output
     portd0 = 1;
     delay_ms(500);
     portd0 = 0;
     delay_ms(500);
   }
}

void ser_init(void)
{
    trisc6 = 0;
    portc6 = 1;
    delay_ms(200);
}

void ser_char(char ch) // 9600 baud
{

   byte dly, num_bits, gie_status;
     // start bit + 8 data bits
   gie_status = gie;
   while(gie)
   {
      gie = 0;
   }
   num_bits = 9;
#asm
   CLRWDT
   BCF STATUS, RP0
   BCF STATUS, C

LCD_CHAR_1:
   BTFSS STATUS, C
   BCF PORTC, 6
   BTFSC STATUS, C
   BSF PORTC, 6
   MOVLW 32
   MOVWF dly

LCD_CHAR_2:
   DECFSZ dly, F
   GOTO LCD_CHAR_2
   RRF ch, F
   DECFSZ num_bits, F
   GOTO LCD_CHAR_1

   BSF PORTC, 6
   CLRWDT
   MOVLW 100
   MOVWF dly

LCD_CHAR_3:
   DECFSZ dly, F
   GOTO LCD_CHAR_3
   CLRWDT
#endasm
   gie = gie_status;
}

void delay_10us(byte t)
// provides delay of t * 10 usecs (4.0 MHz clock)
{
#asm
      BCF STATUS, RP0
DELAY_10US_1:
      CLRWDT
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      DECFSZ t, F
      GOTO DELAY_10US_1
#endasm
}


void delay_ms(long t)   // delays t millisecs (4.0 MHz clock)
{
   do
   {
     delay_10us(100);
   } while(--t);
}