ich kann dem Listing zwar nicht ganz entnehmen was da vorsich gehen soll, aber wenn an Port B1 die ErrorLed sein soll so leuchte diese ständig nach dem flashen des µCs
Dann mal mehr ernten als essen
Hier mal einen zusammengeschraubten Code, basierend auf den von mir verlinkten Fleury Libs, diese müssen sich im selben Verzeichnis, wie die ds1307.c befinden.
Bei den AVR-Studios muss die CPU-Frequenz über die Projekteinstellungen definiert werden, sonst wird sie nicht übernommen, so zumindest meine Erfahrung. Das dürfte am automatisch erstellten Makefile liegen.
Bei AVR-Studio 4 unter Project --> Configuration Options --> General. Bei anderen AS-Versionen muss man ggf. ein Symbol anlegen, das ist dort Projekteinstellungen --> Toolchain --> Compiler --> Symbols, dort ein neues Symbol mit F_CPU=16000000UL erzeugen.
Die Hex-Datei zum direkten Flashen hängt auch mit an, Hardware hab' ich hier keine, die Hex ist aber dahingehend überprüft, dass die CPU-Frequenz stimmt und die Funktionen (prinzipiell) das machen, was sie sollen.
Code:#include <avr/io.h> #include <util/delay.h> #include "twi_lib.h" #define led_port PORTB #define led_port_dir DDRB #define alive_led (1<<PB0) #define err_led (1<<PB1) #define alive_led_off led_port |= alive_led #define alive_led_tgl led_port ^= alive_led #define err_led_on led_port &= ~err_led #define err_led_off led_port |= err_led #define rtc_base_addr 0xD0 #define sec_regaddr 0 int main (void) { unsigned char sec; unsigned char last_sec = 0; led_port_dir = (alive_led | err_led); alive_led_off; err_led_off; i2c_init(); while(1) { err_led_off; if (!i2c_start(rtc_base_addr | I2C_WRITE)) err_led_on; if (!i2c_write(sec_regaddr)) err_led_on; if (!i2c_rep_start(rtc_base_addr | I2C_READ)) err_led_on; sec = i2c_readAck(); i2c_stop(); if (sec != last_sec) { last_sec = sec; alive_led_tgl; } _delay_ms(100); } return 0; }
ich kann dem Listing zwar nicht ganz entnehmen was da vorsich gehen soll, aber wenn an Port B1 die ErrorLed sein soll so leuchte diese ständig nach dem flashen des µCs
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Nun, die Error-Led soll nicht leuchten. Was verwendest Du als Pullup für SCL & SDA?
- - - Aktualisiert - - -
Kann es sei, dass Du keine Pullups dran hast? Dann arbeitet der Bascom-Code, weil er interne Pullups verwendet.
Dann verwende mal das Hex hier im Anhang.
Oder ist das noch die RTC aus diesem Thread?
Hallo Magic !
Ja ja Computer bereiten uns gerne die Sorgen, die man ohne Conmputer nicht hätte. Also das Beisspiel von Dir funktioniert, Schuld war das AVR Studio. Nun frage nicht warum und weshalb. habe nochmals neu installiert , die Reg vom PC ausgefegt...nun klappt es. Du hattest schon den richtigen Riecher, ins Sachen AVR StudioNich bei allen Proj. die ich neu wieder aufrief war die Frequenz noch eingestellt, wie zu Begin...Na dann konnte es nicht klappen. Komisch das die Usartprogramme und sontige, wo es auch auf Timing ankommt bislang ohne Probs liefen...Bei den AVR-Studios muss die CPU-Frequenz über die Projekteinstellungen definiert werden, sonst wird sie nicht übernommen, so zumindest meine Erfahrung. Das dürfte am automatisch erstellten Makefile liegen.
Bei AVR-Studio 4 unter Project --> Configuration Options --> General. Bei anderen AS-Versionen muss man ggf. ein Symbol anlegen, das ist dort Projekteinstellungen --> Toolchain --> Compiler --> Symbols, dort ein neues Symbol mit F_CPU=16000000UL erzeugen.
Ich hatte heute, schon fast mit Verzweiflung, ein funktionierendes Bascom Prog zusammen gewürfelt, na nun wird es mit GCC auch klappen und AVR Studio.
Ich danke Dir für die viele Hilfe wobei ich auch ne Menge gelernt habe und ich hoffendlich nun mein Porgramm in GCC fertigstellen kann.
Gerhard
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Für Nach-Leser wäre es noch interessant zu wissen, welches genau, sonst stochern die dann auch wieder nur im Nebel.
Als Arzt tätest Du Dich schwer, einmal den Patienten neu formatierenSchuld war das AVR Studio. Nun frage nicht warum und weshalb. habe nochmals neu installiert , die Reg vom PC ausgefegt...nun klappt es.
Es kommt immer darauf an, wer das Define F_CPU verwendet. Wenn das Baudratenregister direkt gesetzt wird, ohne verwendung des Defines, dann hat das keinen Einfluss. Für alles, was delay_... verwendet, wird es aber benötigt. Die entsprechenden Delay-Routinen geben dann beim Compilieren eine Warnung aus und setzen F_CPU auf einen Standardwert, mit entsprechenden Folgen.Komisch das die Usartprogramme und sontige, wo es auch auf Timing ankommt bislang ohne Probs liefen...
Bitte.Ich danke Dir für die viele Hilfe wobei ich auch ne Menge gelernt habe und ich hoffendlich nun mein Porgramm in GCC fertigstellen kann.
Hallo Magic !
Hier nun das funktionierendes Beispiel von Dir..ein wenig umgeschrieben wegen der LED Anzeige:
Nun muss ich nun noch hinbekommen um in Minuten und Stunden auszuwerten, dann passt das schon.Code:#define F_CPU 16000000UL #include<avr/io.h> #include<util/delay.h> #define rtc_adr_w 0xD0 #define rtc_adr_r rtc_adr_w | 0x01 #define P1 0 #define P2 1 void rtc_init(void) { TWSR=0x00; TWBR=0x48; // I2C Clock 50kHz@16MHz } void rtc_start(void) { TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); while(!(TWCR & (1<<TWINT))); } unsigned char rtc_read(void) { unsigned char data; TWCR=(1<<TWINT)|(1<<TWEN); while(!(TWCR & (1<<TWINT))); data =(TWDR); return data; } void rtc_write(unsigned char data) { TWDR=data; // sending address TWCR=(1<<TWINT) | (1<<TWEN); while(!(TWCR & (1<<TWINT)));} void rtc_stop() { TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO); while(TWCR & (1 <<TWSTO)); } int main(void) { unsigned char sec; //unsigned char last_sec = 0; DDRB=0xFF; PORTB=0xFF; rtc_init(); while(1) { rtc_start(); rtc_write(rtc_adr_w); // Sende Schreibadresse rtc_write(0x00); // Sekunden Register Adresse rtc_start(); // Repeated Start rtc_write(rtc_adr_r); // Sende Leseadresse sec = rtc_read(); // Wert Register 0 lesen = RTC Sekunde rtc_stop(); if (sec >= 30) { PORTB = (1<< P2)|~(1<< P1); //PORTB = 0xFE; // 30...59sec LED ein } else PORTB = (1<< P1)|~(1<< P2); //PORTB = 0xFD ; // 0..29sec LED aus _delay_ms(1000); } }
Danke Gerhard
PS. Nix formatieren am PC , die Registrierung reinigen, so was wie ne Hirnwäsche beim Menschen...hat gereicht..![]()
Geändert von oderlachs (18.06.2013 um 10:00 Uhr)
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Nun funktioniert das ganze gut im Test, für alle die es interessiert, möchte ich es nicht vorenthalten, was ich daraus gestrickt habe. Ich denke mal die Kommentare erklären die Funktionen usw. Hier nun der Source zur Ansicht und allgemeinen Verfügung:
Code:/* ========================================================================== */ /* */ /* ATM16_Uhr.c */ /* (c) 2013 Gerhard Hinze */ /* */ /* Description: Schaltuhr mit Atmega16 mit 2 Schaltausgängen und DS1307 RTC */ /* Zeitausgabe über ser. Port und LCD später geplant */ /* ========================================================================== */ #define F_CPU 16000000UL #include<avr/io.h> #include<util/delay.h> #define rtc_adr_w 0xD0 // Adressen DS1307 schreiben #define rtc_adr_r rtc_adr_w | 0x01 // DS1307 lesen #define P1 0 // Schaltausgang 1 = PortB.0 #define P2 1 // Schaltausgang 2 = PortB.1 /* ========================================================================== */ /* */ /* I2C initialisieren */ /* */ /* ========================================================================== */ void rtc_init(void) { // Werte vorher berechnen TWSR=0x00; TWBR=0x48; // I2C Clock 50kHz@16MHz } /* ========================================================================== */ /* */ /* I2C starten */ /* */ /* ========================================================================== */ void rtc_start(void) { TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); while(!(TWCR & (1<<TWINT))); } /* ========================================================================== */ /* */ /* ein Byte über I2C vom RTC lesen */ /* */ /* ========================================================================== */ unsigned char rtc_read(void) { unsigned char data; TWCR=(1<<TWINT)|(1<<TWEN); while(!(TWCR & (1<<TWINT))); data =(TWDR); return data; } /* ========================================================================== */ /* */ /* ein Byte über I2C zum RTC schreiben */ /* */ /* ========================================================================== */ void rtc_write(unsigned char data) { TWDR=data; TWCR=(1<<TWINT) | (1<<TWEN); while(!(TWCR & (1<<TWINT)));} /* ========================================================================== */ /* */ /* I2C Stoppen */ /* */ /* ========================================================================== */ void rtc_stop() { TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO); while(TWCR & (1 <<TWSTO)); } /* ========================================================================== */ /* */ /* Dezimal zu BCD codieren */ /* */ /* ========================================================================== */ char DECtoBCD(char dec) { return ((dec/10 * 16) + (dec % 10)); } /* ========================================================================== */ /* */ /* BCD zu Dezimal decodieren */ /* */ /* ========================================================================== */ char BCDtoDEC(char bcd) { return ((bcd/16 * 10) + (bcd % 16)); } /* ========================================================================== */ /* */ /* USART initialisieren */ /* */ /* ========================================================================== */ void usart_init(void) { UCSRB = (1<<TXEN)|(1<<RXEN)|(1<<RXCIE); UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8N1 UBRRL = 103; //9600 Baud bei 16MHz } /* ========================================================================== */ /* */ /* ein Byte über Serialport senden */ /* */ /* ========================================================================== */ void usart_txchar(uint8_t byte) { while(!(UCSRA & (1 << UDRE))); UDR=byte; } /* ========================================================================== */ /* */ /* einen Textstring über Serialport senden */ /* */ /* ========================================================================== */ void usart_txstr(char *str) { while(*str) { usart_txchar(*str); str++; } usart_txchar(10); usart_txchar(13); } /* ========================================================================== */ /* */ /* Hauptprogramm */ /* */ /* ========================================================================== */ int main(void) { unsigned char sec; // zum Test wird nur sec benutzt //unsigned char min; //unsigned char hour; //unsigned char day; //unsigned char month; //unsigned char year; //unsigned char weekday; DDRB=0xFF; PORTB=0xFF; usart_init(); rtc_init(); while(1) { rtc_start(); rtc_write(rtc_adr_w); // Sende Schreibadresse rtc_write(0x00); // Sekunden Register Adresse rtc_start(); // Repeated Start rtc_write(rtc_adr_r); // Sende Leseadresse sec = rtc_read(); // Wert Register 0 lesen = RTC Sekunde rtc_stop(); sec = BCDtoDEC(sec); // Nicht vergessen umzuwandeln !!!! if ((sec >= 30)&&(sec <=59)) { //PORTB = (1<< P2)|~(1<< P1); PORTB = 0xFE; // 30...59sec LED ein } else //PORTB = (1<< P1)|~(1<< P2); PORTB = 0xFD ; // 0..29sec LED aus _delay_ms(100); } } /* ========================================================================== */ /* */ /* Ende Programm */ /* */ /* ========================================================================== */
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Lesezeichen