#pragma CLOCK_FREQ 20000000
#include <system.h>
//-----------------------------------------------------------------------------
// Macros
// Very useful macro which allows use of predefine bit values from system.h
// to be used for testing bits just like they are used in set_bit and clear_bit
#define test_bit(x,y) (x&(1<<y))
//-----------------------------------------------------------------------------
// Set the configuration values (aka fuses)
#ifdef _PIC16F877A
// Appropriate defines for 16F877A
asm __config _HS_OSC & _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_ON & _BODEN_ON & _PWRTE_ON & _WDT_OFF
#endif
#ifdef _PIC16F877
// Appropriate defines for 16F877A
asm __config _HS_OSC & _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_ON & _BODEN_ON & _PWRTE_ON & _WDT_OFF
#endif
//-----------------------------------------------------------------------------
// Set the ID bytes
asm __idlocs H'1234'
//-----------------------------------------------------------------------------
// Prototypes
void ms_tick(void);
void writeString(const char *s);
void sendDecimalInt(int n);
void sendDecimalByte(int n);
void sendHexInt(int n);
void sendHexByte(int n);
void sendBinaryByte(char n);
void sendChar(char c);
void sendRate(void);
void handleReceivedChar(char receivedChar);
//-----------------------------------------------------------------------------
// Globals
int ms_count;
int blink_interval; // # of MS between blinks
char led_flag; // Use of a shadow flag prevents side effects of pin latency
char port_b_val; // Only used for testing
const char *strReady = "\r\nReady> ";
const char *strRate = "Blink Rate = ";
//----------------------------------------------------------------------------
// Writes a string (character array) to the USART
//----------------------------------------------------------------------------
void writeString(const char *s)
{
char i=0;
if( ! test_bit(txsta,TXEN) )
set_bit(txsta, TXEN );
while( s[i]!=0 ){
// write 'u' to serial port, LCD, etc.
while( ! test_bit(pir1, TXIF) )
nop();
txreg=s[i];
i++;
}
}
//----------------------------------------------------------------------------
// Writes a single character to the USART
//----------------------------------------------------------------------------
void sendChar(char c)
{
if( ! test_bit(txsta, TXEN) ){
set_bit(txsta, TXEN );
}
while( ! test_bit(pir1, TXIF) ){
nop();
}
txreg=c;
}
//----------------------------------------------------------------------------
// Writes a 16-bit integer in decimal format to the USART
//----------------------------------------------------------------------------
void sendDecimalInt(int n)
{
if( n >=10000 )
sendChar(((n/10000)%10)+'0');
if( n >=1000 )
sendChar(((n/1000)%10)+'0');
if( n >=100 )
sendChar(((n/100)%10)+'0');
if( n >=10 )
sendChar(((n/10)%10)+'0');
sendChar((n%10)+'0');
}
//----------------------------------------------------------------------------
// Writes a 8-bit byte in decimal format to the USART
//----------------------------------------------------------------------------
void sendDecimalByte(int n)
{
if( n >=100 )
sendChar(((n/100)%10)+'0');
if( n >=10 )
sendChar(((n/10)%10)+'0');
sendChar((n%10)+'0');
}
//----------------------------------------------------------------------------
// Writes a 16-bit integer in hex format to the USART
//----------------------------------------------------------------------------
void sendHexInt(int n)
{
sendHexByte((n>>8)&0xFF);
sendHexByte(n&0xFF);
}
//----------------------------------------------------------------------------
// Writes a 8-bit byte in hex format to the USART
//----------------------------------------------------------------------------
void sendHexByte(char n)
{
char h;
h=(n>>4)&0xF;
n=n&0xF;
if( h>=10 )
sendChar((h-10)+'A');
else
sendChar(h+'0');
if( n>=10 )
sendChar((n-10)+'A');
else
sendChar(n+'0');
}
//----------------------------------------------------------------------------
// Writes a 8-bit byte in binary format to the USART
//----------------------------------------------------------------------------
void sendBinaryByte(char n)
{
static char masks[]={0x80, 0x40, 0x20, 0x10, 8,4,2,1 };
int i;
for(i=0; i<8; i++ ){
if( n & masks[i] )
sendChar('1');
else
sendChar('0');
}
}
//----------------------------------------------------------------------------
// Write the current blink interval value to the terminal
// This illustrates mixing string and numeric output
// This method avoids the memory waste of a printf type function
// Sends the 16-bit value in decimal, hex, and binary
//----------------------------------------------------------------------------
void sendRate(void)
{
writeString(strRate);
sendDecimalInt(blink_interval);
sendChar(' ');
sendChar('0');
sendChar('x');
sendHexInt(blink_interval);
sendChar(' ');
sendBinaryByte((blink_interval>>8)&0xFF);
sendChar('.');
sendBinaryByte(blink_interval&0xFF);
sendChar('b');
sendChar('\r');
sendChar('\n');
}
//-----------------------------------------------------------------------------
void handleReceivedChar(char receivedChar)
{
if( receivedChar==13 ){
writeString(strReady);
}else if( receivedChar=='+' ){ // Increase the blink delay
if( blink_interval>=100 ){
blink_interval = blink_interval + 100;
}else{
blink_interval = blink_interval + 10;
}
sendRate();
}else if( receivedChar=='-' ){ // Decrease the blink delay
if( blink_interval >= 200 )
blink_interval = blink_interval - 100;
else if( blink_interval > 10 )
blink_interval = blink_interval - 10;
sendRate();
}else if( receivedChar=='?' ){ // Show the blink delay
sendRate();
}else{ // Just echo the inbound char
txreg=receivedChar;
set_bit(txsta,TXEN);
}
}
//-----------------------------------------------------------------------------
void interrupt(void)
{
if( test_bit(intcon,T0IF) ){ // TMR0 overflow interrupt
ms_tick();
tmr0 = 0x64; // -156 generates a 1MHz tick at 20MHz
clear_bit(intcon,T0IF);
}
if ( test_bit(intcon,INTF) ){ // INT interrupt
clear_bit(intcon,INTF); // reset flag
}
if ( test_bit(intcon,RBIF) ){ // RB port change interrupt
port_b_val = portb; // clear mismatch
clear_bit(intcon,RBIF);
}
if ( test_bit(pir1, RCIF) ){ // Char received will be in RCREG
if( test_bit(rcsta, FERR) || test_bit(rcsta, OERR) ){
clear_bit(rcsta,CREN);
nop(); // Put a nop between bit operations on the same register to avoid PIC read-modify-write problems
set_bit(rcsta,CREN);
}
handleReceivedChar(rcreg);
}
}
//----------------------------------------------------------------------------
void ms_tick(void)
{
ms_count++;
if( ms_count > blink_interval ){
ms_count=0;
if( led_flag==0 ){
led_flag=1;
set_bit(porta,0); // led1=1;
}else{
led_flag=0;
clear_bit(porta,0); // led1=0;
}
}
}
//-----------------------------------------------------------------------------
void main()
{
disable_interrupt( GIE );
adcon1=0x06;
led_flag=0;
blink_interval=500; // Default blink on/off interval of 500 ms yelds 1 blink/sec
ms_count=0;
option_reg=4; // set prescaler to 1:32
porta=00000001b;
trisa=11111110b;
tmr0 = 0x64; // -156 generates a 1ms interrupt at 20MHz
set_bit(intcon, T0IE);
char i = 0;
// Set up serial comm
trisc = 11000000b;
txsta=0; // Transmit Status Register - init everything to 0
rcsta=0; // Receive Status Register - init everything to 0
// Now set up baud rate
set_bit(txsta,BRGH); // High Baud Rate Select
spbrg=129; // 20MHz: 129=9600, 64=19200 (if BRGH=0 then 129=2400)
// Set SYNC to 0 for Async mode
clear_bit(txsta,SYNC); // SYNC=0; // Async Mode
set_bit(rcsta,SPEN); // SPEN=1; // Serial Port Enable
set_bit(txsta,TXEN); // Transmit Enable
set_bit(pie1,TXIE); // Transmit Interrupt Enable
set_bit(rcsta,CREN); // Constant Receive ENable
set_bit(pie1,RCIE); // Receive Interrupt Enable
set_bit(intcon,PEIE); // PEripherial Interrupt Enable
enable_interrupt( GIE );
while( 1 )
{
nop();
}
}
//-----------------------------------------------------------------------------
Copyright © 2002-2006 SourceBoost Technologies