#include #include #include //interrupts #include #include #include "pinout.h" #include "uart.h" #include "i2cmaster.h" #include "DS3231.h" #define RX_INPUT_BUFFER_SIZE 92 void check_dip_switches(void); void setup(void); void set_PWM_duty(int dutycycle); unsigned char SR_Buffer[6]; const unsigned char number_Font[10] = { 0b11011110, //0 0b00000110, //1 0b11101010, //2 0b01101110, //3 0b00110110, //4 0b01111100, //5 0b11111100, //6 0b00001110, //7 0b11111110, //8 0b01111110 //9 }; void clear_SR_Buffer(void) { for (uint8_t i = 0; i < 6; i++) { SR_Buffer[i] = 0; } } void print_SR_Buffer(void) { PORTC &= ~(LATCH_SR); for (uint8_t i = 0; i < 6; i++) { SPDR = SR_Buffer[i]; while (!(SPSR & (1 << SPIF))); //warten auf transferabschluss } PORTC |= LATCH_SR; } int8_t parse_nmea_gps(char input_string[RX_INPUT_BUFFER_SIZE], uint8_t output_buffer[3]){ char* token = strsep(&input_string, ","); if(!strcmp("$GPRMC", token)){ char* time = strsep(&input_string, ","); if(!strlen(time)){ // no valid time available return -2; } // craft bcd values output_buffer[2] = (time[0] - 48) << 4; output_buffer[2] |= time[1] - 48; output_buffer[1] = (time[2] - 48) << 4; output_buffer[1] |= time[3] - 48; output_buffer[0] = (time[4] - 48) << 4; output_buffer[0] |= time[5] - 48; return 0; } return -1; } int main(void){ setup(); while(1){ _delay_ms(200); check_dip_switches(); uint8_t clock[3]; DS3231_read(clock); for(uint8_t i=0; i < 3; i++){ SR_Buffer[5-(2*i)] = number_Font[clock[i] & 0x0F]; SR_Buffer[5-(2*i)-1] = number_Font[(clock[i] & 0xF0)>>4]; } print_SR_Buffer(); } } void check_dip_switches() { if (PINB & DIP_1) { PORTC |= ENABLE_TUBE_PSU; PORTA &= ~ENABLE_TUBE_SUPPLY; // PORTB |= STATUS_LED_B; } else { PORTC &= ~(ENABLE_TUBE_PSU); PORTA |= (ENABLE_TUBE_SUPPLY); // PORTB &= ~STATUS_LED_B; } } void setup(){ DDRA = ENABLE_TUBE_SUPPLY; DDRB = STATUS_LED_B | STATUS_LED_C | MOSI | CLK; DDRC = LATCH_SR | ENABLE_SR | DOT | ENABLE_TUBE_PSU; DDRD = RESET_SR | TUBE_LED; //-------------------------- // SPI //-------------------------- SPCR = (1 << SPE) | //enable SPI (1 << MSTR) | //SPI als Master starten (1 << SPR0) | //clock-prescaler LSB (1 << SPR1) | //clock-prescaler MSB (0 << SPIE) | //complete transfer/ recive interrupt (0 << CPOL) | (0 << CPHA) | (0 << DORD); //MSB first = 0 SPSR = (1 << SPI2X);// | //clock- prescaler double speed PORTC &= ~LATCH_SR; //latch low, sonst startet SPI nicht PORTC |= LATCH_SR; PORTD |= RESET_SR; //Setzte Reset auf HIGH (active LOW) PORTC &= ~(ENABLE_SR); //Aktiviert Shiftregister (active LOW) //-------------------------- // Externe Interrupts //-------------------------- //External Interrupt Mask Register EIMSK |= (1 << INT0) | //Aktiviere Interrupt INT0 (1 << INT1); //Aktiviere Interrupt INT1 //External Interrupt Control Register A EICRA |= (0 << ISC10) | //Interrupt bei jedem Pegelwechsel auf INT1 (1 << ISC11) | (1 << ISC00) | //Interrupt bei jedem Pegelwechsel auf INT0 (1 << ISC01); //-------------------------- // Timer + Zeitinterrupts //-------------------------- //PWM-Timer //OC2A set when upcounting, clear when down counting TCCR2A = (1< 0){ async_input_buffer[async_buffer_pointer] = 0; // Null terminate string async_buffer_pointer=0; uint8_t gps_time[3]; int8_t err = parse_nmea_gps(async_input_buffer, gps_time); if(!err){ PORTB |= STATUS_LED_C; //if(rtc_time[0] != gps_time[0] || rtc_time[1] != gps_time[1] || rtc_time[2] != gps_time[2]) DS3231_write(gps_time); } else if(err == -2) PORTB &= ~STATUS_LED_C; } }