74HC595 bei ISP Programmierung deaktivieren

Gast #4290083
Lesenswert?

Hallo,

ich möchte mit einem HC595 ein 4Bit LCD ansteuern (LCD16x2, HD44780).
Nun habe ich das Problem, dass bei dem überschreiben des Programms das 
Display wie verrückt Daten bekommt. Teilweise wird es dabei so stark 
gestört, dass ich nach dem Upload einen Reset am AVR machen muss, da 
ansonsten das Display keine erkennbaren Zeichen liefert.


1
#define SERPA_DDR       DDRA
2
#define SERPA_PORT      PORTA
3

4
#define SERPA_SCK       4
5
#define SERPA_MISO      5
6
#define SERPA_MOSI      6
7
#define SERPA_SS        7
8

9
/* Intern */
10
void serpa_shiftout(void)
11
{
12
  SERPA_PORT &= ~(1<<SERPA_SS);
13
  SPDR = serpa_data;
14
  while(!(SPSR & 1<<SPIF));
15
  SERPA_PORT |= 1<<SERPA_SS;
16
}
17

18
/* Extern */
19
void serpa_init(void)
20
{
21
  SERPA_DDR |= (1<<SERPA_SS) | (1<<SERPA_MOSI) | (1<<SERPA_SCK);
22
  SPCR = (1<<SPE) | (1<<MSTR);
23
  //SPSR = (1<<SPI2X);
24
}

Das Schieberegister ist über SCK, MOSI und SS mit dem AVR verbunden. 
OE/G ist auf GND. Kann man das ganze nun über die Schaltung selber so 
einstellen, dass solange die ISP Programmierung stattfindet, der OE/G 
HIGH ist oder aber das HC595 sich dauerhaft im Reset befindet? Möchte 
keinen zusätzlichen Pin verwenden.
Gast #4290110
Lesenswert?

>Teilweise wird es dabei so stark
>gestört, dass ich nach dem Upload einen Reset am AVR machen muss

Der ISP macht doch schon einen Reset.
Ein gutes LCDInit() sollte das auch ohne Tricks hinkriegen.
Deine Funktion ist ja leider nicht zu sehen.
#4290113
Lesenswert?

Vogel schrieb:

> Das Schieberegister ist über SCK, MOSI und SS mit dem AVR verbunden.
> OE/G ist auf GND. Kann man das ganze nun über die Schaltung selber so
> einstellen, dass solange die ISP Programmierung stattfindet, der OE/G
> HIGH ist oder aber das HC595 sich dauerhaft im Reset befindet? Möchte
> keinen zusätzlichen Pin verwenden.

!OE über Inverter an !RESET hängen. Im Normalbetrieb ist !Reset High, 
und damit !OE low, beim ISP-Vorgang ist !Reset Low und damit !OE high.

fchk
Gast #4290114
Lesenswert?

Habe mich bei der Lib an der aus dem Wiki hier gehalten
1
void lcd_init(void)
2
{
3
  // SPI initialisieren
4
  //lcd_bus_init();
5
  serpa_init();
6
  
7
  // warten auf die Bereitschaft des LCD
8
  _delay_ms( LCD_BOOTUP_MS );
9
  
10
  // Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung
11
  lcd_out( LCD_SOFT_RESET );
12
  _delay_ms( LCD_SOFT_RESET_MS1 );
13
  
14
  lcd_enable();
15
  _delay_ms( LCD_SOFT_RESET_MS2 );
16
  
17
  lcd_enable();
18
  _delay_ms( LCD_SOFT_RESET_MS3 );
19
  
20
  // 4-bit Modus aktivieren
21
  lcd_out( LCD_SET_FUNCTION | LCD_FUNCTION_4BIT );
22
  _delay_ms( LCD_SET_4BITMODE_MS );
23
  
24
  // 4-bit Modus / 2 Zeilen / 5x7
25
  lcd_command( LCD_SET_FUNCTION |
26
  LCD_FUNCTION_4BIT |
27
  LCD_FUNCTION_2LINE |
28
  LCD_FUNCTION_5X7 );
29
  
30
  // Display ein / Cursor aus / Blinken aus
31
  lcd_command( LCD_SET_DISPLAY |
32
  LCD_DISPLAY_ON |
33
  LCD_CURSOR_OFF |
34
  LCD_BLINKING_OFF);
35
  
36
  // Cursor inkrement / kein Scrollen
37
  lcd_command( LCD_SET_ENTRY |
38
  LCD_ENTRY_INCREASE |
39
  LCD_ENTRY_NOSHIFT );
40
  
41
  lcd_clear();
42
}
43

44
void lcd_enable(void)
45
{
46
  lcd_port |= (1<<LCD_EN);
47
  lcd_send(lcd_port);
48
  //lcd_setBit(LCD_EN);
49
  _delay_us(LCD_ENABLE_US);
50
  lcd_port &= ~(1<<LCD_EN);
51
  lcd_send(lcd_port);
52
  //lcd_clearBit(LCD_EN);
53
}
54

55
void lcd_out(uint8_t data)
56
{
57
  if (data & 1<<4) lcd_port |= (1<<LCD_DB4); else lcd_port &= ~(1<<LCD_DB4);
58
  if (data & 1<<5) lcd_port |= (1<<LCD_DB5); else lcd_port &= ~(1<<LCD_DB5);
59
  if (data & 1<<6) lcd_port |= (1<<LCD_DB6); else lcd_port &= ~(1<<LCD_DB6);
60
  if (data & 1<<7) lcd_port |= (1<<LCD_DB7); else lcd_port &= ~(1<<LCD_DB7);
61
  lcd_send(lcd_port);
62

63
  lcd_enable();
64
}
65

66
void lcd_command(uint8_t cmd)
67
{
68
  lcd_port &= ~(1<<LCD_RS);
69
  lcd_send(lcd_port);
70
  //lcd_clearBit(LCD_RS);
71
  lcd_out(cmd);
72
  lcd_out(cmd  << 4);
73
  _delay_us(LCD_COMMAND_US);
74
}
75

76

77
void lcd_putc(char c)
78
{
79
  lcd_port |= (1<<LCD_RS);
80
  lcd_send(lcd_port);
81
  //   lcd_setBit(LCD_RS);
82
  lcd_out(c);
83
  lcd_out(c<<4);
84
  
85
  _delay_us(LCD_WRITEDATA_US);
86
}

Das sind alle Funktionen, die auf den SPI Bus zugreifen. Der Rest ist 
unberührt
Gast #4290118
Lesenswert?

Das gehört noch dazu
1
#define lcd_send(data)  serpa_valByte(data)

1
uint8_t serpa_data; // Inhalt, was ueber SPI geschickt wird.
2
void serpa_valByte(uint8_t data)
3
{
4
  serpa_data = data;
5
  serpa_shiftout();
6
}
Gast #4290123
Lesenswert?

Stephan B. schrieb:
> Vogel schrieb:
>> Während des Uploads flackert das Display dennoch.
>
> Bricht deine Spannung ein?
>
> Waehrend des Uploads sollte SS hochohmig werden und der pullup das ganze
> auf 1 ziehen. Das Display also gar keine Daten annehmen...
>
> MfG

Falls das nicht richtig rüber gekommen ist. Es flackern Zeichen auf dem 
Display und das Display flackert selber auch, da am HC595 auch die Led 
für das Display angeschlossen ist. 560Ohm Widerstand zwischen Kathode 
und dem HC595 Pin.
#4290183
Lesenswert?

Das kann eigentlich nicht sein.
Denn ein 595 reagiert nur bei steigender Flanke am RCK Pin.
Da während des Programmierens per ISP der SS Ausgang hochohmig ist, 
sollte sich da an diesem Ausgang eigentlich überhaupt nichts tun.
Entweder hast du dich beim SS-Pullup verlötet oder deine 
Versorgungsspannung bricht laufend ein wenig ein, was der 595 als Flanke 
interpretiert.
Gast #4290197
Lesenswert?

Jedoch kommt immer mal wieder nach dem Upload nur noch ein Kauderwelsch 
aufs Display. Hierbei passt die Struktur auf dem Display bedingt, nur 
halt falsche Zeichen.

Das erste Bild zeigt den Fehler, das zweite ist nach dem ich die 
Spannungsversorgung wieder eingeschaltet hab.

Auf dem Display soll in Zeile 1 stehen:
1
Dauer(ms):..1499
In der zweiten Zeile ist rechtsformatiert ein Zahlenwert. Geht der Wert 
über 999 hinaus, soll ### angezeigt werden. Wie im Bild 2.

Bei Bild 1 wird dort 222 angezeigt. Der andere Text ist auch 
verkrüppelt.

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4

5
#include "lcd/lcd.h"
6

7
volatile uint32_t _millis;
8

9

10
ISR(TIMER0_COMPA_vect)
11
{
12
  _millis++;
13
}
14

15
uint32_t millis(void)
16
{
17
  return _millis;
18
}
19

20

21
int main(void)
22
{
23
  // Timer0 millis()
24
  TCCR0A |= (1<<WGM01);
25
  TCCR0B |= (1<<CS01) | (1<<CS00);
26
  OCR0A = 125-1;
27
  TIMSK0 |= (1<<OCIE0A);
28
  
29
  //_delay_ms(1000);
30
  lcd_init();
31
  sei();
32

33
  lcd_puts_P_xy("Dauer(ms):", 0, 0);
34
  uint32_t lastMillis = millis();
35
  
36
  while (1)
37
  {
38
    static int16_t i = 0;
39
    
40
    static uint32_t last;
41
    if(millis() -last >= 1)
42
    {
43
      last = millis();
44
      
45
      lcd_puti_format_xy(i++, 3, 13, 1);
46
    }
47
    
48
    
49
    if(i >= 1500)
50
    {
51
      i = 0;
52
      lcd_puti_format_xy((millis()-lastMillis), 4, 12, 0);
53
      lastMillis = millis();
54
    }
55
    
56
  }
57
}
Angehängte Dateien:
Gast #4290208
Lesenswert?

Aber warum soll die Stromversorgung nur beim Programmieren einbrechen? 
Programmiere mit dem mkii. Die Spannungsversorgung erfolgt aus einem 
Arduino Uno der an USB angeschlossen ist. Auf dem Uno kein Atmega328P 
drin. Der wurde entfernt. Das Board ist nur für die Serielle 
Schnittstelle eingeschaltet, da ich kein FTDI hier habe.

Ausser dem Display ist nichts angeschlossen.
#4290226
Lesenswert?

Vogel schrieb:
> Hallo Marc. Der Arduino UNO wird nicht verwendet. Der stellt lediglich
> die 5V zur Verfügung. Ich habe bis auf 5V und VCC nichts verbunden.

Dann checke dort nochmal alle Verbindungen auf schlechte Lötstellen 
und/oder Wackelkontakte.
Es ist NICHT normal, dass ein 595 bei hochgezogenem RCK Eingang an 
seinen Ausgängen flackert. Irgendetwas ist da im Busch und an deinem 
letzten Eregbnis siehst du ja, dass es nichts bringt dieses Problem zu 
ignorieren. Es wird dich immer wieder einholen.
Gast #4290368
Lesenswert?

Habe alle Verbindung soweit überprüft, kann da nichts finden.

Programmiere ich den AVR, kommt es ab und zu, zu den Ergebnissen wie 
oben. ~50:50 Chance

Das neue Programm landet aber vollständig auf dem AVR. Ziehe ich die 
Spannungsversorgung und schließe sie wieder an, läuft alles korrekt.



Was mit nun auffällt, ich kann keinen anderen Pin für SPI_SS nutzen. PA0 
und PB0 (mit DDRB) versucht. Da regt sich nichts.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren