- /*
- Title: SerialCom.c
- Date Created: 6/9/2009
- Last Modified: 6/9/2009
- Target: Atmel ATmega168
- Environment: AVR-GCC
- Note: the makefile is expecting a '168 with a 16 MHz crystal.
- Adapted from the Arduino sketch "Serial Call and Response," by Tom Igoe.
- // This program sends an ASCII A (byte of value 65) on startup
- // and repeats that until it gets some data in.
- // Then it waits for a byte in the serial port, and
- // sends three (faked) sensor values whenever it gets a byte in.
- Written by Windell Oskay, http://www.evilmadscientist.com/
- Copyright 2009 Windell H. Oskay
- Distributed under the terms of the GNU General Public License, please see below.
- Additional license terms may be available; please contact us for more information.
- More information about this project is at
- http://www.evilmadscientist.com/article.php/peggy
- */
- #include <avr/io.h>
- #define F_CPU 16000000 // 16 MHz oscillator.
- #define BaudRate 9600
- #define MYUBRR (F_CPU / 16 / BaudRate ) - 1
- void delayLong()
- {
- unsigned int delayvar;
- delayvar = 0;
- while (delayvar <= 65500U)
- {
- asm("nop");
- delayvar++;
- }
- }
- unsigned char serialCheckRxComplete(void)
- {
- return( UCSR0A & (1<<RXC0)) ; // nonzero if serial data is available to read.
- }
- unsigned char serialCheckTxReady(void)
- {
- return( UCSR0A & (1<<UDRE0) ) ; // nonzero if transmit register is ready to receive new data.
- }
- unsigned char serialRead(void)
- {
- while (serialCheckRxComplete() == 0) // While data is NOT available to read
- {;;}
- return UDR0;
- }
- void serialWrite(unsigned char DataOut)
- {
- while (serialCheckTxReady() == 0) // while NOT ready to transmit
- {;;}
- UDR0 = DataOut;
- }
- void establishContact() {
- while (serialCheckRxComplete() == 0) {
- serialWrite('H');
- // serialWrite(65U);
- delayLong();
- delayLong();
- delayLong();
- delayLong();
- delayLong();
- delayLong();
- delayLong();
- }
- }
- int main (void)
- {
- //Interrupts are not needed in this program. You can optionally disable interrupts.
- //asm("cli"); // DISABLE global interrupts.
- DDRD = (1<<1); // portd, pin 1 as output, TXD pin
- DDRB = (1<<0) | (1<<1) | (1<<3) | (1<<5);
- //Serial Initialization
- /*Set baud rate */
- UBRR0H = (unsigned char)(MYUBRR>>8);
- UBRR0L = (unsigned char) MYUBRR;
- /* Enable receiver and transmitter */
- UCSR0B = (1<<RXEN0)|(1<<TXEN0);
- /* Frame format: 8data, No parity, 1stop bit */
- //UCSR0C = (3<<UCSZ00); //== 00000110
- //UCRS0C |= (1<<1) | (1<<2); //these settings are also the chip default, so not needed
- int inByte = 0; // incoming serial byte
- PORTB |= (1<<1); // Turn on LED @ PB1
- establishContact(); // send a byte to establish contact until Processing responds
- PORTB &= 253U; // Turn off LED
- for (;;) {
- if (serialCheckRxComplete()) {
- PORTB |= (1<<1); // Turn on LED @ PB1
- inByte = serialRead();
- serialWrite(inByte);
- PORTB &= 253U; // Turn off LED
- }
- }
- return 0;
- }