/* * Michael Fernandes * Shirley Gaw * CSE 466 Final Project - Shared Memory with I2C * * Implementation of the serial port interface * * Created: 12/17/2001 * Modified: 12/17/2001 * */ #include #include "Serial.h" #define TIMER_MODE 0x20 // True when a send is in progress bit SERIAL_sendInProgress; // True when receiving a character bit SERIAL_receivingCharacter; // Stores a single character unsigned char* SERIAL_character; // Stores a string unsigned char* SERIAL_string; unsigned char SERIAL_stringIndex; unsigned char SERIAL_delimiter; unsigned char SERIAL_maxSize; // True when receiving a string, busy wait on this to determine if ReceiveString has completed bit SERIAL_receivingString; bit SERIAL_getReceivingString() { return SERIAL_receivingString; } // Used to busy wait until a send has completed void SERIAL_WaitForSend() { while(SERIAL_sendInProgress) { } } // Initialize the processor for serial mode // Must be called before using any of the below functions void Serial_Init(unsigned char baudRate) { // Initialize variables SERIAL_sendInProgress = 0; SERIAL_receivingCharacter = 0; SERIAL_receivingString = 0; // Do not disable all interrupts EA = 1; // Enable serial interrupt ES = 1; // Disable timer 1 overflow interrupt ET1 = 0; // Timer 1 overflow used for serial port receive/transmit clock RCLK = 0; TCLK = 0; // Set timer 1 to 8-bit auto-reload TMOD = TIMER_MODE; // Set timer 1 auto-reload TH1 = baudRate; // Enable timer 1 TR1 = 1; // Enable serial port mode 1 SM1 = 1; // Enable serial reception REN = 1; } // Send a single character void Serial_SendCharacter(unsigned char character) { SERIAL_sendInProgress = 1; SBUF = character; SERIAL_WaitForSend(); } // Send the decimal value of the character void Serial_SendDecimal(unsigned char character) { unsigned char bit_1; unsigned char bit_10; unsigned char bit_100; bit_1 = character % 10; character = character / 10; bit_10 = character % 10; character = character / 10; bit_100 = character % 10; if(bit_100 > 0) { SERIAL_sendInProgress = 1; SBUF = '0' + bit_100; SERIAL_WaitForSend(); SERIAL_sendInProgress = 1; SBUF = '0' + bit_10; SERIAL_WaitForSend(); SERIAL_sendInProgress = 1; SBUF = '0' + bit_1; SERIAL_WaitForSend(); } else if(bit_10 > 0) { SERIAL_sendInProgress = 1; SBUF = '0' + bit_10; SERIAL_WaitForSend(); SERIAL_sendInProgress = 1; SBUF = '0' + bit_1; SERIAL_WaitForSend(); } else { SERIAL_sendInProgress = 1; SBUF = '0' + bit_1; SERIAL_WaitForSend(); } } // Send a string of characters // If delimiter is found, no more of the string is sent (delimiter is not sent) // Else if maxSize characters are sent, no more of the string is sent void Serial_SendString(unsigned char* string, unsigned char delimiter, unsigned char maxSize) { unsigned char index; for(index = 0; index < maxSize; index++) { if(string[index] == delimiter) break; SERIAL_sendInProgress = 1; SBUF = string[index]; SERIAL_WaitForSend(); } } // Send a new line void Serial_SendNewLine() { // Line feed SERIAL_sendInProgress = 1; SBUF = 10; SERIAL_WaitForSend(); // Carriage return SERIAL_sendInProgress = 1; SBUF = 13; SERIAL_WaitForSend(); } // Receive a character void Serial_ReceiveCharacter(unsigned char* character) { SERIAL_character = character; SERIAL_receivingCharacter = 1; while(SERIAL_receivingCharacter) { } } // Receive a string of characters // If delimiter is received, the string is returned terminated by the delimiter // Else if maxSize-1 characters are received, the delimiter is added no matter what void Serial_ReceiveString(unsigned char* string, unsigned char delimiter, unsigned char maxSize) { SERIAL_string = string; SERIAL_delimiter = delimiter; SERIAL_maxSize = maxSize; SERIAL_stringIndex = 0; SERIAL_receivingString = 1; } void serialInterrupt() interrupt 4 { unsigned char tmp; // Interrupt was caused by a serial read if(RI == 1) { // Reset the read interrupt flag RI = 0; // Store the byte from the serial buffer tmp = SBUF; // Echo everything SBUF = tmp; // Only store characters if a receive has been called if(SERIAL_receivingString) { if(tmp == SERIAL_delimiter) { SERIAL_string[SERIAL_stringIndex] = SERIAL_delimiter; // No longer receiving a string SERIAL_receivingString = 0; } else { if(SERIAL_stringIndex == (SERIAL_maxSize-1)) { SERIAL_string[SERIAL_stringIndex] = SERIAL_delimiter; // No longer receiving a string SERIAL_receivingString = 0; } else { SERIAL_string[SERIAL_stringIndex] = tmp; SERIAL_stringIndex++; } } } else if(SERIAL_receivingCharacter) { *SERIAL_character = tmp; // No longer receiving a character SERIAL_receivingCharacter = 0; } // Echo back to screen SBUF = tmp; } // Interrupt was caused by a serial transfer else { // Reset the transfer interrupt flag TI = 0; // Send no longer in progress SERIAL_sendInProgress = 0; } }