/* bb_serial.c BitBang functions for serial communication with any pin */ /* for convenience we use PD0 and PD1 as they are allready connected to terminal */ /* The USART is not used */ /* bit_time = 1 / baud_rate 9600 Baud => 104 us bit_time */ // Arduino UNO R3 // AVR_ATmega328P #define F_CPU 16000000UL #include // register names/addresses and bit names/numbers #include void init_BB( void ); unsigned char getchar_BB( void ); void putchar_BB( unsigned char ); void string_out_BB( char * ); void string_in_BB( char * ); #define MAX_STRING 12 /* Redefine if to use bitbanging with other pins! */ #define RX_BBpin PD0 #define RX_DDR DDRD #define RX_PORT PORTD #define RX_PIN PIND #define TX_BBpin PD1 #define TX_DDR DDRD #define TX_PORT PORTD int main() { char text_input[ MAX_STRING ]; unsigned char c; init_BB( ); string_out_BB("Echo strings with BitBanging routines\r\n"); while(1) { string_in_BB( text_input ); string_out_BB("\r\nYour input:\r\n"); string_out_BB( text_input ); } } /* *********************************** */ /* FUNCTIONS */ /* *********************************** */ void init_BB( void ) { RX_DDR &= ~( 1 << RX_BBpin ); // "0" pin 2 PD0 direction is input used for rxd TX_DDR |= ( 1 << TX_BBpin ); // "1" pin 3 PD1 direction is output used for txd TX_PORT |= ( 1 << TX_BBpin ); // Marking line // USART will not be turned on. Just happens to use USART pins. } unsigned char getchar_BB( void ) // recieves one char, blocking { unsigned char ch = 0, bit_mask; while( ( RX_PIN & ( 1 << RX_BBpin ) ) != 0 ){} // wait for startbit _delay_us( 156 ); // 1.5 bit_time for( bit_mask = 0b00000001 ; ; bit_mask <<= 1 ) { if( ( RX_PIN & ( 1 << RX_BBpin ) ) !=0 ) ch |= bit_mask; _delay_us( 104 ); // 1 bit_time if( bit_mask == 0b10000000 ) break; } _delay_us( 45 ); // less than one stopbit return (ch); } void putchar_BB( unsigned char ch ) { unsigned char bitcount; TX_PORT &= ~( 1 << TX_BBpin ); // generate start bit _delay_us( 104 ); // bit_time for( bitcount = 0; bitcount < 8; bitcount++ ) { if (ch & 0x01) TX_PORT |= ( 1 << TX_BBpin ); else TX_PORT &= ~( 1 << TX_BBpin ); ch >>= 1; _delay_us( 104 ); // bit_time } TX_PORT |= ( 1 << TX_BBpin ); // marking line _delay_us( 104*2 ); // duration two stop bits } void string_out_BB( char * string ) // use for strings in RAM { while ( * string != '\0' ) putchar_BB( *string ++ ); } void string_in_BB( char * string ) // Expects '\r' + '\n' to end input. Windows style. { unsigned char charCount, c; for( charCount = 0; ; charCount++ ) { c = getchar_BB( ); /* input 1 character */ string[charCount] = c; /* store the character */ if(c=='\r' ) charCount-- ; /* skip and wait for '\n' to end input */ if( c=='\n'){ string[charCount] = '\0'; return; } /* end of string and end of input */ if( charCount == (MAX_STRING-1)) charCount-- ; /* prevent buffer overflow */ } } /* *********************************** */ /* HARDWARE */ /* *********************************** */ /* Chip ATMega328 Arduino Uno R3 stackable header _______ Digital: _____/ \__ Analog: ______________ ______________ txd ->-|D00 >RXD A5|- | \/ | rxd -<-|D01 -(D01)-|03 PD1/TXD PC3 26|-(A3)- -|D04 A1|- -(D02)-|04 PD2/INT0 PC2 25|-(A2)- -|D05~ A0|- -(D03)-|05 PD3/INT1/PWM PC1 24|-(A1)- -|D06~ | Power: -(D04)-|06 PD4 PC0 23|-(A0)- -|D07 Vin|- +5V ---|07 VCC GND 22|--- Gnd | GND|- Gnd ---|08 GND AREF 21|--- Vin -|D08 GND|- Xtal |X|--|09 PB6/OSC1 AVCC 20|--- +5V -|D09~ +5V|- 16MHz |X|--|10 PB7/OSC2 SCK/PB5 19|-(D13)- -|D10~ +3.3V|- -(D05)-|11 PD5/PWM MISO/PB4 18|-(D12)- -|D11~ Res|- -(D06)-|12 PD6/PWM PWM/MOSI/PB3 17|-(D11)- -|D12 IOREF|- -(D07)-|13 PD7 PWM/SS'/PB2 16|-(D10)- -|D13 LED --- | -(D08)-|14 PB0 PWM/PB1 15|-(D09)- -|GND | |______________________________| -|AREF | -|SCL | -|SDA | |________________| */