So back a few years ago since before I moved over working on the ESP family, I was an Atmel junkie. One of the thing’s that came in real handy was working with Software UART and the ATTiny84. It was a real great learning experience and I got really really burned with the DIV8 fuse being enabled on chip’s by default. I wanted to post my work here because I’m sure someone else may need it for the AT84 or 4313 2313 etc etc. Now the code below can be improved but the main thing to really take home is the caluclating the baud sleep while in the function. #define SleepRX9600 104 //= (1/ 9600) #define SleepRX4800 180 //= (1/ 4800) #define sleepTransmitString4800 208 #define sleepTransmitString9600 104 Now one thing to take home is if you want to transfer at 9600 baud over a second just take 1 / baud to get your uS sleep time. After you get it rocking you adjust the numbers to match the clock cycles of your added code. Sending data is almost mirrored logic. In this case I was working with a GPS, Once the string is received you can parse it just as if it is any other string in C.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
void GetGPSData(int UART_INCOMMING_DATAPORT) { PCMSK0 &= ~(1 << UART_GPSRX_INTERRUPT); //Disable Interrupt Trigger for just GPS \ _delay\ _us(SleepRX4800 * 1.5); for (uint8_t i = 0; i < 8; i += 1) { if (PINA & (1 << UART_GPSRX_INTERRUPT)) //RX PIN IS HIGH { uart_GPS_rx_buffer[uart_GPS_rx_buff_end] |= (1 << i); //RX PIN IS HIGH, try not to change any code here its timing sensitive } else { uart_GPS_rx_buffer[uart_GPS_rx_buff_end] &= ~(1 << i); //RX PIN IS LOW } if (i != (UART_RX_BUFFER_SIZE - 1)) {\ _delay\ _us(SleepRX4800); } } if (uart_GPS_rx_buff_end == 0x0) { if (uart_GPS_rx_buffer[0] != '$') { PCMSK0 &= ~(1 << UART_WIFIRX_INTERRUPT); PCMSK0 |= (1 << UART_GPSRX_INTERRUPT); return; } } if (uart_GPS_rx_buffer[uart_GPS_rx_buff_end] == 0x0A) //This checks to see if the Last char that was sent is a LineFeed { uart_GPS_rx_buffer[uart_GPS_rx_buff_end + 1] = 0x00; if (Counter == 3) { transmitstr9600((char * ) "Sending to Cellphone\xd\xa", UART_DEBUG_TX_PIN); transmit((char * ) uart_GPS_rx_buffer, UART_WiFly_TX_PIN); Counter = 0; } else { transmitstr9600((char * ) uart_GPS_rx_buffer, UART_DEBUG_TX_PIN); Counter++; } PCMSK0 |= (1 << UART_WIFIRX_INTERRUPT); uart_GPS_rx_buff_end = 0; for (uint8_t i = 0; i < UART_RX_BUFFER_SIZE; i++) { uart_GPS_rx_buffer[i] = 0; } } else { PCMSK0 |= (1 << UART_GPSRX_INTERRUPT); uart_GPS_rx_buff_end++; } // \ _delay\ _us(sleep); //Get past stop bit } void transmitstr4800(char StringToSend[], int PAPin) { int a = 0; while (StringToSend[a] != 0x0) //Look for Null Terminator { // low for start bit PORTA &= ~(1 << PAPin); //Startbit \ _delay\ _us(sleepTransmitString4800); // data bits for (int i = 0; i <= 7; i++) { if (StringToSend[a] & (1 << i)) { PORTA |= (1 << PAPin); } else { PORTA &= ~(1 << PAPin); }\ _delay\ _us(sleepTransmitString4800); } PORTA |= (1 << PAPin); //Stopbit \ _delay\ _us(sleepTransmitString4800 * 4); a++; } } void UART_INITIALIZE() { uart_GPS_rx_buff_end = 0; uart_GPS_rx_buff_position = 0; for (uint8_t i = 0; i < UART_RX_BUFFER_SIZE; i++) { uart_GPS_rx_buffer[i] = 0; } void UART_INITIALIZE_RX() { /* RX pin input and with pullup */ /* UART_RX_DDR &= ~(1<<UART_GPSRX_PIN); UART_RX_PORT |= 1<<UART_GPSRX_PIN; */ // PCMSK0 |= (1 << UART_WIFIRX_INTERRUPT); //Enable interrupts on GPS PA3 // PCMSK0 |= (1 << UART_GPSRX_INTERRUPT); //Enable interrupts on GPS PA2 sei(); } void UART_EnableRECV() { GIMSK |= (1 << UART_RX_INTERRUPT_PORT); //Enable interrupts period for PCI0 (PCINT7:0), This setups Interrupt for All pins 0-7 } void UART_DisableRECV() { GIMSK |= (1 << UART_RX_INTERRUPT_PORT); //Enable interrupts period for PCI0 (PCINT7:0), This setups Interrupt for All pins 0-7 } |