1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <util/twi.h>
|
4 | #include <stdint.h>
|
5 | # define F_CPU 8000000UL
|
6 |
|
7 |
|
8 | #define AN_SHIFT_PIN PB0
|
9 | #define AN_SHIFT_PORT PORTB
|
10 | #define AN_DATA_PIN PD7
|
11 | #define AN_DATA_PORT PORTD
|
12 |
|
13 | #define KA_SHIFT_PIN PB1
|
14 | #define KA_SHIFT_PORT PORTB
|
15 | #define KA_DATA_PIN PB2
|
16 | #define KA_DATA_PORT PORTB
|
17 |
|
18 | #define STORE_PIN PD6
|
19 | #define STORE_PORT PORTD
|
20 |
|
21 | #define RTC_ADDR 0b11010000
|
22 |
|
23 | #define RTC_CTRL 0x0E
|
24 | #define RTC_SECONDS 0x00
|
25 |
|
26 | void annodeShift(uint8_t value){
|
27 | for(uint8_t b = 0; b < 8; b++){
|
28 | if(value & 1){
|
29 | AN_DATA_PORT |= _BV(AN_DATA_PIN);
|
30 | }else{
|
31 | AN_DATA_PORT &= ~_BV(AN_DATA_PIN);
|
32 | }
|
33 | AN_SHIFT_PORT |= _BV(AN_SHIFT_PIN);
|
34 | _delay_us(100);
|
35 | AN_SHIFT_PORT &= ~_BV(AN_SHIFT_PIN);
|
36 | value >>= 1;
|
37 | }
|
38 | }
|
39 |
|
40 | void kathodeShift(uint8_t value){
|
41 | for(uint8_t b = 0; b < 8; b++){
|
42 | if(value & 1){
|
43 | KA_DATA_PORT |= _BV(KA_DATA_PIN);
|
44 | }else{
|
45 | KA_DATA_PORT &= ~_BV(KA_DATA_PIN);
|
46 | }
|
47 | KA_SHIFT_PORT |= _BV(KA_SHIFT_PIN);
|
48 | _delay_us(100);
|
49 | KA_SHIFT_PORT &= ~_BV(KA_SHIFT_PIN);
|
50 | value >>= 1;
|
51 | }
|
52 | }
|
53 |
|
54 | void store(){
|
55 | STORE_PORT |= _BV(STORE_PIN);
|
56 | //_delay_us(10);
|
57 | STORE_PORT &= ~_BV(STORE_PIN);
|
58 | }
|
59 |
|
60 | void _twi_enable(){
|
61 | TWCR |= _BV(TWEN);
|
62 | }
|
63 |
|
64 | void ERROR(){
|
65 | annodeShift(0b00010000);
|
66 | kathodeShift(~(0b00000001));
|
67 | store();
|
68 | }
|
69 |
|
70 | void ERROR2(){
|
71 | annodeShift(0b00010000);
|
72 | kathodeShift(~(0b00000010));
|
73 | store();
|
74 | }
|
75 |
|
76 | void ERROR3(){
|
77 | annodeShift(0b00010000);
|
78 | kathodeShift(~(0b00000100));
|
79 | store();
|
80 | }
|
81 |
|
82 | void TWI_START_OK(){
|
83 | annodeShift(0b00000001);
|
84 | kathodeShift(~(0b00000001));
|
85 | store();
|
86 | }
|
87 |
|
88 | void ADDRESS_RTC_OK(){
|
89 | annodeShift(0b00000010);
|
90 | kathodeShift(~(0b00000001));
|
91 | store();
|
92 | }
|
93 |
|
94 | void REGISTER_RTC_OK(){
|
95 | annodeShift(0b00000100);
|
96 | kathodeShift(~(0b00000001));
|
97 | store();
|
98 | }
|
99 |
|
100 | void _twi_init(){
|
101 | TWBR = 0x20;
|
102 | TWSR &= ~_BV(TWPS0);
|
103 | TWSR &= ~_BV(TWPS1);
|
104 | }
|
105 |
|
106 | int _twi_start(){
|
107 | TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
|
108 | while (!(TWCR & (1<<TWINT)));
|
109 | if ((TWSR & 0xF8) != TW_START)
|
110 | ERROR();
|
111 | else{
|
112 | TWI_START_OK();
|
113 | //_delay_ms(200);
|
114 | }
|
115 | return 1;
|
116 | }
|
117 |
|
118 | void _twi_stop(){
|
119 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
120 | }
|
121 |
|
122 | void _twi_write(uint8_t slave){
|
123 | TWDR = (slave & ~1);
|
124 | TWCR = (1<<TWINT) | (1<<TWEN);
|
125 | while (!(TWCR & (1<<TWINT)));
|
126 | if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
|
127 | ERROR();
|
128 | else{
|
129 | ADDRESS_RTC_OK();
|
130 | //_delay_ms(200);
|
131 | }
|
132 | }
|
133 |
|
134 | void _twi_read(uint8_t slave){
|
135 | TWDR = (slave | 1);
|
136 | TWCR = (1<<TWINT) | (1<<TWEN);
|
137 | while (!(TWCR & (1<<TWINT)));
|
138 | if ((TWSR & 0xF8) != TW_MR_SLA_ACK)
|
139 | ERROR();
|
140 | else
|
141 | ADDRESS_RTC_OK();
|
142 | if ((TWSR & 0xF8) == TW_MR_SLA_NACK)
|
143 | ERROR2();
|
144 | if ((TWSR & 0xF8) == TW_MR_ARB_LOST)
|
145 | ERROR3();
|
146 |
|
147 | //_delay_ms(200);
|
148 | }
|
149 |
|
150 | void _twi_send_ack(){
|
151 | TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
|
152 | }
|
153 |
|
154 | void _twi_send_nack(){
|
155 | TWCR = _BV(TWINT) | _BV(TWEN);
|
156 | }
|
157 |
|
158 | uint8_t _twi_rec(){
|
159 | while (!(TWCR & (1<<TWINT)));
|
160 | return TWDR;
|
161 | }
|
162 |
|
163 | void _twi_send(uint8_t data){
|
164 | TWDR = data;
|
165 | TWCR = (1<<TWINT) | (1<<TWEN);
|
166 | while (!(TWCR & (1<<TWINT)));
|
167 |
|
168 | if ((TWSR & 0xF8) != TW_MT_DATA_ACK)
|
169 | ERROR();
|
170 | else{
|
171 | REGISTER_RTC_OK();
|
172 | //_delay_ms(200);
|
173 | }
|
174 | }
|
175 |
|
176 | int main() {
|
177 | //init pins as outputs
|
178 | DDRB |= ((_BV(AN_SHIFT_PIN) | _BV(KA_SHIFT_PIN)) | _BV(KA_DATA_PIN));
|
179 | DDRD |= (_BV(AN_DATA_PIN) | _BV(STORE_PIN));
|
180 | DDRB |= _BV(PB6);
|
181 | PORTB &= ~_BV(PB6);
|
182 | annodeShift(0b00000000);
|
183 | kathodeShift(~(0b00000000));
|
184 | store();
|
185 | _delay_ms(100);
|
186 | _twi_init();
|
187 |
|
188 | _twi_start();
|
189 | _twi_write(RTC_ADDR);
|
190 | _twi_send(RTC_CTRL);
|
191 | _twi_send(0);
|
192 | _twi_stop();
|
193 | int count = 0;
|
194 | while(1){
|
195 | if(count >= 10){
|
196 | _twi_start();
|
197 | _twi_write(RTC_ADDR);
|
198 | _twi_send(RTC_SECONDS);
|
199 | _twi_start();
|
200 | _twi_read(RTC_ADDR);
|
201 | uint8_t secs = _twi_rec();
|
202 | _twi_send_nack();
|
203 | _twi_stop();
|
204 | annodeShift(0b00001000);
|
205 | kathodeShift(~secs);
|
206 | store();
|
207 |
|
208 | count = 0;
|
209 | }
|
210 | PORTB ^= _BV(PB6);
|
211 | count ++;
|
212 | _delay_ms(200);
|
213 | }
|
214 | }
|
215 |
|
216 | void symbole(){
|
217 | //init pins as outputs
|
218 | DDRB |= ((_BV(AN_SHIFT_PIN) | _BV(KA_SHIFT_PIN)) | _BV(KA_DATA_PIN));
|
219 | DDRD |= (_BV(AN_DATA_PIN) | _BV(STORE_PIN));
|
220 |
|
221 | int symb[2][5];
|
222 |
|
223 |
|
224 | //herz
|
225 |
|
226 | symb[0][0] = 0b00000110;
|
227 | symb[0][1] = 0b00001001;
|
228 | symb[0][2] = 0b00010010;
|
229 | symb[0][3] = symb[0][1];
|
230 | symb[0][4] = symb[0][0];
|
231 |
|
232 |
|
233 | //smile
|
234 | /*
|
235 | symb[0][0] = 0b00001000;
|
236 | symb[0][1] = 0b00010010;
|
237 | symb[0][2] = 0b00010000;
|
238 | symb[0][3] = symb[0][1];
|
239 | symb[0][4] = symb[0][0];
|
240 | */
|
241 | //pfeil
|
242 | symb[1][0] = 0b00000100;
|
243 | symb[1][1] = symb[1][0];
|
244 | symb[1][2] = 0b00010101;
|
245 | symb[1][3] = 0b00001110;
|
246 | symb[1][4] = symb[1][0];
|
247 |
|
248 | int count = 0;
|
249 | int sidx = 0;
|
250 |
|
251 | while(1){
|
252 | for(int i = 0; i < 5; i++){
|
253 | annodeShift(symb[sidx][i]);
|
254 | kathodeShift(~(1 << i));
|
255 | store();
|
256 | _delay_us(10);
|
257 | if(count >= 1000){
|
258 | if(sidx == 0){
|
259 | sidx = 1;
|
260 | }else{
|
261 | sidx = 0;
|
262 | }
|
263 | count = 0;
|
264 | }
|
265 | count ++;
|
266 | }
|
267 |
|
268 | }
|
269 |
|
270 | //while(1){
|
271 | //PORTB |= _BV(BLINKEPORT);
|
272 | //_delay_ms(1000);
|
273 | //PORTB &= ~_BV(BLINKEPORT);
|
274 | //_delay_ms(1000);
|
275 | //}
|
276 | }
|