diff options
| author | Max Christian Pohle | 2017-05-25 19:45:15 +0200 |
|---|---|---|
| committer | Max Christian Pohle | 2017-05-25 19:45:15 +0200 |
| commit | 25d1f4326cce046b245cd224f3e6335c1a6f76b0 (patch) | |
| tree | c6ceee46bab7d5f10ffe2c6465610a77fd0d1019 | |
| parent | e8c784a9502bbaa8d3c47b2fc60884311632d968 (diff) | |
| download | binwatch-mini-25d1f4326cce046b245cd224f3e6335c1a6f76b0.tar.bz2 binwatch-mini-25d1f4326cce046b245cd224f3e6335c1a6f76b0.zip | |
DCF signal recognized and shown
| -rwxr-xr-x | inc/int/dcf77.c | 139 | ||||
| -rwxr-xr-x | inc/int/dcf77.h | 69 | ||||
| -rw-r--r-- | main.c | 49 |
3 files changed, 231 insertions, 26 deletions
diff --git a/inc/int/dcf77.c b/inc/int/dcf77.c new file mode 100755 index 0000000..13af50d --- /dev/null +++ b/inc/int/dcf77.c | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | // vim:set et sw=2 ts=2 tw=120: | ||
| 2 | #include "dcf77.h" | ||
| 3 | |||
| 4 | // returns -1 on error | ||
| 5 | unsigned char getBits(const DCF start, const char len) | ||
| 6 | { | ||
| 7 | static const unsigned char mult[] = {1, 2, 4, 8, 10, 20 ,40 ,80}; | ||
| 8 | /// unsigned char p = 1; //parity | ||
| 9 | unsigned char r = 0; // retval | ||
| 10 | unsigned char i; | ||
| 11 | for(i=0; i<len; i++) | ||
| 12 | r += dcf77[start+i].bit * mult[i]; | ||
| 13 | /// if(dcf77[start+i].bit) | ||
| 14 | /// p ^= 1; | ||
| 15 | return r; | ||
| 16 | } | ||
| 17 | |||
| 18 | void set_dcf_value() | ||
| 19 | { | ||
| 20 | t_current.m = (getBits(DCF_MIN, 7)) - 1; | ||
| 21 | t_current.h = (getBits(DCF_HOUR, 6)); | ||
| 22 | t_current.dd = (getBits(DCF_DAY, 6)); | ||
| 23 | t_current.wd = (getBits(DCF_WEEKDAY, 3)); | ||
| 24 | t_current.mm = (getBits(DCF_MONTH, 5)); | ||
| 25 | t_current.yy = (getBits(DCF_YEAR, 8)); | ||
| 26 | } | ||
| 27 | |||
| 28 | // 7372800/a=10000 | ||
| 29 | // 115200 / a * x = 10000 | ||
| 30 | // 7372800/8/150 | ||
| 31 | |||
| 32 | // interrupt service routine (ISR) for timer 0 A compare match | ||
| 33 | /* | ||
| 34 | ISR(TIMER0A_COMP_vect) // called 10000 times per second (12000000/8/150) | ||
| 35 | { | ||
| 36 | |||
| 37 | } | ||
| 38 | */ | ||
| 39 | ISR(TIMER0_COMPB_vect) | ||
| 40 | { | ||
| 41 | |||
| 42 | } | ||
| 43 | |||
| 44 | ISR(TIMER0_COMPA_vect) | ||
| 45 | { | ||
| 46 | interval++; | ||
| 47 | if (++t_current.ms >= 1000) // one second | ||
| 48 | { | ||
| 49 | t_current.ms = 0; // restart | ||
| 50 | if (++t_current.s > 59) // one minute | ||
| 51 | { | ||
| 52 | t_current.s = 0; // restart | ||
| 53 | if (++t_current.m > 59) // one hour | ||
| 54 | { | ||
| 55 | t_current.m = 0; // restart | ||
| 56 | if (++t_current.h > 23) // one day | ||
| 57 | { | ||
| 58 | t_current.h = 0; // restart | ||
| 59 | t_current.dd++; | ||
| 60 | } | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | ISR(INT0_vect) | ||
| 67 | { | ||
| 68 | } | ||
| 69 | |||
| 70 | ISR(PCINT0_vect) | ||
| 71 | { | ||
| 72 | interval = 1; | ||
| 73 | /// stdout_put_int(interval, uart_putc); | ||
| 74 | /// stdout_put_string("INT0 call\n", uart_putc); | ||
| 75 | // cli(); | ||
| 76 | |||
| 77 | // if(INT0_CONTROL == INT0_RISING_EDGE) | ||
| 78 | // if(MCUCR & (1<<ISC00)) | ||
| 79 | // { | ||
| 80 | if (interval > 1000 && interval < 2000) // 59th second - no rising edge at the beginning | ||
| 81 | { | ||
| 82 | /// if(dcf77_bit == 59) // check if every bit has been transfered | ||
| 83 | // set_dcf_value(); // completely received- apply new time data | ||
| 84 | |||
| 85 | // 59th second: synchronize with receiver... | ||
| 86 | TCNT0 = 0; | ||
| 87 | dcf77_bit = 0; | ||
| 88 | t_current.s = 0; | ||
| 89 | t_current.ms = 0; | ||
| 90 | // t_current.us = 0; | ||
| 91 | // falling edge causes interrupt... | ||
| 92 | // MCUCR &= ~(1 << ISC00); | ||
| 93 | // MCUCR |= (1 << ISC01); | ||
| 94 | // INT0_CONTROL = INT0_FALLING_EDGE; | ||
| 95 | } | ||
| 96 | else // INT0_FALLING_EDGE | ||
| 97 | { | ||
| 98 | dcf77[dcf77_bit++].bit = interval >= 200 ? 1 : 0; | ||
| 99 | |||
| 100 | // rising edge causes interrupt... | ||
| 101 | // MCUCR |= (1 << ISC00); | ||
| 102 | // MCUCR |= (1 << ISC01); | ||
| 103 | // INT0_CONTROL = INT0_RISING_EDGE; | ||
| 104 | // interval = 0; // reset interval to count next interval | ||
| 105 | } | ||
| 106 | |||
| 107 | interval = 0; | ||
| 108 | // sei(); | ||
| 109 | } | ||
| 110 | |||
| 111 | /* | ||
| 112 | void timer_init() | ||
| 113 | { | ||
| 114 | // 7372800/8 | ||
| 115 | // >>>>>> DDRD &= ~((1<<PD2) | (1<<PD3)); // make INT0 and INT1 input-pins | ||
| 116 | |||
| 117 | // Prescaler... | ||
| 118 | // output compare... | ||
| 119 | |||
| 120 | //OCR0 = 152 - 1; | ||
| 121 | //TCCR0 |= (0<<WGM01) | (1<<WGM01); | ||
| 122 | |||
| 123 | // ICNC1 (Input Capture Noise Canceler (4 CKs) Timer/Counter 1 | ||
| 124 | // ICES1 (Input Capture Edge Select Timer/Counter 1) - 1:increasing 0:falling | ||
| 125 | // CSx: set prescaler (010 means 8) | ||
| 126 | /// TCCR1B = (1<<ICNC1) | (1<<ICES1) | (0<<CS12) | (1<<CS11) | (0<<CS10); | ||
| 127 | // OCIE0: Output Compare Match Interrupt Enable | ||
| 128 | // TICIE: Timer/Counter Input Capture Interrupt Enable | ||
| 129 | |||
| 130 | // interrupts_init... | ||
| 131 | // General Interrupt Mask Register (enables interrupts) | ||
| 132 | GIMSK |= (1<<INT0); | ||
| 133 | // GICR |= (1<<INT0); | ||
| 134 | // MCU Control Register (controls CPU-behaviours like interrupts & sleepmode) | ||
| 135 | MCUCR |= (1<<ISC01) | (1<<ISC00); // any logical change generates interrupt | ||
| 136 | INT0_CONTROL = INT0_RISING_EDGE; // going to toggle int0-behaviour | ||
| 137 | /// loworhigh.bit = 0; | ||
| 138 | } | ||
| 139 | */ | ||
diff --git a/inc/int/dcf77.h b/inc/int/dcf77.h new file mode 100755 index 0000000..e47ca4e --- /dev/null +++ b/inc/int/dcf77.h | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | #ifndef CLOCK_H | ||
| 2 | #define CLOCK_H | ||
| 3 | /* this dcf77-module relies on a accuarate clock (crystal) for receiving | ||
| 4 | * the dcf-signal. therefor the clock is going to work as expected, | ||
| 5 | * even with no dcf77-signal available. | ||
| 6 | * receivement is automatically turned on, if the avr is connected to the | ||
| 7 | * signal via INT0. if there is no signal the clock will not be set (K.I.S.S.) | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | #include <avr/io.h> | ||
| 11 | #include <avr/interrupt.h> | ||
| 12 | |||
| 13 | #include <stdint.h> | ||
| 14 | |||
| 15 | #define INT0_CONTROL MCUCR | ||
| 16 | // #define INT0_FALLING_EDGE 0x02 | ||
| 17 | // #define INT0_RISING_EDGE 0x03 | ||
| 18 | #define INT0_FALLING_EDGE (1<<ISC01) | ||
| 19 | #define INT0_RISING_EDGE (1<<ISC01 | 1<<ISC00) | ||
| 20 | #define INT0_EDGE_ANY (1<<ISC00) | ||
| 21 | |||
| 22 | typedef struct | ||
| 23 | { | ||
| 24 | volatile unsigned char bit : 1; | ||
| 25 | } Bit; | ||
| 26 | |||
| 27 | typedef struct | ||
| 28 | { | ||
| 29 | uint16_t h ; // hour | ||
| 30 | uint16_t m ; // minute | ||
| 31 | uint16_t s ; // second | ||
| 32 | uint16_t ms; // milli second | ||
| 33 | uint8_t yy; // year | ||
| 34 | uint8_t mm; // month | ||
| 35 | uint8_t dd; // day | ||
| 36 | uint8_t wd; // weekday | ||
| 37 | } Time; | ||
| 38 | |||
| 39 | typedef enum | ||
| 40 | { | ||
| 41 | DCF_FIRST = 0, // start of a new minute (note: always 0) | ||
| 42 | DCF_WEATHER = 14, // proprietary :-( | ||
| 43 | DCF_ANTENNA = 15, // 0: normal, 1: replacement | ||
| 44 | DCF_DST = 16, // daylight saving time: this hour new time... | ||
| 45 | DCF_MEZ = 17, // 'summer-time' | ||
| 46 | DCF_MESZ = 18, // 'winter-time' | ||
| 47 | DCF_DBLSEC = 19, // one extra second gonna be inserted | ||
| 48 | DCF_START = 20, // begin of time-info (note: always 1) | ||
| 49 | DCF_MIN = 21, // 7 bit | ||
| 50 | DCF_MINP = 28, // parity bit for minutes | ||
| 51 | DCF_HOUR = 29, // 6 bit | ||
| 52 | DCF_HOURP = 35, // parity bit for hours | ||
| 53 | DCF_DAY = 36, // 6 bit | ||
| 54 | DCF_WEEKDAY = 42, // 3 bit | ||
| 55 | DCF_MONTH = 45, // 5 bit | ||
| 56 | DCF_YEAR = 50, // 8 bit | ||
| 57 | DCF_DATEP = 58 // parity bit for date | ||
| 58 | } DCF; | ||
| 59 | |||
| 60 | volatile Bit dcf77[60]; | ||
| 61 | volatile uint8_t dcf77_bit; | ||
| 62 | volatile Time t_current; | ||
| 63 | volatile uint16_t interval; | ||
| 64 | |||
| 65 | /// void getBits(volatile unsigned char* target, const DCF start, const char len, const DCF parity); | ||
| 66 | /// void set_dcf_value(); | ||
| 67 | /// void interrupts_init(); | ||
| 68 | |||
| 69 | #endif | ||
| @@ -25,30 +25,19 @@ static inline void BIT_CLEAR(volatile uint8_t* target, uint8_t bit) { *target &= | |||
| 25 | * | 25 | * |
| 26 | */ | 26 | */ |
| 27 | 27 | ||
| 28 | void pulse_sck() | ||
| 29 | { | ||
| 30 | PORTB |= (1 << PB2); | ||
| 31 | PORTB ^= (1 << PB2); | ||
| 32 | |||
| 33 | } | ||
| 34 | |||
| 35 | void print_data(uint16_t data) | 28 | void print_data(uint16_t data) |
| 36 | { | 29 | { |
| 37 | //BIT_CLEAR(&PORTB, PB4); | 30 | BIT_CLEAR(&PORTB, PB3); |
| 38 | //BIT_SET(&PORTB, PB4); | 31 | for (char i = 0; i < 16; i++) |
| 39 | |||
| 40 | for (uint16_t i = 0; i < 16; i++) | ||
| 41 | { | 32 | { |
| 42 | data & 0x1 << i | 33 | data & 0x1 << i |
| 43 | ? BIT_SET(&PORTB, PB4) | 34 | ? BIT_SET(&PORTB, PB4) |
| 44 | : BIT_CLEAR(&PORTB, PB4); | 35 | : BIT_CLEAR(&PORTB, PB4); |
| 45 | pulse_sck(); | 36 | // pulse sck... |
| 37 | BIT_SET(&PORTB, PB2); | ||
| 38 | BIT_CLEAR(&PORTB, PB2); | ||
| 46 | } | 39 | } |
| 47 | //BIT_CLEAR(&PORTB, PB4); | ||
| 48 | // pulse_sck(); | ||
| 49 | BIT_CLEAR(&PORTB, PB3); | ||
| 50 | BIT_SET(&PORTB, PB3); | 40 | BIT_SET(&PORTB, PB3); |
| 51 | |||
| 52 | } | 41 | } |
| 53 | 42 | ||
| 54 | int main(void) | 43 | int main(void) |
| @@ -64,27 +53,29 @@ int main(void) | |||
| 64 | 53 | ||
| 65 | 54 | ||
| 66 | // make all pins output pins... | 55 | // make all pins output pins... |
| 67 | DDRB = 0xFF; | 56 | // DDRB = 0xFF; |
| 68 | DDRB &= ~(1 << PB0); // makes PB0 an input pin (INT0) | 57 | DDRB = 0b11111110; |
| 69 | PORTB |= (1 << PB0); // activate input resistor | 58 | PORTB |= 1<<PB0; // activate pullup |
| 59 | PORTB |= 1<<PB1; // activate receiver | ||
| 60 | |||
| 61 | // DDRB &= ~(1 << PB0); // makes PB0 an input pin (INT0) | ||
| 62 | // PORTB |= (1 << PB0); // activate input resistor | ||
| 70 | 63 | ||
| 71 | // activate dcf77-receiver... | 64 | // activate dcf77-receiver... |
| 72 | PORTB &= (1 << PB1); // sets PB1 to low | 65 | // PORTB &= (1 << PB1); // sets PB1 to low |
| 73 | _delay_ms(20); | 66 | // _delay_ms(20); |
| 74 | PORTB &= ~(1 << PB1); // sets PB1 to low | 67 | // PORTB &= ~(1 << PB1); // sets PB1 to low |
| 75 | 68 | ||
| 76 | 69 | ||
| 77 | cli(); | 70 | cli(); |
| 78 | 71 | ||
| 79 | /* | ||
| 80 | GIMSK |= (1<<INT0); // External Interrupt Request 0 Enable | 72 | GIMSK |= (1<<INT0); // External Interrupt Request 0 Enable |
| 81 | GIMSK |= (1<<PCIE); // Pin Change Interrupt Enable | 73 | GIMSK |= (1<<PCIE); // Pin Change Interrupt Enable |
| 82 | 74 | ||
| 83 | // MCU Control Register (controls CPU-behaviours like interrupts & sleepmode) | 75 | // MCU Control Register (controls CPU-behaviours like interrupts & sleepmode) |
| 84 | MCUCR |= ~(1<<ISC01) | (1<<ISC00); // any logical change generates interrupt | 76 | // MCUCR |= ~(1<<ISC01) | (1<<ISC00); // any logical change generates interrupt |
| 85 | PCMSK |= (1<<PCINT0); | 77 | PCMSK |= (1<<PCINT0); |
| 86 | // INT0_CONTROL = INT0_RISING_EDGE; // going to toggle int0-behaviour | 78 | // INT0_CONTROL = INT0_RISING_EDGE; // going to toggle int0-behaviour |
| 87 | */ | ||
| 88 | 79 | ||
| 89 | TCCR0A |= (1 << WGM01); // CTC mode | 80 | TCCR0A |= (1 << WGM01); // CTC mode |
| 90 | // TCCR0B |= (1 << CS00); | 81 | // TCCR0B |= (1 << CS00); |
| @@ -104,7 +95,13 @@ int main(void) | |||
| 104 | // uint16_t t = 1; | 95 | // uint16_t t = 1; |
| 105 | // for (uint16_t i=0; i<16; i++) | 96 | // for (uint16_t i=0; i<16; i++) |
| 106 | // { | 97 | // { |
| 107 | print_data(t_current.s); | 98 | // print_data(t_current.s); |
| 99 | // uint16_t p = 0; | ||
| 100 | // for(int i=0; i<sizeof(t_current.s)*__CHAR_BIT__; i++) | ||
| 101 | // p |= t_current.s & (1<<i); | ||
| 102 | |||
| 103 | print_data(t_current.s); | ||
| 104 | // print_data(t_current.s<<10 | interval | ((PINB & PB0) == 1 ? 2 : 0)); | ||
| 108 | // t = t<<1; | 105 | // t = t<<1; |
| 109 | // } | 106 | // } |
| 110 | // print_data(t_current.s); | 107 | // print_data(t_current.s); |
