von
Markus (Gast)
17.02.2011 17:51
So leute würde meiner freundin das hier gerne schenken
:http://tinkerlog.com/howto/64pixels/
hab leider nur ein 5x7 led matrix. Wie stell ich das nun an an, das
programm umzuschreiben? Wäre euch sehr dankbar, da ich es meiner
Freundin nachträglich zum Valentienstag schenken will.
Hab das Programm von dieser seite ein bisschen gekürzt. ist das so
korrekt?
lg
/*
-----------------------------------------------------------------------
* Title: 8x8 LED dot matrix animations
* Author: Alexander Weber alex@tinkerlog.com
* Date: 21.12.2008
* Hardware: ATtiny2313V
* Software: AVRMacPack
*
*/
1 #include <avr/io.h>
2 #include <avr/pgmspace.h>
3
4 #ifndef FONT_H_
5 #define FONT_H_
6
7 #define MAX_CHARS 59
8 #define CHAR_OFFSET 0x20
9
10 const uint8_t font [] PROGMEM = {
11 // 3 chars bitmap, 1 char length
12 0x00 , 0x00 , 0x00 , 0x01 , // 0x20, 32, ' '
13 0x17 , 0x00 , 0x00 , 0x01 , // 0x21, 33, !
14 0x03 , 0x00 , 0x03 , 0x03 , // 0x22, 34, "
15 0x00 , 0x00 , 0x00 , 0x03 , // 0x23, 35, #
16 0x00 , 0x00 , 0x00 , 0x03 , // 0x24, 36, $
17 0x00 , 0x00 , 0x00 , 0x03 , // 0x25, 37, %
18 0x00 , 0x00 , 0x00 , 0x03 , // 0x26, 38, &
19 0x03 , 0x00 , 0x00 , 0x01 , // 0x27, 39, '
20 0x0e , 0x11 , 0x00 , 0x02 , // 0x28, 40, (
21 0x11 , 0x0e , 0x00 , 0x02 , // 0x29, 41, )
22 0x00 , 0x00 , 0x00 , 0x03 , // 0x2A, 42, *
23 0x08 , 0x1c , 0x08 , 0x03 , // 0x2B, 43, +
24 0x18 , 0x00 , 0x00 , 0x01 , // 0x2C, 44, ,
25 0x04 , 0x04 , 0x00 , 0x03 , // 0x2D, 45, -
26 0x10 , 0x00 , 0x00 , 0x01 , // 0x2E, 46, .
27 0x18 , 0x04 , 0x03 , 0x03 , // 0x2F, 47, /
28 0x1f , 0x11 , 0x1f , 0x03 , // 0x30, 48, 0
29 0x01 , 0x1f , 0x00 , 0x02 , // 0x31, 49, 1
30 0x1d , 0x15 , 0x17 , 0x03 , // 0x32, 50, 2
31 0x15 , 0x15 , 0x0e , 0x03 , // 0x33, 51, 3
32 0x0f , 0x08 , 0x1f , 0x03 , // 0x34, 52, 4
33 0x17 , 0x15 , 0x1d , 0x03 , // 0x35, 53, 5
34 0x1f , 0x12 , 0x1e , 0x03 , // 0x36, 54, 6
35 0x11 , 0x09 , 0x07 , 0x03 , // 0x37, 55, 7
36 0x1f , 0x15 , 0x1f , 0x03 , // 0x38, 56, 8
37 0x0f , 0x09 , 0x1f , 0x03 , // 0x39, 57, 9
38 0x0a , 0x00 , 0x00 , 0x01 , // 0x3A, 58, :
39 0x1a , 0x00 , 0x00 , 0x01 , // 0x3B, 59, ;
40 0x08 , 0x14 , 0x00 , 0x02 , // 0x3C, 60, <
41 0x14 , 0x14 , 0x00 , 0x02 , // 0x3D, 61, =
42 0x14 , 0x08 , 0x00 , 0x02 , // 0x3E, 62, >
43 0x15 , 0x05 , 0x02 , 0x03 , // 0x3F, 63, ?
44 0x0e , 0x17 , 0x16 , 0x03 , // 0x40, 64, @
45 0x1f , 0x09 , 0x1e , 0x03 , // 0x41, 65, A
46 0x1f , 0x15 , 0x0a , 0x03 , // 0x42, 66, B
47 0x0e , 0x11 , 0x11 , 0x03 , // 0x43, 67, C
48 0x1f , 0x11 , 0x0e , 0x03 , // 0x44, 68, D
49 0x0e , 0x15 , 0x15 , 0x03 , // 0x45, 69, E
50 0x1e , 0x05 , 0x05 , 0x03 , // 0x46, 70, F
51 0x0e , 0x11 , 0x1d , 0x03 , // 0x47, 71, G
52 0x1f , 0x04 , 0x1f , 0x03 , // 0x48, 72, H
53 0x1f , 0x00 , 0x00 , 0x01 , // 0x49, 73, I
54 0x08 , 0x10 , 0x0f , 0x03 , // 0x4A, 74, J
55 0x1f , 0x04 , 0x1b , 0x03 , // 0x4B, 75, K
56 0x0f , 0x10 , 0x10 , 0x03 , // 0x4C, 76, L
57 0x1f , 0x02 , 0x1f , 0x03 , // 0x4D, 77, M
58 0x1f , 0x01 , 0x1e , 0x03 , // 0x4E, 78, N
59 0x0e , 0x11 , 0x0e , 0x03 , // 0x4F, 79, O
60 0x1f , 0x09 , 0x06 , 0x03 , // 0x50, 80, P
61 0x06 , 0x19 , 0x06 , 0x03 , // 0x51, 81, Q
62 0x1f , 0x09 , 0x16 , 0x03 , // 0x52, 82, R
63 0x12 , 0x15 , 0x09 , 0x03 , // 0x53, 83, S
64 0x01 , 0x1f , 0x01 , 0x03 , // 0x54, 84, T
65 0x0f , 0x10 , 0x0f , 0x03 , // 0x55, 85, U
66 0x1f , 0x10 , 0x0f , 0x03 , // 0x56, 86, V
67 0x1f , 0x08 , 0x1f , 0x03 , // 0x57, 87, W
68 0x1b , 0x04 , 0x1b , 0x03 , // 0x58, 88, X
69 0x03 , 0x1c , 0x03 , 0x03 , // 0x59, 89, Y
70 0x19 , 0x15 , 0x13 , 0x03 , // 0x5A, 90, Z
71 0x1f , 0x11 , 0x00 , 0x02 , // 0x5B, 91, [
72 0x03 , 0x04 , 0x18 , 0x03 , // 0x5C, 92,
73 0x11 , 0x1f , 0x00 , 0x02 , // 0x5D, 93, [
74 0x11 , 0x1f , 0x00 , 0x02 , // 0x5E, 94, ^
75 0x1f , 0x1f , 0x1f , 0x03 // 0x5F, 95, _, used as block, all on
76 };
77
78 /* -----------------------------------------------------------------------
79 * Title: 8x8 LED dot matrix animations
80 * Author: Alexander Weber alex@tinkerlog.com
81 * Date: 21.12.2008
82 * Hardware: ATtiny2313V
83 * Software: AVRMacPack
84 *
85 */
86
87 #include <inttypes.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #include <avr/io.h>
91 #include <avr/interrupt.h>
92 #include <avr/eeprom.h>
93 #include <util/delay.h>
94 #include <avr/pgmspace.h>
95 #include "font.h"
96
97 // Change these values to adjust scroll speeds and animation iterations
98 #define ANIMATION_SCROLL_SPEED 80 // how fast to scroll the animations
99 #define TEXT_SCROLL_SPEED 120 // how fast to scrill the text
100 #define REPEAT_ANIMATION 10 // how often to repeat the animation if in cycling mode
101 #define REPEAT_TEXT 5 // how often to repeat the text if in cycling mode
102 #define F_CPU
103 // How to add a new message:
104 // * add the new message (only upper case, see font.h)
105 // * adjust MAX_MESSAGES
106 // * add the new message to messages
107 // NOTE: messages may not be longer than 59 chars. Otherwise they will not fit in the buffer.
108 // 123456789012345678901234567890123456789012345678901234567890
109 const prog_char PROGMEM message_00 [] PROGMEM = " WTF!?! " ;
110 const prog_char PROGMEM message_01 [] PROGMEM = " I AM NO BOMB! " ;
111 const prog_char PROGMEM message_02 [] PROGMEM = " 5 4 3 2 1 ... BOOM! " ;
112 const prog_char PROGMEM message_03 [] PROGMEM = " I'M SORRY DAVE, I'M AFRAID I CAN'T DO THAT. " ;
113 const prog_char PROGMEM message_04 [] PROGMEM = " NOW BYE ME A SOLDERING STATION " ;
114 const prog_char PROGMEM message_05 [] PROGMEM = " MAKE STUFF " ;
115 const prog_char PROGMEM message_06 [] PROGMEM = " IF YOU CAN'T OPEN IT, YOU DON'T OWN IT " ;
116 const prog_char PROGMEM message_07 [] PROGMEM = " 1337 3L3X7RON!C5 !1!! " ;
117 const prog_char PROGMEM message_08 [] PROGMEM = " MY KUNG FU IS BETTER THAN YOURS " ;
118 const prog_char PROGMEM message_09 [] PROGMEM = " SUDO MAKE ME A SANDWICH " ;
119 const prog_char PROGMEM message_10 [] PROGMEM = " ZOMBIES AHEAD " ;
120 const prog_char PROGMEM message_11 [] PROGMEM = " HTTP://TINKERLOG.COM " ;
121
122 #define MAX_MESSAGES 12
123 PGM_P PROGMEM messages [] = {
124 message_00
125 , message_01
126 , message_02
127 , message_03
128 , message_04
129 , message_05
130 , message_06
131 , message_07
132 , message_08
133 , message_09
134 , message_10
135 , message_11
136 };
137
138 #define MAX_ANIMATIONS 3
139 const prog_uint8_t PROGMEM sprite_00 [] =
140 {
141 0x18 , // ___XX___
142 0x3C , // __XXXX__
143 0x7E , // _XXXXXX_
144 0xDB , // X_XXXX_X
145 0xFF , // XXXXXXXX
146 0x24 , // __X__X__
147 0x5A , // _X_XX_X_
148 0xA5 // X_X__X_X
149 };
150
151 const prog_uint8_t PROGMEM sprite_01 [ 8 ] =
152 {
153 0x18 , // ___XX___
154 0x3C , // __XXXX__
155 0x7E , // _XXXXXX_
156 0xDB , // X_XXXX_X
157 0xFF , // XXXXXXXX
158 0x24 , // __X__X__
159 0x42 , // _X____X_
160 0x24 // __X__X__
161 };
162 const prog_uint8_t PROGMEM sprite_02 [ 8 ] =
163 {
164 0x00 , // ________
165 0x00 , // ________
166 0x14 , // ___X_X__
167 0x3E , // __XXXXX_
168 0x3E , // __XXXXX_
169 0x1C , // ___XXX__
170 0x08 , // ____X___
171 0x00 // ________
172 };
173
174 const prog_uint8_t PROGMEM sprite_03 [ 8 ] =
175 {
176 0x00 , // ________
177 0x66 , // _XX__XX_
178 0xFF , // XXXXXXXX
179 0xFF , // XXXXXXXX
180 0xFF , // XXXXXXXX
181 0x7E , // _XXXXXX_
182 0x3C , // __XXXX__
183 0x18 // ___XX___
184 };
185
186 const prog_uint8_t PROGMEM sprite_04 [ 8 ] =
187 {
188 0x24 , // __X__X__
189 0x7E , // _XXXXXX_
190 0xDB , // XX_XX_XX
191 0xFF , // XXXXXXXX
192 0xA5 , // X_X__X_X
193 0x99 , // X__XX__X
194 0x81 , // X______X
195 0xC3 // XX____XX
196 };
197
198 const prog_uint8_t PROGMEM sprite_05 [ 8 ] =
199 {
200 0x24 , // __X__X__
201 0x18 , // ___XX___
202 0x7E , // X_XXXX_X
203 0xDB , // XX_XX_XX
204 0xFF , // XXXXXXXX
205 0xDB , // X_XXXX_X
206 0x99 , // X__XX__X
207 0xC3 // XX____XX
208 };
209
210
211
212 uint8_t mode_ee EEMEM = 0 ; // stores the mode in eeprom
213 static uint8_t screen_mem [ 8 ]; // screen memory
214 static uint8_t active_row ; // active row
215 static uint8_t buffer [ 60 ]; // stores the active message or sprite
216 static uint8_t message_ptr = 0 ; // points to the active char in the message
217 static uint8_t message_displayed = 0 ; // how often has the message been displayed?
218 static uint8_t active_char = 0 ; // stores the active char
219 static uint8_t message_length = 0 ; // stores the length of the active message
220 static uint8_t char_ptr = 0 ; // points to the active col in the char
221 static uint8_t char_length = 0 ; // stores the length of the active char
222 static volatile uint16_t counter = 0 ; // used for delay function
223
224 // prototypes
225 void delay_ms ( uint16_t delay );
226 void copy_to_display ( int8_t x , int8_t y , uint8_t sprite []);
227 void display_active_row ( void );
228 void show_char ();
229 void clear_screen ( void );
230 void copy_to_buffer ( const prog_uint8_t sprite [ 8 ]);
231 void scroll_animation ( const prog_uint8_t sprite_1 [], const prog_uint8_t sprite_2 []);
232
233
234
235 /*
236 * ISR TIMER0_OVF_vect
237 * Handles overflow interrupts of timer 0.
238 *
239 * 4MHz
240 * ----
241 * Prescaler 8 ==> 1953.1 Hz
242 * Complete display = 244 Hz
243 *
244 */
245 ISR ( TIMER0_OVF_vect ) {
246 display_active_row ();
247 counter ++ ;
248 }
249
250
251
252 /*
253 * delay_ms
254 * Uses the counter that is incremented by the ISR.
255 * Max delay is 32767ms.
256 */
257 void delay_ms ( uint16_t delay ) {
258 while ( ! ( PIND & ( 1 << PD6 ))) {} // used to stop the animation when PD6 goes LOW
259 uint16_t t = delay * 2 ;
260 counter = 0 ;
261 while ( counter < t ) {}
262 }
263
264
265
266 /*
267 * copy_to_display
268 * Copies sprite data to the screen memory at the given position.
269 */
270 void copy_to_display ( int8_t x , int8_t y , uint8_t sprite [ 8 ]) {
271 int8_t i , t ;
272 uint8_t row ;
273 for ( i = 0 ; i < 8 ; i ++ ) {
274 t = i - y ;
275 row = (( t >= 0 ) && ( t < 8 )) ? sprite [ t ] : 0x00 ;
276 row = ( x >= 0 ) ? ( row >> x ) : ( row << - x );
277 screen_mem [ i ] = row ;
278 }
279 }
280
281
282
283 /*
284 * display_active_col
285 * Deactivates the active column and displays the next one.
286 * Data is read from screen_mem.
287 *
288 * ATtiny2313
289 * 16 - PD0 PB7 - 1
290 * 15 - PD1 PB6 - 2
291 * 14 - PA1 PB5 - 3
292 * 13 - PA0 PB4 - 4
293 * 12 - PD2 PB3 - 5
294 * 11 - PD3 PB2 - 6
295 * 10 - PD4 PB1 - 7
296 * 9 - PD5 PB0 - 8
297 *
298 * NFM-12883 common anode |
299 * A0B5B4D4B2D3D1D0 +-----+
300 * PD5 o o o o o o o o | |
301 * PA1 o o o o o o o o _+_ |
302 * PB0 o o o o o o o o \ / |
303 * PD2 o o o o o o o o __V__ |
304 * PB7 o o o o o o o o | |
305 * PB1 o o o o o o o o ---+-----C---
306 * PB6 o o o o o o o o |
307 * PB3 o o o o o o o o
308 *
309 */
310 void display_active_row ( void ) {
311
312 uint8_t row ;
313
314 // shut down all rows and columns
315 PORTA = ( 0 << PA0 ) | ( 1 << PA1 );
316 PORTB = ( 0 << PB5 ) | ( 0 << PB4 ) | ( 0 << PB2 ) | ( 1 << PB0 ) |
317 ( 1 << PB7 ) | ( 1 << PB1 ) | ( 1 << PB6 ) | ( 1 << PB3 );
318 PORTD = ( 0 << PD4 ) | ( 0 << PD3 ) | ( 0 << PD1 ) | ( 0 << PD0 ) |
319 ( 1 << PD5 ) | ( 1 << PD2 ) | ( 1 << PD6 );
320
321 // next row
322 active_row = ( active_row + 1 ) % 8 ;
323 row = screen_mem [ active_row ];
324
325 // output all columns, switch leds on.
326 // column 1
327 if (( row & 0x80 ) == 0x80 ) {
328 PORTA |= ( 1 << PA0 );
329 }
330 // column 2
331 if (( row & 0x40 ) == 0x40 ) {
332 PORTB |= ( 1 << PB5 );
333 }
334 // column 3
335 if (( row & 0x20 ) == 0x20 ) {
336 PORTB |= ( 1 << PB4 );
337 }
338 // column 4
339 if (( row & 0x10 ) == 0x10 ) {
340 PORTD |= ( 1 << PD4 );
341 }
342 // column 5
343 if (( row & 0x08 ) == 0x08 ) {
344 PORTB |= ( 1 << PB2 );
345 }
346 // column 6
347 if (( row & 0x04 ) == 0x04 ) {
348 PORTD |= ( 1 << PD3 );
349 }
350 // column 7
351 if (( row & 0x02 ) == 0x02 ) {
352 PORTD |= ( 1 << PD1 );
353 }
354 // column 8
355 if (( row & 0x01 ) == 0x01 ) {
356 PORTD |= ( 1 << PD0 );
357 }
358
359 // activate row
360 switch ( active_row ) {
361 case 0 :
362 PORTD &= ~ ( 1 << PD5 );
363 break ;
364 case 1 :
365 PORTA &= ~ ( 1 << PA1 );
366 break ;
367 case 2 :
368 PORTB &= ~ ( 1 << PB0 );
369 break ;
370 case 3 :
371 PORTD &= ~ ( 1 << PD2 );
372 break ;
373 case 4 :
374 PORTB &= ~ ( 1 << PB7 );
375 break ;
376 case 5 :
377 PORTB &= ~ ( 1 << PB1 );
378 break ;
379 case 6 :
380 PORTB &= ~ ( 1 << PB6 );
381 break ;
382 case 7 :
383 PORTB &= ~ ( 1 << PB3 );
384 break ;
385 }
386
387 }
388 /*
389 * Use this method, if you have a common cathode matrix.
390 */
391 /*
392 void display_active_row(void) {
393
394 uint8_t row;
395
396 // shut down all rows and columns
397 PORTB = 0x34;
398 PORTD = 0x1B;
399 PORTA = 0x01;
400
401 // next row
402 active_row = (active_row+1) % 8;
403 row = screen_mem[active_row];
404
405 // output all columns, switch leds on.
406 // column 1
407 if ((row & 0x80) == 0x80) {
408 PORTA &= ~(1 << PA0);
409 }
410 // column 2
411 if ((row & 0x40) == 0x40) {
412 PORTB &= ~(1 << PB5);
413 }
414 // column 3
415 if ((row & 0x20) == 0x20) {
416 PORTB &= ~(1 << PB4);
417 }
418 // column 4
419 if ((row & 0x10) == 0x10) {
420 PORTD &= ~(1 << PD4);
421 }
422 // column 5
423 if ((row & 0x08) == 0x08) {
424 PORTB &= ~(1 << PB2);
425 }
426 // column 6
427 if ((row & 0x04) == 0x04) {
428 PORTD &= ~(1 << PD3);
429 }
430 // column 7
431 if ((row & 0x02) == 0x02) {
432 PORTD &= ~(1 << PD1);
433 }
434 // column 8
435 if ((row & 0x01) == 0x01) {
436 PORTD &= ~(1 << PD0);
437 }
438
439 // activate row
440 switch (active_row) {
441 case 0:
442 PORTD |= (1 << PD5);
443 break;
444 case 1:
445 PORTA |= (1 << PA1);
446 break;
447 case 2:
448 PORTB |= (1 << PB0);
449 break;
450 case 3:
451 PORTD |= (1 << PD2);
452 break;
453 case 4:
454 PORTB |= (1 << PB7);
455 break;
456 case 5:
457 PORTB |= (1 << PB1);
458 break;
459 case 6:
460 PORTB |= (1 << PB6);
461 break;
462 case 7:
463 PORTB |= (1 << PB3);
464 break;
465 }
466
467 }
468 */
469
470
471 /*
472 * show_char
473 * Displays the actual message.
474 * Scrolls the screen to the left and draws new pixels on the right.
475 */
476 void show_char () {
477 uint8_t i ;
478 uint8_t b ;
479
480 // blit the screen to the left
481 for ( i = 0 ; i < 8 ; i ++ ) {
482 screen_mem [ i ] <<= 1 ;
483 }
484 // advance a char if needed
485 if ( char_ptr == char_length ) {
486 message_ptr ++ ;
487 if ( message_ptr == message_length ) {
488 message_ptr = 0 ;
489 message_displayed ++ ;
490 }
491 active_char = buffer [ message_ptr ] - CHAR_OFFSET ;
492 char_length = pgm_read_byte ( & font [ active_char * 4 + 3 ]);
493 char_ptr = 0 ;
494 return ; // this makes the space between two chars
495 }
496 // read pixels for current column of char
497 b = pgm_read_byte ( & font [ active_char * 4 + char_ptr ++ ]);
498 // write pixels into screen memory
499 for ( i = 0 ; i < 7 ; i ++ ) {
500 if (( b & ( 1 << i )) == ( 1 << i )) {
501 screen_mem [ i + 1 ] |= 0x01 ;
502 }
503 }
504 }
505
506
507
508 /*
509 * clear_screen
510 */
511 void clear_screen ( void ) {
512 uint8_t i ;
513 for ( i = 0 ; i < 8 ; i ++ ) {
514 screen_mem [ i ] = 0x00 ;
515 }
516 }
517
518
519
520 /*
521 * copy_to_buffer
522 * Copies the given sprite from PROGMEM to RAM.
523 */
524 void copy_to_buffer ( const prog_uint8_t sprite [ 8 ]) {
525 memcpy_P ( buffer , sprite , 8 );
526 }
527
528
529
530 /*
531 * scroll_animation
532 * Uses sprite_1 and sprite_2 to draw a simple animation.
533 */
534 void scroll_animation ( const prog_uint8_t sprite_1 [ 8 ], const prog_uint8_t sprite_2 [ 8 ]) {
535 uint8_t i ;
536 int8_t x ;
537 for ( i = 0 ; i < REPEAT_ANIMATION ; i ++ ) {
538 copy_to_buffer ( sprite_1 );
539 for ( x = - 8 ; x <= 0 ; x ++ ) {
540 copy_to_display ( x , 0 , buffer );
541 delay_ms ( ANIMATION_SCROLL_SPEED );
542 }
543 delay_ms ( 200 );
544 copy_to_buffer ( sprite_2 );
545 copy_to_display ( 0 , 0 , buffer );
546 delay_ms ( 200 );
547 copy_to_buffer ( sprite_1 );
548 copy_to_display ( 0 , 0 , buffer );
549 delay_ms ( 200 );
550 copy_to_buffer ( sprite_2 );
551 copy_to_display ( 0 , 0 , buffer );
552 delay_ms ( 200 );
553 copy_to_buffer ( sprite_1 );
554 for ( x = 0 ; x < 8 ; x ++ ) {
555 copy_to_display ( x , 0 , buffer );
556 delay_ms ( ANIMATION_SCROLL_SPEED );
557 }
558 }
559 }
560
561
562
563 int main ( void ) {
564
565 uint8_t i = 0 ;
566 uint8_t mode = 0 ;
567 uint8_t cycle = 0 ;
568
569 // timer 0 setup, prescaler 8
570 TCCR0B |= ( 1 << CS01 );
571
572 // enable timer 0 interrupt
573 TIMSK |= ( 1 << TOIE0 );
574
575 // define outputs
576 DDRA |= 0x03 ;
577 DDRB |= 0xFF ;
578 DDRD |= 0x3F ;
579
580 // shut down all rows and columns, enable column 1
581 PORTA = ( 1 << PA0 ) | ( 1 << PA1 );
582 PORTB = ( 0 << PB5 ) | ( 0 << PB4 ) | ( 0 << PB2 ) | ( 1 << PB0 ) |
583 ( 1 << PB7 ) | ( 1 << PB1 ) | ( 1 << PB6 ) | ( 1 << PB3 );
584 PORTD = ( 0 << PD4 ) | ( 0 << PD3 ) | ( 0 << PD1 ) | ( 0 << PD0 ) |
585 ( 1 << PD5 ) | ( 1 << PD2 );
586
587 // enable pull ups
588 PORTD |= ( 1 << PD6 );
589
590 // say hello, toggle row 1 (pixel 0,0)
591 for ( i = 0 ; i < 5 ; i ++ ) {
592 PORTD &= ~ ( 1 << PD5 );
593 _delay_ms ( 50 );
594 PORTD |= ( 1 << PD5 );
595 _delay_ms ( 50 );
596 }
597
598 // read last mode from eeprom
599 // 0 mean cycle through all modes and messages
600 mode = eeprom_read_byte ( & mode_ee );
601 if (( mode == 0 ) || ( mode >= ( MAX_ANIMATIONS + MAX_MESSAGES + 1 ))) {
602 mode = 1 ;
603 cycle = 1 ;
604 }
605 eeprom_write_byte ( & mode_ee , mode + 1 );
606
607 sei ();
608
609 while ( 1 ) {
610
611 switch ( mode ) {
612 case 1 :
613 scroll_animation ( sprite_00 , sprite_01 );
614 break ;
615 case 2 :
616 for ( i = 0 ; i < REPEAT_ANIMATION ; i ++ ) {
617 copy_to_buffer ( sprite_03 );
618 copy_to_display ( 0 , 0 , buffer );
619 delay_ms ( 750 );
620 copy_to_buffer ( sprite_02 );
621 copy_to_display ( 0 , 0 , buffer );
622 delay_ms ( 180 );
623 }
624 break ;
625 case 3 :
626 scroll_animation ( sprite_04 , sprite_05 );
627 break ;
628 default:
629 strcpy_P ( buffer , ( uint8_t * ) pgm_read_word ( & ( messages [ mode - ( MAX_ANIMATIONS + 1 )])));
630 message_length = strlen ( buffer );
631 while ( message_displayed < REPEAT_TEXT ) {
632 show_char ();
633 delay_ms ( TEXT_SCROLL_SPEED );
634 }
635 message_displayed = 0 ;
636 break ;
637 }
638
639 // cycle through all modes
640 if ( cycle ) {
641 mode ++ ;
642 clear_screen ();
643 if ( mode >= ( MAX_ANIMATIONS + MAX_MESSAGES + 1 )) {
644 mode = 1 ;
645 }
646 }
647
648 }
649
650 return 0 ;
651
652 }
von
Markus (Gast)
17.02.2011 18:00
sry nochmal das programm : 1 #include <avr/io.h>
2 #include <avr/pgmspace.h>
3
4 #ifndef FONT_H_
5 #define FONT_H_
6
7 #define MAX_CHARS 59
8 #define CHAR_OFFSET 0x20
9
10 const uint8_t font [] PROGMEM = {
11 // 3 chars bitmap, 1 char length
12 0x00 , 0x00 , 0x00 , 0x01 , // 0x20, 32, ' '
13 0x17 , 0x00 , 0x00 , 0x01 , // 0x21, 33, !
14 0x03 , 0x00 , 0x03 , 0x03 , // 0x22, 34, "
15 0x00 , 0x00 , 0x00 , 0x03 , // 0x23, 35, #
16 0x00 , 0x00 , 0x00 , 0x03 , // 0x24, 36, $
17 0x00 , 0x00 , 0x00 , 0x03 , // 0x25, 37, %
18 0x00 , 0x00 , 0x00 , 0x03 , // 0x26, 38, &
19 0x03 , 0x00 , 0x00 , 0x01 , // 0x27, 39, '
20 0x0e , 0x11 , 0x00 , 0x02 , // 0x28, 40, (
21 0x11 , 0x0e , 0x00 , 0x02 , // 0x29, 41, )
22 0x00 , 0x00 , 0x00 , 0x03 , // 0x2A, 42, *
23 0x08 , 0x1c , 0x08 , 0x03 , // 0x2B, 43, +
24 0x18 , 0x00 , 0x00 , 0x01 , // 0x2C, 44, ,
25 0x04 , 0x04 , 0x00 , 0x03 , // 0x2D, 45, -
26 0x10 , 0x00 , 0x00 , 0x01 , // 0x2E, 46, .
27 0x18 , 0x04 , 0x03 , 0x03 , // 0x2F, 47, /
28 0x1f , 0x11 , 0x1f , 0x03 , // 0x30, 48, 0
29 0x01 , 0x1f , 0x00 , 0x02 , // 0x31, 49, 1
30 0x1d , 0x15 , 0x17 , 0x03 , // 0x32, 50, 2
31 0x15 , 0x15 , 0x0e , 0x03 , // 0x33, 51, 3
32 0x0f , 0x08 , 0x1f , 0x03 , // 0x34, 52, 4
33 0x17 , 0x15 , 0x1d , 0x03 , // 0x35, 53, 5
34 0x1f , 0x12 , 0x1e , 0x03 , // 0x36, 54, 6
35 0x11 , 0x09 , 0x07 , 0x03 , // 0x37, 55, 7
36 0x1f , 0x15 , 0x1f , 0x03 , // 0x38, 56, 8
37 0x0f , 0x09 , 0x1f , 0x03 , // 0x39, 57, 9
38 0x0a , 0x00 , 0x00 , 0x01 , // 0x3A, 58, :
39 0x1a , 0x00 , 0x00 , 0x01 , // 0x3B, 59, ;
40 0x08 , 0x14 , 0x00 , 0x02 , // 0x3C, 60, <
41 0x14 , 0x14 , 0x00 , 0x02 , // 0x3D, 61, =
42 0x14 , 0x08 , 0x00 , 0x02 , // 0x3E, 62, >
43 0x15 , 0x05 , 0x02 , 0x03 , // 0x3F, 63, ?
44 0x0e , 0x17 , 0x16 , 0x03 , // 0x40, 64, @
45 0x1f , 0x09 , 0x1e , 0x03 , // 0x41, 65, A
46 0x1f , 0x15 , 0x0a , 0x03 , // 0x42, 66, B
47 0x0e , 0x11 , 0x11 , 0x03 , // 0x43, 67, C
48 0x1f , 0x11 , 0x0e , 0x03 , // 0x44, 68, D
49 0x0e , 0x15 , 0x15 , 0x03 , // 0x45, 69, E
50 0x1e , 0x05 , 0x05 , 0x03 , // 0x46, 70, F
51 0x0e , 0x11 , 0x1d , 0x03 , // 0x47, 71, G
52 0x1f , 0x04 , 0x1f , 0x03 , // 0x48, 72, H
53 0x1f , 0x00 , 0x00 , 0x01 , // 0x49, 73, I
54 0x08 , 0x10 , 0x0f , 0x03 , // 0x4A, 74, J
55 0x1f , 0x04 , 0x1b , 0x03 , // 0x4B, 75, K
56 0x0f , 0x10 , 0x10 , 0x03 , // 0x4C, 76, L
57 0x1f , 0x02 , 0x1f , 0x03 , // 0x4D, 77, M
58 0x1f , 0x01 , 0x1e , 0x03 , // 0x4E, 78, N
59 0x0e , 0x11 , 0x0e , 0x03 , // 0x4F, 79, O
60 0x1f , 0x09 , 0x06 , 0x03 , // 0x50, 80, P
61 0x06 , 0x19 , 0x06 , 0x03 , // 0x51, 81, Q
62 0x1f , 0x09 , 0x16 , 0x03 , // 0x52, 82, R
63 0x12 , 0x15 , 0x09 , 0x03 , // 0x53, 83, S
64 0x01 , 0x1f , 0x01 , 0x03 , // 0x54, 84, T
65 0x0f , 0x10 , 0x0f , 0x03 , // 0x55, 85, U
66 0x1f , 0x10 , 0x0f , 0x03 , // 0x56, 86, V
67 0x1f , 0x08 , 0x1f , 0x03 , // 0x57, 87, W
68 0x1b , 0x04 , 0x1b , 0x03 , // 0x58, 88, X
69 0x03 , 0x1c , 0x03 , 0x03 , // 0x59, 89, Y
70 0x19 , 0x15 , 0x13 , 0x03 , // 0x5A, 90, Z
71 0x1f , 0x11 , 0x00 , 0x02 , // 0x5B, 91, [
72 0x03 , 0x04 , 0x18 , 0x03 , // 0x5C, 92,
73 0x11 , 0x1f , 0x00 , 0x02 , // 0x5D, 93, [
74 0x11 , 0x1f , 0x00 , 0x02 , // 0x5E, 94, ^
75 0x1f , 0x1f , 0x1f , 0x03 // 0x5F, 95, _, used as block, all on
76 };
77
78 #endif /*FONT_H_*/
79
80 #include <inttypes.h>
81 #include <stdlib.h>
82 #include <string.h>
83 #include <avr/io.h>
84 #include <avr/interrupt.h>
85 #include <avr/eeprom.h>
86 #include <util/delay.h>
87 #include <avr/pgmspace.h>
88
89 // Change these values to adjust scroll speeds and animation iterations
90 #define ANIMATION_SCROLL_SPEED 80 // how fast to scroll the animations
91 #define TEXT_SCROLL_SPEED 120 // how fast to scrill the text
92 #define REPEAT_ANIMATION 10 // how often to repeat the animation if in cycling mode
93 #define REPEAT_TEXT 5 // how often to repeat the text if in cycling mode
94
95 // How to add a new message:
96 // * add the new message (only upper case, see font.h)
97 // * adjust MAX_MESSAGES
98 // * add the new message to messages
99 // NOTE: messages may not be longer than 59 chars. Otherwise they will not fit in the buffer.
100 // 123456789012345678901234567890123456789012345678901234567890
101 const prog_char PROGMEM message_00 [] PROGMEM = " I LOVE U " ;
102
103 #define MAX_MESSAGES 12
104 PGM_P PROGMEM messages [] = {
105 message_00
106
107 };
108
109 #define MAX_ANIMATIONS 1
110
111
112 const prog_uint8_t PROGMEM sprite_03 [ 8 ] =
113 {
114 0x00 , // ________
115 0x66 , // _XX__XX_
116 0xFF , // XXXXXXXX
117 0xFF , // XXXXXXXX
118 0xFF , // XXXXXXXX
119 0x7E , // _XXXXXX_
120 0x3C , // __XXXX__
121 0x18 // ___XX___
122 };
123
124
125
126
127 uint8_t mode_ee EEMEM = 0 ; // stores the mode in eeprom
128 static uint8_t screen_mem [ 8 ]; // screen memory
129 static uint8_t active_row ; // active row
130 static uint8_t buffer [ 60 ]; // stores the active message or sprite
131 static uint8_t message_ptr = 0 ; // points to the active char in the message
132 static uint8_t message_displayed = 0 ; // how often has the message been displayed?
133 static uint8_t active_char = 0 ; // stores the active char
134 static uint8_t message_length = 0 ; // stores the length of the active message
135 static uint8_t char_ptr = 0 ; // points to the active col in the char
136 static uint8_t char_length = 0 ; // stores the length of the active char
137 static volatile uint16_t counter = 0 ; // used for delay function
138
139 // prototypes
140 void delay_ms ( uint16_t delay );
141 void copy_to_display ( int8_t x , int8_t y , uint8_t sprite []);
142 void display_active_row ( void );
143 void show_char ();
144 void clear_screen ( void );
145 void copy_to_buffer ( const prog_uint8_t sprite [ 8 ]);
146 void scroll_animation ( const prog_uint8_t sprite_1 [], const prog_uint8_t sprite_2 []);
147
148
149
150 /*
151 * ISR TIMER0_OVF_vect
152 * Handles overflow interrupts of timer 0.
153 *
154 * 4MHz
155 * ----
156 * Prescaler 8 ==> 1953.1 Hz
157 * Complete display = 244 Hz
158 *
159 */
160 ISR ( TIMER0_OVF_vect ) {
161 display_active_row ();
162 counter ++ ;
163 }
164
165
166
167 /*
168 * delay_ms
169 * Uses the counter that is incremented by the ISR.
170 * Max delay is 32767ms.
171 */
172 void delay_ms ( uint16_t delay ) {
173 while ( ! ( PIND & ( 1 << PD6 ))) {} // used to stop the animation when PD6 goes LOW
174 uint16_t t = delay * 2 ;
175 counter = 0 ;
176 while ( counter < t ) {}
177 }
178
179
180
181 /*
182 * copy_to_display
183 * Copies sprite data to the screen memory at the given position.
184 */
185 void copy_to_display ( int8_t x , int8_t y , uint8_t sprite [ 8 ]) {
186 int8_t i , t ;
187 uint8_t row ;
188 for ( i = 0 ; i < 8 ; i ++ ) {
189 t = i - y ;
190 row = (( t >= 0 ) && ( t < 8 )) ? sprite [ t ] : 0x00 ;
191 row = ( x >= 0 ) ? ( row >> x ) : ( row << - x );
192 screen_mem [ i ] = row ;
193 }
194 }
195
196
197
198 /*
199 * display_active_col
200 * Deactivates the active column and displays the next one.
201 * Data is read from screen_mem.
202 *
203 * ATtiny2313
204 * 16 - PD0 PB7 - 1
205 * 15 - PD1 PB6 - 2
206 * 14 - PA1 PB5 - 3
207 * 13 - PA0 PB4 - 4
208 * 12 - PD2 PB3 - 5
209 * 11 - PD3 PB2 - 6
210 * 10 - PD4 PB1 - 7
211 * 9 - PD5 PB0 - 8
212 *
213 * NFM-12883 common anode |
214 * A0B5B4D4B2D3D1D0 +-----+
215 * PD5 o o o o o o o o | |
216 * PA1 o o o o o o o o _+_ |
217 * PB0 o o o o o o o o \ / |
218 * PD2 o o o o o o o o __V__ |
219 * PB7 o o o o o o o o | |
220 * PB1 o o o o o o o o ---+-----C---
221 * PB6 o o o o o o o o |
222 * PB3 o o o o o o o o
223 *
224 */
225 void display_active_row ( void ) {
226
227 uint8_t row ;
228
229 // shut down all rows and columns
230 PORTA = ( 0 << PA0 ) | ( 1 << PA1 );
231 PORTB = ( 0 << PB5 ) | ( 0 << PB4 ) | ( 0 << PB2 ) | ( 1 << PB0 ) |
232 ( 1 << PB7 ) | ( 1 << PB1 ) | ( 1 << PB6 ) | ( 1 << PB3 );
233 PORTD = ( 0 << PD4 ) | ( 0 << PD3 ) | ( 0 << PD1 ) | ( 0 << PD0 ) |
234 ( 1 << PD5 ) | ( 1 << PD2 ) | ( 1 << PD6 );
235
236 // next row
237 active_row = ( active_row + 1 ) % 8 ;
238 row = screen_mem [ active_row ];
239
240 // output all columns, switch leds on.
241 // column 1
242 if (( row & 0x80 ) == 0x80 ) {
243 PORTA |= ( 1 << PA0 );
244 }
245 // column 2
246 if (( row & 0x40 ) == 0x40 ) {
247 PORTB |= ( 1 << PB5 );
248 }
249 // column 3
250 if (( row & 0x20 ) == 0x20 ) {
251 PORTB |= ( 1 << PB4 );
252 }
253 // column 4
254 if (( row & 0x10 ) == 0x10 ) {
255 PORTD |= ( 1 << PD4 );
256 }
257 // column 5
258 if (( row & 0x08 ) == 0x08 ) {
259 PORTB |= ( 1 << PB2 );
260 }
261 // column 6
262 if (( row & 0x04 ) == 0x04 ) {
263 PORTD |= ( 1 << PD3 );
264 }
265 // column 7
266 if (( row & 0x02 ) == 0x02 ) {
267 PORTD |= ( 1 << PD1 );
268 }
269 // column 8
270 if (( row & 0x01 ) == 0x01 ) {
271 PORTD |= ( 1 << PD0 );
272 }
273
274 // activate row
275 switch ( active_row ) {
276 case 0 :
277 PORTD &= ~ ( 1 << PD5 );
278 break ;
279 case 1 :
280 PORTA &= ~ ( 1 << PA1 );
281 break ;
282 case 2 :
283 PORTB &= ~ ( 1 << PB0 );
284 break ;
285 case 3 :
286 PORTD &= ~ ( 1 << PD2 );
287 break ;
288 case 4 :
289 PORTB &= ~ ( 1 << PB7 );
290 break ;
291 case 5 :
292 PORTB &= ~ ( 1 << PB1 );
293 break ;
294 case 6 :
295 PORTB &= ~ ( 1 << PB6 );
296 break ;
297 case 7 :
298 PORTB &= ~ ( 1 << PB3 );
299 break ;
300 }
301
302 }
303 /*
304 * Use this method, if you have a common cathode matrix.
305 */
306 /*
307 void display_active_row(void) {
308
309 uint8_t row;
310
311 // shut down all rows and columns
312 PORTB = 0x34;
313 PORTD = 0x1B;
314 PORTA = 0x01;
315
316 // next row
317 active_row = (active_row+1) % 8;
318 row = screen_mem[active_row];
319
320 // output all columns, switch leds on.
321 // column 1
322 if ((row & 0x80) == 0x80) {
323 PORTA &= ~(1 << PA0);
324 }
325 // column 2
326 if ((row & 0x40) == 0x40) {
327 PORTB &= ~(1 << PB5);
328 }
329 // column 3
330 if ((row & 0x20) == 0x20) {
331 PORTB &= ~(1 << PB4);
332 }
333 // column 4
334 if ((row & 0x10) == 0x10) {
335 PORTD &= ~(1 << PD4);
336 }
337 // column 5
338 if ((row & 0x08) == 0x08) {
339 PORTB &= ~(1 << PB2);
340 }
341 // column 6
342 if ((row & 0x04) == 0x04) {
343 PORTD &= ~(1 << PD3);
344 }
345 // column 7
346 if ((row & 0x02) == 0x02) {
347 PORTD &= ~(1 << PD1);
348 }
349 // column 8
350 if ((row & 0x01) == 0x01) {
351 PORTD &= ~(1 << PD0);
352 }
353
354 // activate row
355 switch (active_row) {
356 case 0:
357 PORTD |= (1 << PD5);
358 break;
359 case 1:
360 PORTA |= (1 << PA1);
361 break;
362 case 2:
363 PORTB |= (1 << PB0);
364 break;
365 case 3:
366 PORTD |= (1 << PD2);
367 break;
368 case 4:
369 PORTB |= (1 << PB7);
370 break;
371 case 5:
372 PORTB |= (1 << PB1);
373 break;
374 case 6:
375 PORTB |= (1 << PB6);
376 break;
377 case 7:
378 PORTB |= (1 << PB3);
379 break;
380 }
381
382 }
383 */
384
385
386 /*
387 * show_char
388 * Displays the actual message.
389 * Scrolls the screen to the left and draws new pixels on the right.
390 */
391 void show_char () {
392 uint8_t i ;
393 uint8_t b ;
394
395 // blit the screen to the left
396 for ( i = 0 ; i < 8 ; i ++ ) {
397 screen_mem [ i ] <<= 1 ;
398 }
399 // advance a char if needed
400 if ( char_ptr == char_length ) {
401 message_ptr ++ ;
402 if ( message_ptr == message_length ) {
403 message_ptr = 0 ;
404 message_displayed ++ ;
405 }
406 active_char = buffer [ message_ptr ] - CHAR_OFFSET ;
407 char_length = pgm_read_byte ( & font [ active_char * 4 + 3 ]);
408 char_ptr = 0 ;
409 return ; // this makes the space between two chars
410 }
411 // read pixels for current column of char
412 b = pgm_read_byte ( & font [ active_char * 4 + char_ptr ++ ]);
413 // write pixels into screen memory
414 for ( i = 0 ; i < 7 ; i ++ ) {
415 if (( b & ( 1 << i )) == ( 1 << i )) {
416 screen_mem [ i + 1 ] |= 0x01 ;
417 }
418 }
419 }
420
421
422
423 /*
424 * clear_screen
425 */
426 void clear_screen ( void ) {
427 uint8_t i ;
428 for ( i = 0 ; i < 8 ; i ++ ) {
429 screen_mem [ i ] = 0x00 ;
430 }
431 }
432
433
434
435 /*
436 * copy_to_buffer
437 * Copies the given sprite from PROGMEM to RAM.
438 */
439 void copy_to_buffer ( const prog_uint8_t sprite [ 8 ]) {
440 memcpy_P ( buffer , sprite , 8 );
441 }
442
443
444
445 /*
446 * scroll_animation
447 * Uses sprite_1 and sprite_2 to draw a simple animation.
448 */
449 void scroll_animation ( const prog_uint8_t sprite_1 [ 8 ], const prog_uint8_t sprite_2 [ 8 ]) {
450 uint8_t i ;
451 int8_t x ;
452 for ( i = 0 ; i < REPEAT_ANIMATION ; i ++ ) {
453 copy_to_buffer ( sprite_1 );
454 for ( x = - 8 ; x <= 0 ; x ++ ) {
455 copy_to_display ( x , 0 , buffer );
456 delay_ms ( ANIMATION_SCROLL_SPEED );
457 }
458 delay_ms ( 200 );
459 copy_to_buffer ( sprite_2 );
460 copy_to_display ( 0 , 0 , buffer );
461 delay_ms ( 200 );
462 copy_to_buffer ( sprite_1 );
463 copy_to_display ( 0 , 0 , buffer );
464 delay_ms ( 200 );
465 copy_to_buffer ( sprite_2 );
466 copy_to_display ( 0 , 0 , buffer );
467 delay_ms ( 200 );
468 copy_to_buffer ( sprite_1 );
469 for ( x = 0 ; x < 8 ; x ++ ) {
470 copy_to_display ( x , 0 , buffer );
471 delay_ms ( ANIMATION_SCROLL_SPEED );
472 }
473 }
474 }
475
476
477
478 int main ( void ) {
479
480 uint8_t i = 0 ;
481 uint8_t mode = 0 ;
482 uint8_t cycle = 0 ;
483
484 // timer 0 setup, prescaler 8
485 TCCR0B |= ( 1 << CS01 );
486
487 // enable timer 0 interrupt
488 TIMSK |= ( 1 << TOIE0 );
489
490 // define outputs
491 DDRA |= 0x03 ;
492 DDRB |= 0xFF ;
493 DDRD |= 0x3F ;
494
495 // shut down all rows and columns, enable column 1
496 PORTA = ( 1 << PA0 ) | ( 1 << PA1 );
497 PORTB = ( 0 << PB5 ) | ( 0 << PB4 ) | ( 0 << PB2 ) | ( 1 << PB0 ) |
498 ( 1 << PB7 ) | ( 1 << PB1 ) | ( 1 << PB6 ) | ( 1 << PB3 );
499 PORTD = ( 0 << PD4 ) | ( 0 << PD3 ) | ( 0 << PD1 ) | ( 0 << PD0 ) |
500 ( 1 << PD5 ) | ( 1 << PD2 );
501
502 // enable pull ups
503 PORTD |= ( 1 << PD6 );
504
505 // say hello, toggle row 1 (pixel 0,0)
506 for ( i = 0 ; i < 5 ; i ++ ) {
507 PORTD &= ~ ( 1 << PD5 );
508 _delay_ms ( 50 );
509 PORTD |= ( 1 << PD5 );
510 _delay_ms ( 50 );
511 }
512
513 // read last mode from eeprom
514 // 0 mean cycle through all modes and messages
515 mode = eeprom_read_byte ( & mode_ee );
516 if (( mode == 0 ) || ( mode >= ( MAX_ANIMATIONS + MAX_MESSAGES + 1 ))) {
517 mode = 1 ;
518 cycle = 1 ;
519 }
520 eeprom_write_byte ( & mode_ee , mode + 1 );
521
522 sei ();
523
524 while ( 1 ) {
525
526 switch ( mode ) {
527 case 1 :
528 break ;
529 case 2 :
530 for ( i = 0 ; i < REPEAT_ANIMATION ; i ++ ) {
531 copy_to_buffer ( sprite_03 );
532 copy_to_display ( 0 , 0 , buffer );
533 delay_ms ( 750 );
534 }
535 break ;
536 case 3 :
537 break ;
538 default:
539 while ( message_displayed < REPEAT_TEXT ) {
540 show_char ();
541 delay_ms ( TEXT_SCROLL_SPEED );
542 }
543 message_displayed = 0 ;
544 break ;
545 }
546
547 // cycle through all modes
548 if ( cycle ) {
549 mode ++ ;
550 clear_screen ();
551 if ( mode >= ( MAX_ANIMATIONS + MAX_MESSAGES + 1 )) {
552 mode = 1 ;
553 }
554 }
555
556 }
557
558 return 0 ;
559
560 }
von
Maddin (Gast)
17.02.2011 18:01
reinfunken und gucken!
wo kommt das denn her? Es gibt schon noch 2 3 Codeschnipsel mehr hier...
M.
Markus schrieb:
> Hab das Programm von dieser seite ein bisschen gekürzt. ist das so
> korrekt?
Gibt es Probleme oder warum schreibst du das?
Ich meine was erwartest du?
Dass wir das ganze Programm durchdenken ohne konkrete Problemstellung
und vernünfigen Schaltplan... was erhoffst du dir?
Wenn du wissen möchtest ob es funktioniert - probier es aus ... kaputt
machen kannst du wohl kaum was ...
von
Markus (Gast)
17.02.2011 18:10
so hatte ausversehen das falsche geschickt ^^
also ich weiß jetzt nicht wie ich das auf eine 5x7 matrix umschreiben
soll. wie kann ich das am besten umsetzen? 1 #include <avr/io.h>
2 #include <avr/pgmspace.h>
3
4 #ifndef FONT_H_
5 #define FONT_H_
6
7 #define MAX_CHARS 59
8 #define CHAR_OFFSET 0x20
9
10 const uint8_t font [] PROGMEM = {
11 // 3 chars bitmap, 1 char length
12 0x00 , 0x00 , 0x00 , 0x01 , // 0x20, 32, ' '
13 0x17 , 0x00 , 0x00 , 0x01 , // 0x21, 33, !
14 0x03 , 0x00 , 0x03 , 0x03 , // 0x22, 34, "
15 0x00 , 0x00 , 0x00 , 0x03 , // 0x23, 35, #
16 0x00 , 0x00 , 0x00 , 0x03 , // 0x24, 36, $
17 0x00 , 0x00 , 0x00 , 0x03 , // 0x25, 37, %
18 0x00 , 0x00 , 0x00 , 0x03 , // 0x26, 38, &
19 0x03 , 0x00 , 0x00 , 0x01 , // 0x27, 39, '
20 0x0e , 0x11 , 0x00 , 0x02 , // 0x28, 40, (
21 0x11 , 0x0e , 0x00 , 0x02 , // 0x29, 41, )
22 0x00 , 0x00 , 0x00 , 0x03 , // 0x2A, 42, *
23 0x08 , 0x1c , 0x08 , 0x03 , // 0x2B, 43, +
24 0x18 , 0x00 , 0x00 , 0x01 , // 0x2C, 44, ,
25 0x04 , 0x04 , 0x00 , 0x03 , // 0x2D, 45, -
26 0x10 , 0x00 , 0x00 , 0x01 , // 0x2E, 46, .
27 0x18 , 0x04 , 0x03 , 0x03 , // 0x2F, 47, /
28 0x1f , 0x11 , 0x1f , 0x03 , // 0x30, 48, 0
29 0x01 , 0x1f , 0x00 , 0x02 , // 0x31, 49, 1
30 0x1d , 0x15 , 0x17 , 0x03 , // 0x32, 50, 2
31 0x15 , 0x15 , 0x0e , 0x03 , // 0x33, 51, 3
32 0x0f , 0x08 , 0x1f , 0x03 , // 0x34, 52, 4
33 0x17 , 0x15 , 0x1d , 0x03 , // 0x35, 53, 5
34 0x1f , 0x12 , 0x1e , 0x03 , // 0x36, 54, 6
35 0x11 , 0x09 , 0x07 , 0x03 , // 0x37, 55, 7
36 0x1f , 0x15 , 0x1f , 0x03 , // 0x38, 56, 8
37 0x0f , 0x09 , 0x1f , 0x03 , // 0x39, 57, 9
38 0x0a , 0x00 , 0x00 , 0x01 , // 0x3A, 58, :
39 0x1a , 0x00 , 0x00 , 0x01 , // 0x3B, 59, ;
40 0x08 , 0x14 , 0x00 , 0x02 , // 0x3C, 60, <
41 0x14 , 0x14 , 0x00 , 0x02 , // 0x3D, 61, =
42 0x14 , 0x08 , 0x00 , 0x02 , // 0x3E, 62, >
43 0x15 , 0x05 , 0x02 , 0x03 , // 0x3F, 63, ?
44 0x0e , 0x17 , 0x16 , 0x03 , // 0x40, 64, @
45 0x1f , 0x09 , 0x1e , 0x03 , // 0x41, 65, A
46 0x1f , 0x15 , 0x0a , 0x03 , // 0x42, 66, B
47 0x0e , 0x11 , 0x11 , 0x03 , // 0x43, 67, C
48 0x1f , 0x11 , 0x0e , 0x03 , // 0x44, 68, D
49 0x0e , 0x15 , 0x15 , 0x03 , // 0x45, 69, E
50 0x1e , 0x05 , 0x05 , 0x03 , // 0x46, 70, F
51 0x0e , 0x11 , 0x1d , 0x03 , // 0x47, 71, G
52 0x1f , 0x04 , 0x1f , 0x03 , // 0x48, 72, H
53 0x1f , 0x00 , 0x00 , 0x01 , // 0x49, 73, I
54 0x08 , 0x10 , 0x0f , 0x03 , // 0x4A, 74, J
55 0x1f , 0x04 , 0x1b , 0x03 , // 0x4B, 75, K
56 0x0f , 0x10 , 0x10 , 0x03 , // 0x4C, 76, L
57 0x1f , 0x02 , 0x1f , 0x03 , // 0x4D, 77, M
58 0x1f , 0x01 , 0x1e , 0x03 , // 0x4E, 78, N
59 0x0e , 0x11 , 0x0e , 0x03 , // 0x4F, 79, O
60 0x1f , 0x09 , 0x06 , 0x03 , // 0x50, 80, P
61 0x06 , 0x19 , 0x06 , 0x03 , // 0x51, 81, Q
62 0x1f , 0x09 , 0x16 , 0x03 , // 0x52, 82, R
63 0x12 , 0x15 , 0x09 , 0x03 , // 0x53, 83, S
64 0x01 , 0x1f , 0x01 , 0x03 , // 0x54, 84, T
65 0x0f , 0x10 , 0x0f , 0x03 , // 0x55, 85, U
66 0x1f , 0x10 , 0x0f , 0x03 , // 0x56, 86, V
67 0x1f , 0x08 , 0x1f , 0x03 , // 0x57, 87, W
68 0x1b , 0x04 , 0x1b , 0x03 , // 0x58, 88, X
69 0x03 , 0x1c , 0x03 , 0x03 , // 0x59, 89, Y
70 0x19 , 0x15 , 0x13 , 0x03 , // 0x5A, 90, Z
71 0x1f , 0x11 , 0x00 , 0x02 , // 0x5B, 91, [
72 0x03 , 0x04 , 0x18 , 0x03 , // 0x5C, 92,
73 0x11 , 0x1f , 0x00 , 0x02 , // 0x5D, 93, [
74 0x11 , 0x1f , 0x00 , 0x02 , // 0x5E, 94, ^
75 0x1f , 0x1f , 0x1f , 0x03 // 0x5F, 95, _, used as block, all on
76 };
77
78 #endif /*FONT_H_*/
79
80 #include <inttypes.h>
81 #include <stdlib.h>
82 #include <string.h>
83 #include <avr/io.h>
84 #include <avr/interrupt.h>
85 #include <avr/eeprom.h>
86 #include <util/delay.h>
87 #include <avr/pgmspace.h>
88
89 // Change these values to adjust scroll speeds and animation iterations
90 #define ANIMATION_SCROLL_SPEED 80 // how fast to scroll the animations
91 #define TEXT_SCROLL_SPEED 120 // how fast to scrill the text
92 #define REPEAT_ANIMATION 10 // how often to repeat the animation if in cycling mode
93 #define REPEAT_TEXT 5 // how often to repeat the text if in cycling mode
94
95 // How to add a new message:
96 // * add the new message (only upper case, see font.h)
97 // * adjust MAX_MESSAGES
98 // * add the new message to messages
99 // NOTE: messages may not be longer than 59 chars. Otherwise they will not fit in the buffer.
100 // 123456789012345678901234567890123456789012345678901234567890
101 const prog_char PROGMEM message_00 [] PROGMEM = " I LOVE U " ;
102
103 #define MAX_MESSAGES 12
104 PGM_P PROGMEM messages [] = {
105 message_00
106
107 };
108
109 #define MAX_ANIMATIONS 1
110
111
112 const prog_uint8_t PROGMEM sprite_03 [ 8 ] =
113 {
114 0x00 , // ________
115 0x66 , // _XX__XX_
116 0xFF , // XXXXXXXX
117 0xFF , // XXXXXXXX
118 0xFF , // XXXXXXXX
119 0x7E , // _XXXXXX_
120 0x3C , // __XXXX__
121 0x18 // ___XX___
122 };
123
124
125
126
127 uint8_t mode_ee EEMEM = 0 ; // stores the mode in eeprom
128 static uint8_t screen_mem [ 8 ]; // screen memory
129 static uint8_t active_row ; // active row
130 static uint8_t buffer [ 60 ]; // stores the active message or sprite
131 static uint8_t message_ptr = 0 ; // points to the active char in the message
132 static uint8_t message_displayed = 0 ; // how often has the message been displayed?
133 static uint8_t active_char = 0 ; // stores the active char
134 static uint8_t message_length = 0 ; // stores the length of the active message
135 static uint8_t char_ptr = 0 ; // points to the active col in the char
136 static uint8_t char_length = 0 ; // stores the length of the active char
137 static volatile uint16_t counter = 0 ; // used for delay function
138
139 // prototypes
140 void delay_ms ( uint16_t delay );
141 void copy_to_display ( int8_t x , int8_t y , uint8_t sprite []);
142 void display_active_row ( void );
143 void show_char ();
144 void clear_screen ( void );
145 void copy_to_buffer ( const prog_uint8_t sprite [ 8 ]);
146 void scroll_animation ( const prog_uint8_t sprite_1 [], const prog_uint8_t sprite_2 []);
147
148
149
150 /*
151 * ISR TIMER0_OVF_vect
152 * Handles overflow interrupts of timer 0.
153 *
154 * 4MHz
155 * ----
156 * Prescaler 8 ==> 1953.1 Hz
157 * Complete display = 244 Hz
158 *
159 */
160 ISR ( TIMER0_OVF_vect ) {
161 display_active_row ();
162 counter ++ ;
163 }
164
165
166
167 /*
168 * delay_ms
169 * Uses the counter that is incremented by the ISR.
170 * Max delay is 32767ms.
171 */
172 void delay_ms ( uint16_t delay ) {
173 while ( ! ( PIND & ( 1 << PD6 ))) {} // used to stop the animation when PD6 goes LOW
174 uint16_t t = delay * 2 ;
175 counter = 0 ;
176 while ( counter < t ) {}
177 }
178
179
180
181 /*
182 * copy_to_display
183 * Copies sprite data to the screen memory at the given position.
184 */
185 void copy_to_display ( int8_t x , int8_t y , uint8_t sprite [ 8 ]) {
186 int8_t i , t ;
187 uint8_t row ;
188 for ( i = 0 ; i < 8 ; i ++ ) {
189 t = i - y ;
190 row = (( t >= 0 ) && ( t < 8 )) ? sprite [ t ] : 0x00 ;
191 row = ( x >= 0 ) ? ( row >> x ) : ( row << - x );
192 screen_mem [ i ] = row ;
193 }
194 }
195
196
197
198 /*
199 * display_active_col
200 * Deactivates the active column and displays the next one.
201 * Data is read from screen_mem.
202 *
203 * ATtiny2313
204 * 16 - PD0 PB7 - 1
205 * 15 - PD1 PB6 - 2
206 * 14 - PA1 PB5 - 3
207 * 13 - PA0 PB4 - 4
208 * 12 - PD2 PB3 - 5
209 * 11 - PD3 PB2 - 6
210 * 10 - PD4 PB1 - 7
211 * 9 - PD5 PB0 - 8
212 *
213 * NFM-12883 common anode |
214 * A0B5B4D4B2D3D1D0 +-----+
215 * PD5 o o o o o o o o | |
216 * PA1 o o o o o o o o _+_ |
217 * PB0 o o o o o o o o \ / |
218 * PD2 o o o o o o o o __V__ |
219 * PB7 o o o o o o o o | |
220 * PB1 o o o o o o o o ---+-----C---
221 * PB6 o o o o o o o o |
222 * PB3 o o o o o o o o
223 *
224 */
225 void display_active_row ( void ) {
226
227 uint8_t row ;
228
229 // shut down all rows and columns
230 PORTA = ( 0 << PA0 ) | ( 1 << PA1 );
231 PORTB = ( 0 << PB5 ) | ( 0 << PB4 ) | ( 0 << PB2 ) | ( 1 << PB0 ) |
232 ( 1 << PB7 ) | ( 1 << PB1 ) | ( 1 << PB6 ) | ( 1 << PB3 );
233 PORTD = ( 0 << PD4 ) | ( 0 << PD3 ) | ( 0 << PD1 ) | ( 0 << PD0 ) |
234 ( 1 << PD5 ) | ( 1 << PD2 ) | ( 1 << PD6 );
235
236 // next row
237 active_row = ( active_row + 1 ) % 8 ;
238 row = screen_mem [ active_row ];
239
240 // output all columns, switch leds on.
241 // column 1
242 if (( row & 0x80 ) == 0x80 ) {
243 PORTA |= ( 1 << PA0 );
244 }
245 // column 2
246 if (( row & 0x40 ) == 0x40 ) {
247 PORTB |= ( 1 << PB5 );
248 }
249 // column 3
250 if (( row & 0x20 ) == 0x20 ) {
251 PORTB |= ( 1 << PB4 );
252 }
253 // column 4
254 if (( row & 0x10 ) == 0x10 ) {
255 PORTD |= ( 1 << PD4 );
256 }
257 // column 5
258 if (( row & 0x08 ) == 0x08 ) {
259 PORTB |= ( 1 << PB2 );
260 }
261 // column 6
262 if (( row & 0x04 ) == 0x04 ) {
263 PORTD |= ( 1 << PD3 );
264 }
265 // column 7
266 if (( row & 0x02 ) == 0x02 ) {
267 PORTD |= ( 1 << PD1 );
268 }
269 // column 8
270 if (( row & 0x01 ) == 0x01 ) {
271 PORTD |= ( 1 << PD0 );
272 }
273
274 // activate row
275 switch ( active_row ) {
276 case 0 :
277 PORTD &= ~ ( 1 << PD5 );
278 break ;
279 case 1 :
280 PORTA &= ~ ( 1 << PA1 );
281 break ;
282 case 2 :
283 PORTB &= ~ ( 1 << PB0 );
284 break ;
285 case 3 :
286 PORTD &= ~ ( 1 << PD2 );
287 break ;
288 case 4 :
289 PORTB &= ~ ( 1 << PB7 );
290 break ;
291 case 5 :
292 PORTB &= ~ ( 1 << PB1 );
293 break ;
294 case 6 :
295 PORTB &= ~ ( 1 << PB6 );
296 break ;
297 case 7 :
298 PORTB &= ~ ( 1 << PB3 );
299 break ;
300 }
301
302 }
303 /*
304 * Use this method, if you have a common cathode matrix.
305 */
306 /*
307 void display_active_row(void) {
308
309 uint8_t row;
310
311 // shut down all rows and columns
312 PORTB = 0x34;
313 PORTD = 0x1B;
314 PORTA = 0x01;
315
316 // next row
317 active_row = (active_row+1) % 8;
318 row = screen_mem[active_row];
319
320 // output all columns, switch leds on.
321 // column 1
322 if ((row & 0x80) == 0x80) {
323 PORTA &= ~(1 << PA0);
324 }
325 // column 2
326 if ((row & 0x40) == 0x40) {
327 PORTB &= ~(1 << PB5);
328 }
329 // column 3
330 if ((row & 0x20) == 0x20) {
331 PORTB &= ~(1 << PB4);
332 }
333 // column 4
334 if ((row & 0x10) == 0x10) {
335 PORTD &= ~(1 << PD4);
336 }
337 // column 5
338 if ((row & 0x08) == 0x08) {
339 PORTB &= ~(1 << PB2);
340 }
341 // column 6
342 if ((row & 0x04) == 0x04) {
343 PORTD &= ~(1 << PD3);
344 }
345 // column 7
346 if ((row & 0x02) == 0x02) {
347 PORTD &= ~(1 << PD1);
348 }
349 // column 8
350 if ((row & 0x01) == 0x01) {
351 PORTD &= ~(1 << PD0);
352 }
353
354 // activate row
355 switch (active_row) {
356 case 0:
357 PORTD |= (1 << PD5);
358 break;
359 case 1:
360 PORTA |= (1 << PA1);
361 break;
362 case 2:
363 PORTB |= (1 << PB0);
364 break;
365 case 3:
366 PORTD |= (1 << PD2);
367 break;
368 case 4:
369 PORTB |= (1 << PB7);
370 break;
371 case 5:
372 PORTB |= (1 << PB1);
373 break;
374 case 6:
375 PORTB |= (1 << PB6);
376 break;
377 case 7:
378 PORTB |= (1 << PB3);
379 break;
380 }
381
382 }
383 */
384
385
386 /*
387 * show_char
388 * Displays the actual message.
389 * Scrolls the screen to the left and draws new pixels on the right.
390 */
391 void show_char () {
392 uint8_t i ;
393 uint8_t b ;
394
395 // blit the screen to the left
396 for ( i = 0 ; i < 8 ; i ++ ) {
397 screen_mem [ i ] <<= 1 ;
398 }
399 // advance a char if needed
400 if ( char_ptr == char_length ) {
401 message_ptr ++ ;
402 if ( message_ptr == message_length ) {
403 message_ptr = 0 ;
404 message_displayed ++ ;
405 }
406 active_char = buffer [ message_ptr ] - CHAR_OFFSET ;
407 char_length = pgm_read_byte ( & font [ active_char * 4 + 3 ]);
408 char_ptr = 0 ;
409 return ; // this makes the space between two chars
410 }
411 // read pixels for current column of char
412 b = pgm_read_byte ( & font [ active_char * 4 + char_ptr ++ ]);
413 // write pixels into screen memory
414 for ( i = 0 ; i < 7 ; i ++ ) {
415 if (( b & ( 1 << i )) == ( 1 << i )) {
416 screen_mem [ i + 1 ] |= 0x01 ;
417 }
418 }
419 }
420
421
422
423 /*
424 * clear_screen
425 */
426 void clear_screen ( void ) {
427 uint8_t i ;
428 for ( i = 0 ; i < 8 ; i ++ ) {
429 screen_mem [ i ] = 0x00 ;
430 }
431 }
432
433
434
435 /*
436 * copy_to_buffer
437 * Copies the given sprite from PROGMEM to RAM.
438 */
439 void copy_to_buffer ( const prog_uint8_t sprite [ 8 ]) {
440 memcpy_P ( buffer , sprite , 8 );
441 }
442
443
444
445 /*
446 * scroll_animation
447 * Uses sprite_1 and sprite_2 to draw a simple animation.
448 */
449 void scroll_animation ( const prog_uint8_t sprite_1 [ 8 ], const prog_uint8_t sprite_2 [ 8 ]) {
450 uint8_t i ;
451 int8_t x ;
452 for ( i = 0 ; i < REPEAT_ANIMATION ; i ++ ) {
453 copy_to_buffer ( sprite_1 );
454 for ( x = - 8 ; x <= 0 ; x ++ ) {
455 copy_to_display ( x , 0 , buffer );
456 delay_ms ( ANIMATION_SCROLL_SPEED );
457 }
458 delay_ms ( 200 );
459 copy_to_buffer ( sprite_2 );
460 copy_to_display ( 0 , 0 , buffer );
461 delay_ms ( 200 );
462 copy_to_buffer ( sprite_1 );
463 copy_to_display ( 0 , 0 , buffer );
464 delay_ms ( 200 );
465 copy_to_buffer ( sprite_2 );
466 copy_to_display ( 0 , 0 , buffer );
467 delay_ms ( 200 );
468 copy_to_buffer ( sprite_1 );
469 for ( x = 0 ; x < 8 ; x ++ ) {
470 copy_to_display ( x , 0 , buffer );
471 delay_ms ( ANIMATION_SCROLL_SPEED );
472 }
473 }
474 }
475
476
477
478 int main ( void ) {
479
480 uint8_t i = 0 ;
481 uint8_t mode = 0 ;
482 uint8_t cycle = 0 ;
483
484 // timer 0 setup, prescaler 8
485 TCCR0B |= ( 1 << CS01 );
486
487 // enable timer 0 interrupt
488 TIMSK |= ( 1 << TOIE0 );
489
490 // define outputs
491 DDRA |= 0x03 ;
492 DDRB |= 0xFF ;
493 DDRD |= 0x3F ;
494
495 // shut down all rows and columns, enable column 1
496 PORTA = ( 1 << PA0 ) | ( 1 << PA1 );
497 PORTB = ( 0 << PB5 ) | ( 0 << PB4 ) | ( 0 << PB2 ) | ( 1 << PB0 ) |
498 ( 1 << PB7 ) | ( 1 << PB1 ) | ( 1 << PB6 ) | ( 1 << PB3 );
499 PORTD = ( 0 << PD4 ) | ( 0 << PD3 ) | ( 0 << PD1 ) | ( 0 << PD0 ) |
500 ( 1 << PD5 ) | ( 1 << PD2 );
501
502 // enable pull ups
503 PORTD |= ( 1 << PD6 );
504
505 // say hello, toggle row 1 (pixel 0,0)
506 for ( i = 0 ; i < 5 ; i ++ ) {
507 PORTD &= ~ ( 1 << PD5 );
508 _delay_ms ( 50 );
509 PORTD |= ( 1 << PD5 );
510 _delay_ms ( 50 );
511 }
512
513 // read last mode from eeprom
514 // 0 mean cycle through all modes and messages
515 mode = eeprom_read_byte ( & mode_ee );
516 if (( mode == 0 ) || ( mode >= ( MAX_ANIMATIONS + MAX_MESSAGES + 1 ))) {
517 mode = 1 ;
518 cycle = 1 ;
519 }
520 eeprom_write_byte ( & mode_ee , mode + 1 );
521
522 sei ();
523
524 while ( 1 ) {
525
526 switch ( mode ) {
527 case 1 :
528 break ;
529 case 2 :
530 for ( i = 0 ; i < REPEAT_ANIMATION ; i ++ ) {
531 copy_to_buffer ( sprite_03 );
532 copy_to_display ( 0 , 0 , buffer );
533 delay_ms ( 750 );
534 }
535 break ;
536 case 3 :
537 break ;
538 default:
539 while ( message_displayed < REPEAT_TEXT ) {
540 show_char ();
541 delay_ms ( TEXT_SCROLL_SPEED );
542 }
543 message_displayed = 0 ;
544 break ;
545 }
546
547 // cycle through all modes
548 if ( cycle ) {
549 mode ++ ;
550 clear_screen ();
551 if ( mode >= ( MAX_ANIMATIONS + MAX_MESSAGES + 1 )) {
552 mode = 1 ;
553 }
554 }
555
556 }
557
558 return 0 ;
559
560 }
von
Maddin (Gast)
17.02.2011 18:14
...Mensch Markus - du musst mal zum Ursprung referenzieren, damit man
mal weiß wo was angeschlossen ist, dann wo du was angeschlossen hast,
nutzt du den gleichen Prozessor, funktioniert dein Aufbau prinzipiell,
wo hakt es.... etc.
M
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.