For the efficient lounge project, we plan to record room status changes in the lounge and upload it to a computer or server. The data collected will be used to for testing purposes and later for viewing by the general public on the webserver.
Most of the following code was borrowed from code written by jazzman, surfingcat, afterburn and teknick. Their original project and code can be found here.
The microcontroller was originally connected to another machine running Windows XP. We received text using HyperTerminal (already installed in XP), which was configured to receive at 9.6k baud.
We also successfully received text on a machine running Ubuntu using a program similar to HyperTerminal called minicom. To install minicom, call the following command in the Linux terminal. For Debian/Ubuntu Linux:
sudo apt-get install minicom
For Red hat Linux (RHEL) / CentOS / Fedora Linux, enter:
yum install minicom
To setup minicom:
minicom -s
or if color is supported in the console, call:
minicom -s -c on
Both HyperTerminal and minicom have logging features.
The code was written for the HCS08GB60 microcontroller (in C) using the CodeWarrior IDE.
Since we're programming for a microcontroller and care about how many bits each type uses, we're going to use the following typedef.
typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned long uint32; typedef signed char int8; typedef short int16; typedef long int int32;
Include the following prototypes before main().
//sets up registers for tx //notice setup_Tx has no inputs or outputs so it is essentially a subroutine //called to made the code look neater. void setup_Tx(void); //sends one byte or one char void send_byte(uint8 b); //sends a string //calls send_byte void send_string(const uint8 * str);
Before any of the send functions are usable, setup_Tx() must be called to set up the SCI module. This involves setting up the baud rate and interrupt settings.
The SCIxBDH and SCIxBDL registers are used to configure the baud rate. (See code comments for the formula.)
The SCIxC1 and SCIxC2 are the control registers (see code for comments on what each bit does).
For more information on these registers, refer to the HCS08GB60 datasheet.
Below is the code for setup_Tx(). For our code, we used SCI2 (so we replaced the x with a 2) as our transmitting port since port 1 was used for debugging and loading the code onto the microcontroller.
void setup_Tx(void) { /* Set baud rate register for SCI2 formula: SCI baud rate = BUSCLK/(16×BR) where BR refers to 13 writable bits of the SCIxBDH and DL registers */ //we want baud rate = 9600Hz = 20Mhz/(16xBR) //so BR SHOULD BE 130 or 0x82 //testing the frequency on the oscilloscope did not produce a signal of exactly 9600 baud //so BR had to be lowered to 0x7B SCI2BDH = 0x00; //set H register first SCI2BDL = 0x7B; //set L after H register /* Set SCI control register for SCI2 SCI x Control Register 1 options bit7=0 Normal operation - RxD1 and TxD1 use separate pins bit6=0 SCI clocks do not freeze while CPU is in wait mode bit5=0 Has no effect unless bit7 is set to 1 bit4=0 8-bit mode bit3=0 Idle-line wakeup method bit2=0 Idle character bit count starts after start bit bit1=0 Parity checking disabled bit0=0 Even parity but should not matter since parity checking is disabled SCI x Control Register 2 options bit7=0 Hardware interrupts for transmit data register empty (TDRE) disabled bit6=0 Hardware interrupts for transmission complete (TC) disabled bit5=0 Hardware interrupt for receive data register (RDRF) flag disabled bit4=0 Hardware interrupts from IDLE disabled bit3=1 Transmitter on bit2=0 Receiver off bit1=0 Normal SCI receiver operation, not in standby bit0=0 Do not sent break characters */ SCI2C1 = 0x00; SCI2C2 = 0x08; }
When sending a byte, the transmit data register empty flag (bit-7) of the SCIxS1 register must be checked repeatedly until the data register is ready to receive data. When the data register is empty (i.e. TDRE = 1), one byte of data is sent to the SCxD register.
void send_byte(uint8 b) { while(!(SCI2S1 & 0x80)); //check if transmit data register is empty, TDRE = 1 SCI2D = b; //while empty, write byte to data register } // Send a string out // Calls send_byte() to send each byte until end of string is reached void send_string(const uint8 * str) { __RESET_WATCHDOG(); for(;*str;str++) send_byte(*str); }
Code must be loaded and ran through the CodeWarrior serial monitor so the microcontroller must be attached to a computer at all times. Well what if we want the microcontroller to be free standing and running code on its own? Apparently, we're not suppose to be able to do this without buying more development tools (according to Freescale not to mention they don't provide any documentation on this subject), but fortunately, teknick has previously found a way around this annoyance by removing a few lines of code from the project. Refer to this page. Just make sure to include main() in the function prototypes or the code won't compile.