UARTCODE
//RS232 settings
#define tris_a 0111b
#define tris_b 11111111b
#define tris_c 11111111b
/*------------------------------------------------------------------------------*/
/******************************* Compiler Pragmas *******************************/
/*------------------------------------------------------------------------------*/
// Timing settings
#pragma TURBO_MODE 1
#pragma CLOCK_FREQ 50000000
/*------------------------------------------------------------------------------*/
/*********************** IO Pin and Status Pin Assignments **********************/
/*------------------------------------------------------------------------------*/
/* RA Port */
#define RX_PIN 2
#define TX_PIN 3
/* STATUS */
#define ZERO 2
#define CARRY 0
// [9600] baud - Sampling Rate = ~32 /*###### Tested ######*/
//#define BAUD_BIT 5 /* These 3 definitions were hardcoded into the UART code */
//#define START_DELAY 32+16+1 /* if you look at my comments in the UART code, you can see */
//#define INT_PERIOD 163 /* where I hardcoded them in, so you can change baud rate */
/* in the future */
/*----------------------------------------------------------------*/
/** Absolute Addresses for UART Variables - General Purpose Regs **/
/*----------------------------------------------------------------*/
char tx_high@248; /* ISR: hi byte to transmit */
char tx_low@249; /* ISR: low byte to transmit */
char tx_count@250; /* ISR: number of bits sent */
char tx_divide@251; /* ISR: xmit timing (/16) counter */
char rx_count@252; /* ISR: number of bits received */
char rx_divide@253; /* ISR: receive timing counter */
char rx_byte@254; /* ISR: buffer for incoming byte */
/*------------------------------------------------------------------------------*/
/******************** GLOBAL REGISTER DEFINITIONS *******************************/
/*------------------------------------------------------------------------------*/
char flags;
char ctemp = 0x00;
short stemp = 0x0000;
void interrupt()
{
goto isr_code;
isr_code:
/*------------------------------------*/
transmit:
asm
{
bank _tx_divide
clrb _tx_divide.5 ;/* (tx_divide.baud_bit) clear xmit timing count flag */
inc _tx_divide ;/* (tx_divide) only execute the transmit routine */
setb 3.2 ;/* (STZ) Set zero flag for test */
snb _tx_divide.5 ;/* (tx_divide.baud_bit) every 2^baud_bit interrupt */
test _tx_count ;/* (tx_count) are we sending? */
snb 3.2 ;/* (SNZ) (required for jz instruction) */
jmp _receive ;/* if not, go to :receive */
clrb 3.0 ;/* (CLC) yes, ready stop bit */
rr _tx_high ;/* (tx_high) and shift to next bit */
rr _tx_low ;/* (tx_low) */
dec _tx_count ;/* (tx_count) decrement bit counter */
}
if ((tx_low & 0x20) == 0) /* output next bit */
{ /* ( Rewritten MOVB instruction */
output_high_port_a(TX_PIN); /* movb tx_pin,/tx_low.6 ) */
}
else
{
output_low_port_a(TX_PIN);
}
/*------------------------------------*/
receive:
if (input_pin_port_a(RX_PIN) == 0) /* get current rx bit */
{ /* ( Rewritten MOVB instruction */
clear_bit(STATUS,CARRY); /* movb c,rx_pin ) */
}
else
{
set_bit(STATUS,CARRY);
}
asm
{
bank _rx_count
test _rx_count ;/* (rx_count) currently receiving byte? */
sb 3.2 ;/* (SZ)( required for jnz instruction ) */
jmp _rxbit ;/* if so, jump ahead */
mov w,#9 ;/* in case start, ready 9 bits */
sb 3.0 ;/* (SC) skip ahead if not start bit */
mov _rx_count,w ;/* (rx_count)it is, so renew bit count */
mov w,#49 ;/* (START_DELAY) ready 1.5 bit periods */
mov _rx_divide,w ;/* (rx_divide) */
}
/*------------------------------------*/
rxbit:
asm
{
bank _rx_divide
decsz _rx_divide ;/* (rx_divide) middle of next bit? */
jmp _rxdone ;/* ( rewritten for djnz instruction, */
;/* djnz rx_divide,_rxdone ) */
setb _rx_divide.5 ;/* (rx_divide.baudbit) yes, ready 1 bit period */
dec _rx_count ;/* (rx_count) last bit? */
sb 3.2 ;/* (SZ) if not */
rr _rx_byte ;/* (rx_byte) then save bit */
snb 3.2 ;/* (SNZ) if so */
bank _flags
setb _flags.0 ;/* (flags.RX_FLAGS)then set flag */
}
rxdone:
asm
{
mov w,#-163 ;/* (INT_PERIOD) interrupt every 'int_period' clk */
retiw ;/* exit interrupt */
}
}
/*------------------------------------------------------------------------------*/
/******************** SUBROUTINE[PUT_CHAR] - Transmit a byte ********************/
/*------------------------------------------------------------------------------*/
void put_char(char data)
{
asm
{
bank param00_put_char
mov w,param00_put_char ; /* read in byte to be written. */
}
pb_wait:
asm
{
bank _tx_count
test _tx_count ;/* (TX_COUNT) wait for not busy */
sb 3.2 ;/* (SZ) */
jmp _pb_wait
not w ;/* ready bits (inverse logic) */
bank _tx_high
mov _tx_high,w ;/* (tx_high) store data byte */
setb _tx_low.7 ;/* (tx_low) set up start bit */
mov w,#10 ;/* 1 start + 8 data + 1 stop bit */
mov _tx_count,w ;/* (TX_COUNT) */
ret ;/* leave and fix page bits */
}
}
/*------------------------------------------------------------------------------*/
/************* SUBROUTINE[PUT_STRING] - Send string out serial port *************/
/*------------------------------------------------------------------------------*/
void put_string(const char* text)
{
char i = 0;
while( text[i] != 0 )
put_char( text[i++] );
}
/*------------------------------------------------------------------------------*/
/*********** SUBROUTINE[PUT_HEX_BYTE] - Send a Hex byte (2 digits) **************/
/*------------------------------------------------------------------------------*/
void put_hex_byte(char data)
{
char temp;
temp = data;
temp = temp >> 4;
temp = 0x0f & temp;
if ((temp >= 0) & (temp <= 9))
{
temp = temp + 48;
}
else
{
temp = temp + 55;
}
put_char(temp);
temp = 0x0f & data;
if ((temp >= 0) & (temp <= 9))
{
temp = temp + 48;
}
else
{
temp = temp + 55;
}
put_char(temp);
}
/*------------------------------------------------------------------------------*/
/*********** SUBROUTINE[PUT_HEX_WORD] - Send a Hex word (4 digits) **************/
/*------------------------------------------------------------------------------*/
void put_hex_word (short data)
{
char ctemp;
asm
{
bank param00_put_hex_word
mov w,param00_put_hex_word+1
bank _ctemp_put_hex_word
mov _ctemp_put_hex_word, w
}
put_hex_byte(ctemp);
asm
{
bank param00_put_hex_word
mov w,param00_put_hex_word
bank _ctemp_put_hex_word
mov _ctemp_put_hex_word, w
}
put_hex_byte(ctemp);
}
/*------------------------------------------------------------------------------*/
/********* SUBROUTINE[GET_CHAR] - Receive a byte from the serial port ***********/
/*------------------------------------------------------------------------------*/
char get_char(void)
{
getit:
asm
{
bank _flags
sb _flags.0 ;/* (flags.#RX_FLAG) wait till byte is received */
jmp _getit
clrb _flags.0 ;/* (flags.#RX_FLAG) reset the receive flag */
bank _rx_byte
mov w,_rx_byte ;/* (rx_byte) */
ret
}
}
/*------------------------------------------------------------------------------*/
/****** SUBROUTINE[GET_HEX_BYTE] - Capture an 8bit ascii Hex number (2 dig) *****/
/*------------------------------------------------------------------------------*/
char get_hex_byte()
{
char nibble, byte, count;
byte = 0;
count = 0;
while (count != 2)
{
nibble = get_char();
if ((nibble >= '0') && (nibble <= '9'))
{
asm
{
bank _byte_get_hex_byte
swap _byte_get_hex_byte
}
byte = byte | (nibble - '0');
count++;
}
else
{
if (nibble >= 'a')
{
nibble = nibble & 0xDF;
}
if ((nibble >= 'A') && (nibble <= 'F'))
{
asm
{
bank _byte_get_hex_byte
swap _byte_get_hex_byte
}
byte = byte | (nibble - ('A' - 10));
count++;
}
}
}
return(byte);
}
/*------------------------------------------------------------------------------*/
/***** SUBROUTINE[GET_HEX_WORD] - Capture an 16bit ascii Hex number (4 dig) *****/
/*------------------------------------------------------------------------------*/
short get_hex_word()
{
short byte, word;
byte = get_hex_byte();
asm
{
bank _byte_get_hex_word
mov w,_byte_get_hex_word
bank _word_get_hex_word
mov _word_get_hex_word+1,w
}
byte = get_hex_byte();
asm
{
bank _byte_get_hex_word
mov w,_byte_get_hex_word
bank _word_get_hex_word
mov _word_get_hex_word,w
}
return(word);
}
//***********************************************
//MAIN CODE
//***********************************************
main()
{
set_tris_a(tris_a);
set_tris_b(tris_b);
set_tris_c(tris_c);
set_option(0x9F);
while(1)
{
put_string("\r\nHELLO WORLD get_char = ");
ctemp = get_char();
put_char(ctemp);
put_string("\r\n");
put_string("HELLO EARTH get_hex_byte = ");
ctemp = get_hex_byte();
put_hex_byte(ctemp);
put_string("\r\n");
put_string("HELLO MARS get_hex_word = ");
stemp = get_hex_word();
put_hex_word(stemp);
put_string("\r\n");
}
}
Copyright© 2000 John Wynia