1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <util/atomic.h>
|
4 | #include <util/delay.h>
|
5 |
|
6 |
|
7 | #define NOP __asm__ __volatile__ ("nop")
|
8 |
|
9 | #ifndef sbi
|
10 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) // setzt das angegebene Bit
|
11 | #endif
|
12 | #ifndef cbi
|
13 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) // löscht das angegebene Bit
|
14 | #endif
|
15 |
|
16 | #define shift_Clock_OUT sbi (DDRB,1) // Pin 52, SHCP .. shift register input clock
|
17 | #define shift_Latch_OUT sbi (DDRG,2) // Pin 39, STCP .. latch or storage register clock input
|
18 | #define shift_MOSI_OUT sbi (DDRB,2) // Pin 51, DS .... data serial input
|
19 | #define shift_Reset_OUT sbi (DDRG,0) // Pin 41, /MR ... master reset
|
20 | #define shift_Slave_OUT sbi (DDRB,0) // Pin 53, muss Ausgang sein mit aktiven SPI
|
21 | #define debugLED30_OUT sbi (DDRC,7) // Pin 30
|
22 |
|
23 | #define shift_Clock_ON sbi (PORTB,1) // PB1 einschalten
|
24 | #define shift_Latch_ON sbi (PORTG,2) // PG2
|
25 | #define shift_MOSI_ON sbi (PORTB,2) // PB2
|
26 | #define shift_Reset_ON sbi (PORTG,0) // PG0
|
27 | #define debugLED30_ON sbi (PORTC,7) //
|
28 |
|
29 | #define shift_Clock_OFF cbi (PORTB,1) // PB1 ausschalten
|
30 | #define shift_Latch_OFF cbi (PORTG,2) // PG2
|
31 | #define shift_MOSI_OFF cbi (PORTB,2) // PB2
|
32 | #define shift_Reset_OFF cbi (PORTG,0) // PG0
|
33 | #define debugLED30_OFF cbi (PORTC,7) //
|
34 |
|
35 | uint16_t value = 1;
|
36 | uint8_t data;
|
37 |
|
38 |
|
39 | int main()
|
40 | {
|
41 |
|
42 | /* Init 74HC595 */
|
43 | shift_Reset_ON;
|
44 | shift_Reset_OUT;
|
45 | shift_Latch_OUT;
|
46 | shift_Reset_OFF; // delete shift register
|
47 | shift_Reset_ON;
|
48 | shift_Latch_ON; // take over storage register
|
49 | shift_Latch_OFF;
|
50 |
|
51 | set_SPI_Master();
|
52 |
|
53 | SPDR = data; // zeigt Wirkung
|
54 | //SPSR = (1 << SPIF); // ohne Wirkung
|
55 | //value = SPSR; // ohne Wirkung
|
56 | //value = (SPSR & (1 << SPIF)); // ohne Wirkung
|
57 |
|
58 | debugLED30_OUT;
|
59 |
|
60 | set_Timer1();
|
61 |
|
62 | while (1)
|
63 | {
|
64 | value = value << 1;
|
65 | if (value >= 0x8000) value = 1; // höchstes Bit erreicht
|
66 | _delay_ms(50);
|
67 | }
|
68 |
|
69 | } // end main()
|
70 |
|
71 |
|
72 | // ****** Funktionen ******* //
|
73 |
|
74 | ISR(TIMER1_COMPB_vect) //
|
75 | {
|
76 | const uint16_t tcount = 10000; // aller 5ms
|
77 |
|
78 | /* vom Schieberegister ins Ausgaberegister übernehmen */
|
79 | shift_Latch_ON;
|
80 | shift_Latch_OFF;
|
81 |
|
82 | uint8_t LSB = value & 0xFF;
|
83 | uint8_t MSB = value >> 8;
|
84 |
|
85 | debugLED30_ON;
|
86 | while (!(SPSR & (1 << SPIF))) // wait for transmission complete
|
87 | ;
|
88 | SPDR = LSB; // Start transmission
|
89 | debugLED30_OFF;
|
90 |
|
91 | debugLED30_ON;
|
92 | while (!(SPSR & (1 << SPIF))) // wait for transmission complete
|
93 | ;
|
94 | SPDR = MSB; // Start transmission
|
95 | debugLED30_OFF;
|
96 |
|
97 | OCR1B += tcount;
|
98 | }
|
99 |
|
100 |
|
101 | void set_SPI_Master()
|
102 | {
|
103 | cli();
|
104 | shift_Clock_OUT;
|
105 | shift_Latch_OUT;
|
106 | shift_MOSI_OUT;
|
107 | shift_Reset_OUT;
|
108 | shift_Slave_OUT;
|
109 | // enable SPI, LSB first, Master, fck/4
|
110 | SPCR = (1 << SPE) | (1 << DORD) | (1 << MSTR);
|
111 | sei();
|
112 | }
|
113 |
|
114 |
|
115 | void set_Timer1 () // Normal Mode
|
116 | {
|
117 | cli();
|
118 | TCCR1A = 0; // Reset
|
119 | TCCR1B = 0; //
|
120 | TIMSK1 = 0; //
|
121 | TCNT1 = 0; //
|
122 | OCR1B = 0; //
|
123 | TIMSK1 = (1<<OCIE1B); // enable Compare Match B ISR
|
124 | TCCR1B |= (1 << CS11); // Prescaler 8
|
125 | sei();
|
126 | }
|