// // // hello.echo.45.c // // 9600 baud serial echo hello-world program // // Neil Gershenfeld // CBA MIT 10/5/08 // // (c) Massachusetts Institute of Technology 2008 // Permission granted for experimental and personal use; // license for commercial sale available from MIT. // // #include #include #include #define tx_pin PB2 // transmit pin #define rx_pin PB3 // receive pin #define led_pin PB4 // LED pin #define bit_delay_time 104 // bit delay, 1/9600 in usec for 8 MHZ/8 #define char_delay_time 1 // char delay time, in ms #define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay #define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay #define char_delay() _delay_ms(char_delay_time) // RS232 char delay #define output(pin) (DDRB |= byte(pin)) // set pin for output #define set(pin) (PORTB |= byte(pin)) // set pin in PORTB #define clear(pin) (PORTB &= ~(byte(pin))) // clear pin in PORTB #define byte(bit) (1 << bit) // byte with bit set #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set #define pin_test(bit) (PINB & (1 << bit)) //test for pin test char get_char() { // // read and return a character // assumes no line driver (doesn't invert bits) // unsigned char rxbyte=0; while (! pin_test(rx_pin)) // // wait for start bit // ; // // delay to middle of first data bit // half_bit_delay(); bit_delay(); // // read data bits // if pin_test(rx_pin) rxbyte |= (0 << 0); else rxbyte |= (1 << 0); bit_delay(); if pin_test(rx_pin) rxbyte |= (0 << 1); else rxbyte |= (1 << 1); bit_delay(); if pin_test(rx_pin) rxbyte |= (0 << 2); else rxbyte |= (1 << 2); bit_delay(); if pin_test(rx_pin) rxbyte |= (0 << 3); else rxbyte |= (1 << 3); bit_delay(); if pin_test(rx_pin) rxbyte |= (0 << 4); else rxbyte |= (1 << 4); bit_delay(); if pin_test(rx_pin) rxbyte |= (0 << 5); else rxbyte |= (1 << 5); bit_delay(); if pin_test(rx_pin) rxbyte |= (0 << 6); else rxbyte |= (1 << 6); bit_delay(); if pin_test(rx_pin) rxbyte |= (0 << 7); else rxbyte |= (1 << 7); return rxbyte; } void put_char(char txchar) { // // print the character in txchar // assumes no line driver (doesn't invert bits) // // start bit // set(tx_pin); bit_delay(); // // data bits // if bit_test(txchar,0) clear(tx_pin); else set(tx_pin); bit_delay(); if bit_test(txchar,1) clear(tx_pin); else set(tx_pin); bit_delay(); if bit_test(txchar,2) clear(tx_pin); else set(tx_pin); bit_delay(); if bit_test(txchar,3) clear(tx_pin); else set(tx_pin); bit_delay(); if bit_test(txchar,4) clear(tx_pin); else set(tx_pin); bit_delay(); if bit_test(txchar,5) clear(tx_pin); else set(tx_pin); bit_delay(); if bit_test(txchar,6) clear(tx_pin); else set(tx_pin); bit_delay(); if bit_test(txchar,7) clear(tx_pin); else set(tx_pin); bit_delay(); // // stop bit // clear(tx_pin); bit_delay(); } void print_string(char *str) { // // print the null-terminated program memory string str // while (pgm_read_byte(str) != 0x00) put_char(pgm_read_byte(str++)); char_delay(); } void blink() { // // blink the LED // set(led_pin); _delay_ms(10); clear(led_pin); } char message[] PROGMEM = "received character: "; int main(void) { unsigned char rxbyte; output(tx_pin); output(led_pin); clear(tx_pin); while (1) { rxbyte = get_char(); print_string(message); put_char(rxbyte); put_char('\n'); blink(); } }