PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Gegenseitige Störung bei Schieberegistern



Ofenrohr
10.04.2010, 15:50
Moin!

Ich habe acht 74hc595 Schieberegister auf eine Testplatine gelötet und verkabelt. Alle Spannungen an den Beinen der Chips wurden von mir überprüft. Die Chips werden mit 5v von einem alten Computernetzteil versorgt und wurden nicht kaskadiert (jeder Chip hat eigene Datenleitung).

Um die Schaltung zu testen, habe ich ein c Programm für den Arduino geschrieben. Mit diesem Testprogramm kann ich vier Chips einzeln ansteuern oder eine beliebige Bitfolge senden.
Das Problem ist, dass ich nur jeden Chip einzeln ansteuern kann. Sobald ich alle Datenleitungen auf 5v stelle, also an alle ein high Signal sende, wird 0v ausgegeben. Wenn ich nur ein oder zwei Datenleitungen gleichzeitig aktiviere kann ich problemlos jede Bitfolge übertragen. Es ist dabei egal, welche vier der acht Chips ich probiere, das Verhalten bleibt gleich. Es ist auch egal, in welcher Geschwindigkeit die Daten gesendet werden: Neben Tests mit einer Sende-Funktion habe ich Schritt für Schritt die Bits gesetzt und dabei die Spannungen am Chip überprüft. Es ist im Fehlerfall alles wie es sein soll, nur dass trotz Si=5v ein low Pegel in das Register gespeichert wird (wenn vorher noch high Pegel im Register vorhanden waren, bleiben diese erhalten, bis sie "weggeshifted" wurden).

Ich bin natürlich die ganze Zeit auf der Suche nach Fehlern auf der Platine, konnte aber bisher nur eine Fehlverbindung ausmachen, die mein Problem scheinbar nicht beeinflusst hat.

Hat jemand eine Idee, was der Grund für solch ein Fehlverhalten sein kann, ich bin ziemlich ratlos...

Beste Grüße,
Ofenrohr

BASTIUniversal
10.04.2010, 18:33
Hi!
Poste doch bitte deinen Schaltplan und das (vollständige) Programm.

Gruß
Basti

Ofenrohr
11.04.2010, 16:12
Schaltplan:
http://en.ofenrohr.net/stuff/74hc595-schaltung.jpeg

Quellcode:


/*
* Copyright (C) 2010 by Tom Vincent Peters
* code@vincent-peters.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include "config.h"

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>

#include "usart.h"


#define VCCBRD_RSCK_DDR DDRC
#define VCCBRD_RSCK_PORT PORTC
#define VCCBRD_RSCK_BIT 0x01 /* 00 00 00 01 */

#define VCCBRD_D1_DDR DDRB
#define VCCBRD_D1_PORT PORTB
#define VCCBRD_D1_BIT 0x01 /* 00 00 00 01 */

#define VCCBRD_D2_DDR DDRB
#define VCCBRD_D2_PORT PORTB
#define VCCBRD_D2_BIT 0x02 /* 00 00 00 10 */

#define VCCBRD_D3_DDR DDRB
#define VCCBRD_D3_PORT PORTB
#define VCCBRD_D3_BIT 0x04 /* 00 00 01 00 */

#define VCCBRD_D4_DDR DDRB
#define VCCBRD_D4_PORT PORTB
#define VCCBRD_D4_BIT 0x08 /* 00 00 10 00 */


static uint8_t verbose;

char str_action[] PROGMEM = "action (help=h): ";
char str_help[] PROGMEM = "h: help\r\n"
"p: tootle pulsing (only test leds with pulsing turned on!)\r\n"
"s: set data which will be sent to the board\r\n"
"i: print data, pulse state and other stuff\r\n"
"r: resend data (in pulsing mode data is resend automatically)\r\n"
"v: verbose messages (clutters display with pulsing on!)\r\n"
"k: send one low bit on D1 (triggers RSCK)\r\n"
"K: send one high bit on D1 (triggers RSCK)\r\n"
"a,b,c,d,e: set D1,D2,D3,D4,RSCK to high\r\n"
"A,B,C,D,E: set D1,D2,D3,D4,RSCK to low\r\n"
"use arrow keys to manipulate data:\r\n"
"LEFT: <<=1 on all bytes of data\r\n"
"RIGHT: >>=1 on all bytes of data\r\n"
"UP: +=1 on all bytes of data\r\n"
"DOWN: -=1 on all bytes of data\r\n"
"pulsing is turned on by default\r\n"
"data is initialized to zero\r\n";
char str_data[] PROGMEM = "data: ";
char str_input[] PROGMEM = "pls write 32 bit hex val: ";
char str_flush[] PROGMEM = "data written to vccbrd...";
char str_unkown[] PROGMEM = "dunno what to do!";
char str_pulse[] PROGMEM = "pulse: ";
char str_verbose[] PROGMEM = "verbose: ";
char str_pins[] PROGMEM = "vccbrd_d[1-4]: ";
char str_left[] PROGMEM = "<<=1 on every byte of data results in: 0x";
char str_right[] PROGMEM = ">>=1 on every byte of data results in: 0x";
char str_up[] PROGMEM = "+=1 on every byte of data results in: 0x";
char str_down[] PROGMEM = "-=1 on every byte of data results in: 0x";
char str_hex[] PROGMEM = "0x";
char str_sep[] PROGMEM = ", ";
char str_nl[] PROGMEM = "\r\n";


void send_data(uint8_t data[4]) {
uint8_t i;
uint8_t cmp;
uint8_t out;

cmp=0x80;
while (cmp) {
if (data[0]&cmp) {
VCCBRD_D1_PORT |= VCCBRD_D1_BIT;
out|=VCCBRD_D1_BIT;
} else {
VCCBRD_D1_PORT &= ~(VCCBRD_D1_BIT);
out&=~(VCCBRD_D1_BIT);
}

if (data[1]&cmp) {
VCCBRD_D2_PORT |= VCCBRD_D2_BIT;
out|=VCCBRD_D2_BIT;
} else {
VCCBRD_D2_PORT &= ~(VCCBRD_D2_BIT);
out&=~(VCCBRD_D2_BIT);
}

if (data[2]&cmp) {
VCCBRD_D3_PORT |= VCCBRD_D3_BIT;
out|=VCCBRD_D3_BIT;
} else {
VCCBRD_D3_PORT &= ~(VCCBRD_D3_BIT);
out&=~(VCCBRD_D3_BIT);
}

if (data[3]&cmp) {
VCCBRD_D4_PORT |= VCCBRD_D4_BIT;
out|=VCCBRD_D4_BIT;
} else {
VCCBRD_D4_PORT &= ~(VCCBRD_D4_BIT);
out&=~(VCCBRD_D4_BIT);
}

if (verbose) {
usart_write_hex(out);
usart_progprint(str_sep);
}

VCCBRD_RSCK_PORT |= VCCBRD_RSCK_BIT;
_delay_us(5);
VCCBRD_RSCK_PORT &= ~(VCCBRD_RSCK_BIT);
cmp>>=1;
}

if (verbose) {
usart_progprint(str_nl);
}
VCCBRD_RSCK_PORT |= VCCBRD_RSCK_BIT;
_delay_us(5);
VCCBRD_RSCK_PORT &= ~(VCCBRD_RSCK_BIT);
}


int main() {
uint8_t in;
uint8_t data[4];
uint8_t off_data[4];
uint8_t i;
uint8_t pulse;
uint8_t print_action;

VCCBRD_RSCK_DDR |= VCCBRD_RSCK_BIT;
VCCBRD_D1_DDR |= VCCBRD_D1_BIT;
VCCBRD_D2_DDR |= VCCBRD_D2_BIT;
VCCBRD_D3_DDR |= VCCBRD_D3_BIT;
VCCBRD_D4_DDR |= VCCBRD_D4_BIT;

for (i=0;i<4;i++) {
data[i]=0x00;
off_data[i]=0x00;
}

print_action=1;
pulse=1;

usart_init(9600);
while (1) {
if (print_action) {
usart_progprint(str_action);
print_action=0;
}
in=usart_read_noblock();
if (in!=0) {
usart_write(in);
usart_progprint(str_nl);
}
if (in=='h') {
usart_progprint(str_help);
} else if (in=='k') {
VCCBRD_D1_PORT&=~(VCCBRD_D1_BIT);
VCCBRD_RSCK_PORT |= VCCBRD_RSCK_BIT;
_delay_us(5);
VCCBRD_RSCK_PORT &= ~(VCCBRD_RSCK_BIT);
} else if (in=='K') {
VCCBRD_D1_PORT|=VCCBRD_D1_BIT;
VCCBRD_RSCK_PORT |= VCCBRD_RSCK_BIT;
_delay_us(5);
VCCBRD_RSCK_PORT &= ~(VCCBRD_RSCK_BIT);
} else if (in=='v') {
verbose=verbose?0:1;
usart_progprint(str_verbose);
usart_write_hex(verbose);
usart_progprint(str_nl);
} else if (in=='a') {
VCCBRD_D1_PORT |= VCCBRD_D1_BIT;
} else if (in=='b') {
VCCBRD_D2_PORT |= VCCBRD_D2_BIT;
} else if (in=='c') {
VCCBRD_D3_PORT |= VCCBRD_D3_BIT;
} else if (in=='d') {
VCCBRD_D4_PORT |= VCCBRD_D4_BIT;
} else if (in=='e') {
VCCBRD_RSCK_PORT |= VCCBRD_RSCK_BIT;
} else if (in=='A') {
VCCBRD_D1_PORT &= ~(VCCBRD_D1_BIT);
} else if (in=='B') {
VCCBRD_D2_PORT &= ~(VCCBRD_D2_BIT);
} else if (in=='C') {
VCCBRD_D3_PORT &= ~(VCCBRD_D3_BIT);
} else if (in=='D') {
VCCBRD_D4_PORT &= ~(VCCBRD_D4_BIT);
} else if (in=='E') {
VCCBRD_RSCK_PORT &= ~(VCCBRD_RSCK_BIT);
} else if (in=='i') {
usart_progprint(str_data);
usart_progprint(str_hex);
for (i=0;i<4;i++) {
usart_write_hex(data[i]);
}
usart_progprint(str_nl);
usart_progprint(str_pulse);
usart_write_hex(pulse);
usart_progprint(str_nl);
usart_progprint(str_verbose);
usart_write_hex(verbose);
usart_progprint(str_nl);
} else if (in=='s') {
usart_progprint(str_input);
for (i=0;i<4;i++) {
data[i]=usart_read_hex();
}
usart_progprint(str_nl);
send_data(data);
usart_progprint(str_data);
usart_progprint(str_hex);
for (i=0;i<4;i++) {
usart_write_hex(data[i]);
}
usart_progprint(str_nl);
usart_progprint(str_flush);
usart_progprint(str_nl);
} else if (in=='r') {
usart_progprint(str_data);
usart_progprint(str_hex);
for (i=0;i<4;i++) {
usart_write_hex(data[i]);
}
usart_progprint(str_nl);
send_data(data);
usart_progprint(str_flush);
usart_progprint(str_nl);
} else if (in==0x1B) { /* arrow keys: 0x1b 0x5b [0x41-0x44] */
_delay_ms(5);
if (usart_read_noblock()==0x5B) {
_delay_ms(5);
in=usart_read_noblock();
if (in==0x44) {
usart_progprint(str_left);
for (i=0;i<4;i++) {
data[i]<<=1;
usart_write_hex(data[i]);
}
usart_progprint(str_nl);
}
if (in==0x43) {
usart_progprint(str_right);
for (i=0;i<4;i++) {
data[i]>>=1;
usart_write_hex(data[i]);
}
usart_progprint(str_nl);
}
}if (in==0x41) {
usart_progprint(str_up);
for (i=0;i<4;i++) {
data[i]+=1;
usart_write_hex(data[i]);
}
usart_progprint(str_nl);
}
if (in==0x42) {
usart_progprint(str_down);
for (i=0;i<4;i++) {
data[i]-=1;
usart_write_hex(data[i]);
}
usart_progprint(str_nl);
}
} else if (in=='p') {
pulse=pulse?0:1;
usart_progprint(str_pulse);
usart_write_hex(pulse);
usart_progprint(str_nl);
} else if (in!=0) {
usart_progprint(str_unkown);
usart_progprint(str_nl);
}

if (in!=0) {
print_action=1;
}

if (pulse) {
send_data(off_data);
_delay_us(27);
send_data(data);
_delay_us(3);
}
}
}


Quellcode in Aktion:


action (help=h): h
h: help
p: tootle pulsing (only test leds with pulsing turned on!)
s: set data which will be sent to the board
i: print data, pulse state and other stuff
r: resend data (in pulsing mode data is resent automatically)
v: verbose messages (clutters display with pulsing on!)
k: send one low bit on D1 (triggers RSCK)
K: send one high bit on D1 (triggers RSCK)
a,b,c,d,e: set D1,D2,D3,D4,RSCK to high
A,B,C,D,E: set D1,D2,D3,D4,RSCK to low
use arrow keys to manipulate data:
LEFT: <<=1 on all bytes of data
RIGHT: >>=1 on all bytes of data
UP: +=1 on all bytes of data
DOWN: -=1 on all bytes of data
pulsing is turned on by default
data is initialized to zero
action (help=h): i
data: 0x00000000
pulse: 01
verbose: 00
action (help=h): p
pulse: 00
action (help=h): v
verbose: 01
action (help=h): r
data: 0x00000000
00, 00, 00, 00, 00, 00, 00, 00,
data written to vccbrd...
action (help=h): a // das hier funktioniert: 1 high bit auf U1
action (help=h): e
action (help=h): E
action (help=h): e
action (help=h): E
action (help=h): s // auch hier wird erfolgreich 1 high bit zu U1 gesendet
pls write 32 bit hex val: 01000000
00, 00, 00, 00, 00, 00, 00, 01,
data: 0x01000000
data written to vccbrd...
action (help=h): s // man kann auch beliebige bitfolgen setzen
pls write 32 bit hex val: 99000000
01, 00, 00, 01, 01, 00, 00, 01,
data: 0x99000000
data written to vccbrd...
action (help=h): s // geht ohne probleme
pls write 32 bit hex val: 00ff00ff
0A, 0A, 0A, 0A, 0A, 0A, 0A, 0A,
data: 0x00FF00FF
data written to vccbrd...
action (help=h): s // geht ohne probleme
pls write 32 bit hex val: ffff00ff
0B, 0B, 0B, 0B, 0B, 0B, 0B, 0B,
data: 0xFFFF00FF
data written to vccbrd...
action (help=h): s // geht ohne probleme
pls write 32 bit hex val: 00ffffff
0E, 0E, 0E, 0E, 0E, 0E, 0E, 0E,
data: 0x00FFFFFF
data written to vccbrd...
action (help=h): s // geht gar nicht! (alles 0x00)
pls write 32 bit hex val: ffffffff
0F, 0F, 0F, 0F, 0F, 0F, 0F, 0F,
data: 0xFFFFFFFF
data written to vccbrd...
action (help=h): s // funktioniert halb: U1:0x88, U2:0xff, U3:0xff, U4:0x00
pls write 32 bit hex val: ffffff00
07, 07, 07, 07, 07, 07, 07, 07,
data: 0xFFFFFF00
data written to vccbrd...
action (help=h): s // aufraeumen...
pls write 32 bit hex val: 00000000
00, 00, 00, 00, 00, 00, 00, 00,
data: 0x00000000
data written to vccbrd...
action (help=h): a // U1 bis U3 erhalten 3 high bits, von denen 2
action (help=h): b // ausgegeben werden sollten
action (help=h): c // Messungen ergeben leider folgendes:
action (help=h): e // U1: 0x00, U2: 0x03, U3: 0x03, U4: 0x00
action (help=h): E // das Problem: U1 sollte 0x03 sein
action (help=h): e // wenn ich am U1 Ser Pin messe, werden konstant 5v angezeigt
action (help=h): E
action (help=h): e
action (help=h): E
action (help=h): r // ordnung schaffen
data: 0x00000000
00, 00, 00, 00, 00, 00, 00, 00,
data written to vccbrd...
action (help=h): a // hier soll an alle chips ein high signal uebertragen werden
action (help=h): b // alle Ser Pins sind durchgehend auf 5v und die anderen Pins
action (help=h): c // ebenfalls sind richtig beschaltet (wurde nachgemessen)
action (help=h): d // jedoch sind U1 bis U4 alle 0x00
action (help=h): e // sobald alle 4 pins gleichzeitig aktiviert werden,
action (help=h): E // wird eine 0 ins register gelesen
action (help=h): e // dies ist scheinbar unabhaengig von den chips,
action (help=h): E // da ich mehrere getestet habe
action (help=h): e // der AVR steckt auf einem Arduino board
action (help=h): E

Ofenrohr
27.04.2010, 21:15
Das Problem lag bei Störsignalen, die ich jetzt durch Abblockkondensatoren beseitigt habe. Nächstes Mal bin ich schlauer :)