Hi,
ich habe zwei Probleme, die unmittelbar zusammenhängen. Dabei bezieht
sich meine Frage hier auf einen Workarround (2).
1. Ich habe eine Platine, die irgendwie beim bespeisen eines DC-Motors
sehr sporalische Probelem mit dem Display hat (TWI-Seriell wandler.)
1.1
Ich hätte behauptet, dass durch die Rückinduktion der µC mittels
BrownOut (1,8V) selbst abschaltet.
Ich war beim Kunden und er könnte mir dieses "Problem" leider bei keinen
der 70 Platinen zeigen (Vorführeffekt) und in meiner Werkstatt habe ich
es auch nie selbst gesehen :(
Er beschreibt es so:
"Display bekommt Sonderzeichen aber Programm im Hintergrund läuft
weiter". (Läuft weiter heißt doch 1.1 ist ausgeschlossen!?!)
1.2
Diese Sonderzeichen, kenne ich nur, wenn der Bus schlecht verlötet ist
und die Initialisierung nicht richtig klappt. Daher habe ich NACHLÖTEN
empfohlen.
2.
Ich würde gerne probieren, ob ich einen Workarround hin bekomme, so das
das Display selbst nach diesem Fehler wieder "sauber" wird.
Daher die eigentliche Frage: "Kann/darf ich den i2c_init() regelmäßig
wiederholen und/oder kann dies andere Seiteneffekte haben?"
Folgendes verwende ich:
1 | /*************************************************************************
|
2 | * Title: I2C master library using hardware TWI interface
|
3 | * Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
|
4 | * File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $
|
5 | * Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
|
6 | * Target: any AVR device with hardware TWI
|
7 | * Usage: API compatible with I2C Software Library i2cmaster.h
|
8 | **************************************************************************/
|
9 |
|
10 | #include <inttypes.h>
|
11 | #include <compat/twi.h>
|
12 | #include "i2cmaster.h"
|
13 |
|
14 | /**
|
15 | * The standard clock (SCL) speed for I2C up to 100KHz. Philips do define faster speeds: Fast mode, which is up to 400KHz
|
16 | */
|
17 | /* I2C clock in Hz */
|
18 | #define SCL_CLOCK 100000L
|
19 |
|
20 |
|
21 | /*************************************************************************
|
22 | Initialization of the I2C bus interface. Need to be called only once
|
23 | *************************************************************************/
|
24 | void i2c_init(void)
|
25 | {
|
26 | #if ((F_CPU/SCL_CLOCK)-16)/2 < 10
|
27 | #error TWBR to small
|
28 | #endif
|
29 |
|
30 | /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
|
31 |
|
32 | TWSR = 0; /* no prescaler */
|
33 | TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */
|
34 |
|
35 |
|
36 | }/* i2c_init */
|
37 | ...
|
Verändert habe ich nur (da ich mit 8Mhz arbeite und sonst die Formel
nicht auf geht):
1 | //#define SCL_CLOCK 400000L
|
2 | #define SCL_CLOCK 100000L
|
Dann selektiere ich noch:
1 | uint8_t I2C_Detect(uint8_t addr)
|
2 | // look for device at specified address; return 1=found, 0=not found
|
3 | {
|
4 | return !i2c_start(addr); // return 0 if OK otherwise 1
|
5 | }
|
6 | uint8_t LCD_I2C_DEVICE = I2C_PCF8574;
|
7 | void i2c_detectPCF8574() {
|
8 | bool i2cFound_PCF8574 = I2C_Detect(I2C_PCF8574);
|
9 | bool i2cFound_PCF8574A = I2C_Detect(I2C_PCF8574A);
|
10 | if (!i2cFound_PCF8574 && i2cFound_PCF8574A) {
|
11 | LCD_I2C_DEVICE = I2C_PCF8574A;
|
12 | }
|
13 | }
|
und mache ein:
1 | void lcd_init(void) {
|
2 |
|
3 | lcd_light(false);
|
4 |
|
5 | _delay_ms(15); //- Wait for more than 15ms after VDD rises to 4.5V
|
6 | lcd_write(CMD_D1 | CMD_D0); //- Set interface to 8-bit
|
7 | _delay_ms(5); //- Wait for more than 4.1ms
|
8 | lcd_write(CMD_D1 | CMD_D0); //- Set interface to 8-bit
|
9 | _delay_ms(1); //- Wait for more than 100us
|
10 | lcd_write(CMD_D1 | CMD_D0); //- Set interface to 8-bit
|
11 | lcd_write(CMD_D1); //- Set interface to 4-bit
|
12 |
|
13 | _delay_ms(50);
|
14 | //- From now on in 4-bit-Mode
|
15 | lcd_command(LCD_LINE_MODE | LCD_5X7);
|
16 | _delay_ms(50);
|
17 | lcd_command(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF);
|
18 | _delay_ms(50);
|
19 | lcd_command(LCD_INCREASE | LCD_DISPLAYSHIFTOFF);
|
20 | _delay_ms(50);
|
21 | lcd_command(LCD_CLEAR);
|
22 | _delay_ms(50);
|
23 | }
|
Reihenfolge:
1 | int main(void) {
|
2 | ioinit();
|
3 | timer2_init();
|
4 | timer1_pwm_init();
|
5 |
|
6 | i2c_init();
|
7 | i2c_detectPCF8574();
|
8 | lcd_init();
|
9 | //ADC_init();
|
10 | /** Interrupts (IRQs) global erlauben */
|
11 | sei();
|
12 | wait_10ms(1);
|
13 |
|
14 | readOldVariables();
|
15 |
|
16 | while (1) {
|
17 | sceduled_menue();
|
18 | if(section == RunRun){
|
19 | runningCoutdown();
|
20 | }
|
21 | sceduled_motor();
|
22 | }
|
23 | }
|
Könnte es einen positiven Effekt haben
- i2c_init();
oder
lcd_init();
mehrfach. (z.B. in einer Schleife von 5Sek aufzurufen?
Wie gesagt, konnte ich den Fehler selbst nie sehen geschweigedenn
reproduzieren, daher wäre ein "probier es doch aus" nicht so hilfreich
;)
Alles anderen bezüglich Grundlagenwissen höre ich gerne und bin
neugierig drauf.
Grüße David