/* random690bb.c "pseudo-random" numbers displayed on PK2 UartTool */ /* PICKIT 2 UART-Tool Cable Chip Programmer UART Tool Kjell & Co 37-342 > 1 = Blue > 1 = VPP > 1 2 = Green 2 = VDD Target 2 = VDD Target 3 = Yellow 3 = VSS (Ground) 3 = VSS (Ground) 4 = Orange 4 = ICSPDAT 4 = RX (PICKit2 In) 5 = Red 5 = ICSPCLK 5 = TX (PICKit2 Out) 6 = Brown 6 = AUX 6 */ /* Use "PICkit2 UART Tool" as a 9600 Baud terminal. Uncheck "Echo On". PIC internal USART is not used. BitBanging routines. No extra connections are needed. ___________ ___________ | \/ | +5V---|Vdd 16F690 Vss|---GND |RA5 RA0/AN0/(PGD)|bbTx ->- PK2Rx |RA4 RA1/(PGC)|bbRx -<- PK2Tx |RA3/!MCLR/(Vpp) RA2/INT| |RC5/CCP RC0| |RC4 RC1| |RC3 RC2| |RC6 RB4| |RC7 RB5/Rx|not used not used|RB7/Tx RB6| |________________________| */ #include "16F690.h" #pragma config |= 0x00D4 void initserial( void ); void putchar( char ); char getchar( void ); void delay10( char ); void printf(const char *string, uns8 variable); char rand( void ); void main( void) { /* Missing support for initialized static variables */ /* (are needed in random function) */ /* Clear all RAM instead. Using Cc5x internal function clearRAM() */ char c; initserial(); delay10(100); /* 1 sek delay */ /* 1 sek to turn on VDD and Connect UART-Tool */ getchar( ); /* wait for char to start! */ printf("Pseudo-random numbers:\r\n", 0); while(1) { c = rand(); printf("decimal %u",c); printf(" binary %b\r\n",c); } } /* *********************************** */ /* FUNCTIONS */ /* *********************************** */ void initserial( void ) /* initialise PIC16F690 serialcom port */ { ANSEL.0 = 0; /* No AD on RA0 */ ANSEL.1 = 0; /* No AD on RA1 */ PORTA.0 = 1; /* marking line */ TRISA.0 = 0; /* output to PK2 UART-tool */ TRISA.1 = 1; /* input from PK2 UART-tool */ return; } void putchar( char ch ) /* sends one char */ { char bitCount, ti; PORTA.0 = 0; /* set startbit */ for ( bitCount = 10; bitCount > 0 ; bitCount-- ) { /* delay one bit 104 usec at 4 MHz */ /* 5+18*5-1+1+9=104 without optimization */ ti = 18; do ; while( --ti > 0); nop(); Carry = 1; /* stopbit */ ch = rr( ch ); /* Rotate Right through Carry */ PORTA.0 = Carry; } return; } char getchar( void ) /* recieves one char, blocking */ { /* One start bit, one stop bit, 8 data bit, no parity = 10 bit. */ /* Baudrate: 9600 baud => 104.167 usec. per bit. */ char d_in, bitCount, ti; while( PORTA.1 == 1 ) /* wait for startbit */ ; /* delay 1,5 bit 156 usec at 4 MHz */ /* 5+28*5-1+1+2+9=156 without optimization */ ti = 28; do ; while( --ti > 0); nop(); nop2(); for( bitCount = 8; bitCount > 0 ; bitCount--) { Carry = PORTA.1; d_in = rr( d_in); /* rotate carry */ /* delay one bit 104 usec at 4 MHz */ /* 5+18*5-1+1+9=104 without optimization */ ti = 18; do ; while( --ti > 0); nop(); } return d_in; } void delay10( char n) /* Delays a multiple of 10 milliseconds using the TMR0 timer Clock : 4 MHz => period T = 0.25 microseconds 1 IS = 1 Instruction Cycle = 1 microsecond error: 0.16 percent. B Knudsen. */ { char i; OPTION = 7; do { i = TMR0 + 39; /* 256 microsec * 39 = 10 ms */ while ( i != TMR0) ; } while ( --n > 0); } void printf(const char *string, uns8 variable) { char i, k, m, a, b; for(i = 0 ; ; i++) { k = string[i]; if( k == '\0') break; // at end of string if( k == '%') // insert variable in string { i++; k = string[i]; switch(k) { case 'd': // %d signed 8bit if( variable.7 ==1) putchar('-'); else putchar(' '); if( variable > 128) variable = -variable; // no break! case 'u': // %u unsigned 8bit a = variable/100; putchar('0'+a); // print 100's b = variable%100; a = b/10; putchar('0'+a); // print 10's a = b%10; putchar('0'+a); // print 1's break; case 'b': // %b BINARY 8bit for( m = 0 ; m < 8 ; m++ ) { if (variable.7 == 1) putchar('1'); else putchar('0'); variable = rl(variable); } break; case 'c': // %c 'char' putchar(variable); break; case '%': putchar('%'); break; default: // not implemented putchar('!'); } } else putchar(k); } } char rand( void ) /* Random number function */ { bit EXOR_out; static char rand_hi, rand_lo; /* values from last call will be used as seed for calculation of the next random number */ if( !rand_hi && !rand_lo ) rand_lo = 0x01; /* 0x0000 won't run ... */ EXOR_out = rand_lo.0; EXOR_out ^= rand_lo.2; EXOR_out ^= rand_lo.3; EXOR_out ^= rand_lo.5; Carry = EXOR_out; rand_hi = rr( rand_hi); /* rotate right, Cc5x internal function */ rand_lo = rr( rand_lo); return rand_lo; }