Hallo,
möchte per 74..595 mehrere 7 Segmentanzeigen ansteuern.
Momentan habe ich erstmal einen 595 angeschlossen.
Momentan bin ich bei 3 Varianten:
1. Über manuelles rüberschieben bekomme ich Daten rein.
2. Hardware SPI klappt dagegen nicht.
3. Software SPI irgendwie auch nicht. Das ist seltsam, zumal 1.) geht.
Hier kommt nur nicht reproduzierbares Chaos rüber, bei jedem µC reset
etwas anderes.
Das Setup:
Der 595 ist über MISO, SCK und PD7 als RCK (der Pin, der die Register
auf die Ausgangspins übernimmt) angeschlossen.
µC ist ein Mega32 mit 16Mhz Quarz.
Reset des 595 ist fest auf VCC, Output enable auf GND.
Variante 1 (Jedes Bit manuell rüberschieben):
1 | #include <avr/io.h>
|
2 | #include <stdlib.h>
|
3 |
|
4 | #define RCK_DDR DDRD
|
5 | #define RCK_PORT PORTD
|
6 | #define RCK_PIN 7
|
7 | #define SPI_MOSI 5
|
8 | #define SPI_SCK 7
|
9 | #define SPI_SS 4
|
10 | #define DDR_SPI PORTB
|
11 |
|
12 |
|
13 |
|
14 | int main(void) {
|
15 |
|
16 | DDRD |= (1<<PD2); //macht eine LED an
|
17 | PORTD |= (1 << PD2);
|
18 |
|
19 |
|
20 | DDRB |= (1<<7) | (1<<5); //sck und mosi
|
21 | DDRD |= (1<<7);
|
22 | PORTB |= (1<<5);
|
23 | PORTB |= (1<<7);
|
24 |
|
25 | PORTB &= ~(1<<7);
|
26 | PORTB &= ~(1<<5);
|
27 |
|
28 | PORTB |= (1<<7); //weitere Clockimpulse
|
29 | PORTB &= ~(1<<7);
|
30 |
|
31 | PORTB |= (1<<7);
|
32 | PORTB &= ~(1<<7);
|
33 |
|
34 |
|
35 | PORTB |= (1<<7);
|
36 | PORTB &= ~(1<<7);
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | PORTD |= (1<<7); //LEDs anmachen
|
42 | PORTD &= ~(1<<7);
|
43 |
|
44 | while (1) {
|
45 |
|
46 |
|
47 | }
|
48 |
|
49 | }
|
Variante 2: Hardware SPI
1 | #include <avr/io.h>
|
2 | #include <stdlib.h>
|
3 |
|
4 | #define RCK_DDR DDRD
|
5 | #define RCK_PORT PORTD
|
6 | #define RCK_PIN 7
|
7 | #define SPI_MOSI 5
|
8 | #define SPI_SCK 7
|
9 | #define SPI_SS 4
|
10 | #define DDR_SPI PORTB
|
11 |
|
12 | void SPI_MasterInit(void);
|
13 | void display_write(uint8_t dc) {
|
14 |
|
15 | SPDR = dc;
|
16 |
|
17 | while (!(SPSR & (1 << SPIF)));
|
18 |
|
19 | RCK_PORT &= ~(1 << RCK_PIN); //LEDs anmachen
|
20 | RCK_PORT |= (1 << RCK_PIN);
|
21 |
|
22 | }
|
23 |
|
24 | int main(void) {
|
25 |
|
26 | SPI_MasterInit();
|
27 | display_write(0b10101010);
|
28 |
|
29 | DDRD |= (1<<PD2);
|
30 | PORTD |= (1 << PD2);
|
31 |
|
32 | while (1);
|
33 |
|
34 |
|
35 | }
|
36 |
|
37 | void SPI_MasterInit(void) {
|
38 | /* Set MOSI and SCK output, all others input */
|
39 | DDR_SPI = (1 << SPI_MOSI) | (1 << SPI_SCK) | (1 << SPI_SS);
|
40 | /* Enable SPI, Master, set clock rate fck/2 */
|
41 | SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0) | (1 << SPR1);
|
42 | //SPSR |= (1 << SPI2X);
|
43 |
|
44 | RCK_DDR |= (1<<RCK_PIN);
|
45 | RCK_PORT |= (1<<RCK_PIN);
|
46 | }
|
Variante 3: (Software SPI mit SPI Pins)
1 | #include <avr/io.h>
|
2 | #include <stdlib.h>
|
3 |
|
4 | #define RCK_DDR DDRD
|
5 | #define RCK_PORT PORTD
|
6 | #define RCK_PIN 7
|
7 | #define SPI_MOSI 5
|
8 | #define SPI_SCK 7
|
9 | #define SPI_SS 4
|
10 | #define DDR_SPI PORTB
|
11 |
|
12 | void SPI_MasterInit(void);
|
13 | void display_write(uint8_t dc) {
|
14 |
|
15 | unsigned char bits;
|
16 | for (bits = 8; bits > 0; bits--) {
|
17 | PORTB &= ~(1<<SPI_MOSI);
|
18 | if (dc & 0x80) {
|
19 | PORTB |= (1<<SPI_MOSI);
|
20 | }
|
21 |
|
22 | dc <<= 1;
|
23 |
|
24 | PORTB |= (1<<SPI_SCK);
|
25 | PORTB &= ~(1<<SPI_SCK);
|
26 | }
|
27 |
|
28 |
|
29 | RCK_PORT &= ~(1 << RCK_PIN);
|
30 | RCK_PORT |= (1 << RCK_PIN);
|
31 |
|
32 | }
|
33 |
|
34 | int main(void) {
|
35 |
|
36 | SPI_MasterInit();
|
37 | display_write(0b10101010);
|
38 |
|
39 | DDRD |= (1<<PD2);
|
40 | PORTD |= (1 << PD2);
|
41 |
|
42 | while (1);
|
43 |
|
44 | }
|
45 |
|
46 | void SPI_MasterInit(void) {
|
47 | /* Set MOSI and SCK output, all others input */
|
48 | DDR_SPI = (1 << SPI_MOSI) | (1 << SPI_SCK) | (1 << SPI_SS);
|
49 |
|
50 | RCK_DDR |= (1<<RCK_PIN);
|
51 | RCK_PORT |= (1<<RCK_PIN);
|
52 | PORTB &= ~(1<<SPI_SCK);
|
53 | }
|
Irgendwas essentielles muss ich übersehen, sonst würde entweder 1 auch
nicht funktionieren oder aber 3 auch klappen.
Mein Ziel ist es, es per Hardware SPI hinzubekommen.
Der µC wird über Bootloader programmiert, es hängt kein Programmer an
SPI.
Hat jemand eine Idee?