hi, benutze dem ATMega32 mit internem Takt ( 8 Mhz ) jetzt möchte ich per serieller Schnittstelle Daten an den PC senden. Ist der interne Takt dazu gut genug ? .... ich hab ein Program das für den ATMega128 funktioniert, wenn ich das änder für den ATMega32 funktionierts nicht :-( ... hier mal nen ausschnitt ... #include "printf.h" 12 13 //Installation der Seriellen Schnittstelle 14 void IOInit (void) 15 { 16 // Enable TXEN in Register UCR (TX-Data Enable) 17 UCSRB=(1 << TXEN); 18 // set baudrate divisor 19 UBRRL=(CPU_CLOCK / (BAUD_RATE * 16L) - 1); 20 } 21 22 // 23 // this function is used inside the standard printf function and 24 // has to be implemented to get access to the serial port via printf 25 // 26 int uart_putchar (char c) 27 { 28 if (c == '\n') uart_putchar('\r'); 29 // wait until character is transmitted 30 loop_until_bit_is_set(UCSRA, UDRE); 31 UDR = c; 32 return 0; 33 } 34 I A main.h (c) Row 1 Col 1 1:16 Ctrl-K H for help 1 #ifndef _MAIN_H 2 #define _MAIN_H 3 4 #include <avr/io.h> 5 6 #define BUTTON_PORT PORTC 7 #define BUTTON_DDR DDRC 8 #define BUTTON_PIN PINC 9 #define BATT_LOW 4 10 #define BUTTON_0 5 11 #define BUTTON_1 6 12 #define BUTTON_2 7 13 14 #define LED_PORT PORTC 15 #define LED_DIR DDRC 16 #define LED_GREEN 0 17 #define LED_RED 1 18 19 #define CPU_CLOCK 7372800 20 21 #define CPU_MICROSEC(a) ((a)*CPU_CLOCK/7000000) 22 #define CPU_MILLISEC(a) ((a)*CPU_CLOCK/7000) 23 #define CPU_SEC(a) ((a)*CPU_CLOCK/7) 24 25 #define nop() _asm__ __volatile_ ("nop" ::) 26 27 /* nop/1, subi/1, sbc/1, sbc/1, sbc/1, brcc/2 -> 7 clocks */ 28 static inline void cpu_delay(unsigned long int delay) { 29 while ( delay-- != 0) nop(); 30 } 31 32 #endif 33 bin für Tipps und Hinweise dankbar ... chris
nein, aber wenn ich mit uisp -dprog=stk200 -dpart=atmega32 --rd_fuses mache dann steht da: Fuse Low Byte = 0xe3 Fuse High Byte = 0xd9 Fuse Extended Byte = 0xff Calibration Byte = 0xb4 -- Read Only Lock Bits = 0xff BLB12 -> 1 BLB11 -> 1 BLB02 -> 1 BLB01 -> 1 LB2 -> 1 LB1 -> 1 also das mein calibrationbyte read only ist ! also muss ich das calibration byte auf 0x003 setzen für 8 Mhz ? chris PS : wenn ich das richtig verstanden habe wird später der wert von meinem Calib byte ind OSCAL gelesen ... da gibts ne tabelle wo drinn steht 7F ist 75-150 % meines taktes ?is dis schwankung net bsichen groß ?
hier ist ein code zum senden und empfangen. zum empfangen die chars muss du noch selber sondieren, jenachdem was du damit machen tust. baudrate kannste noch selber ändern. ist für winavr-c. mfg pebisoft #define READ 1 #define WRITE 2 #define USART_BAUD_RATE 19200 #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16l)-1) volatile char buchstabe; SIGNAL(SIG_UART_RECV) { buchstabe=UDR; } void usart_init(int Enable, int Interupts) { if (Enable & READ) UCSRB = (1<<RXEN); if (Enable & WRITE) UCSRB |= (1<<TXEN); if (Interupts & READ) UCSRB |= (1<<RXCIE); if (Interupts & WRITE) UCSRB |= (1<<TXCIE); UBRRL = (unsigned char) USART_BAUD_SELECT; } void usart_writeChar(unsigned char c) { while (!(UCSRA & (1<<UDRE))) {} UDR = c; while(!(UCSRA & (1<<TXC))) {} } void usart_writeString(unsigned char *string) { while (!(UCSRA & (1<<UDRE))) {} while ( *string) usart_writeChar(*string++); } das kommt in die main() : sei(); usart_init( (READ + WRITE) , READ); usart_writeString(string); usart_writeString("\n\r");
Hallo Chris, ich vermute, dein ISP zeigt das Cal.Byte für 1 MHz an. Es gibt aber noch 3 weitere (für 2,4,8 MHz). Dies Bytes werden vom Hersteller (neben den Signatur Bytes) in einen eigenen Adreßraum (read-only) geschrieben. Bei einem Reset wird automatisch das 1MHz Cal.Byte gelesen und nach OSCCAL geschrieben. Dann ist bei 25 °C und 5,0V (!!!) +/- 3% garantiert, was gerade so für die ser. Schnittstelle reichten würde. Du mußt also gleich am Anfang Deines Programms OSCCAL mit dem Wert des 8 MHz Cal.Byte überschreiben. Sicherer bist Du, wenn Du den korrekten Wert selber ermittelst. Der ist sicher in der Nähe des angezeigten Wertes (0xb4). Vielleicht +/- 5,6,7,8 oder so. Dazu gibt es App. Notes oder Du überprüfst die Baudrate mit eine Scope und drehst solange an OSCCAL bis die Baudrate stimmt. hth Gunter
sorry für die blöde Frage, geht das so ? unsigned int &i =0x03; // eine Variable für eine Adresse anlegen Aresse 0x03 ind die Variable reinschreiben OSCCAL= *i>>8; // mit *auf den Inhalt der Adresse zugreifen den Inhalt des High Byte in OSCCAL schreiben chris
Hi, die Cal. und Sig. Byte können nur von einem Programmer gelesen werden (nicht vom Controller zur Laufzeit). Gunter
hallo Gunter, ich hab meinem Controller mit einem stk200 Dongle (isp) programmiert und per uisp -dpart=atmega32 -dprog=stk200 rom.hex mein Programm übertragen. bei uisp -h finde ich nichts von Calibration Byte lesen. Die frage ist kann ich das Calibration Byte überhaupt mit meinem Aufban auslesen ? ... benutze Linux ? .. danke chris
Hi Chris, da kann ich Dir leider nicht helfen - weder mit Linux noch mit C noch mit Deinem ISP. Ich hatte mir damals eine kleine Testschaltung gebaut, in einer Schleife immer 0x55 oder 0xAA gesendet, die Baudrate mit dem Scope ausgemessen und dann das Cal.Byte leicht geändert. Damit kommt man dann auf 1% Genauigkeit. Die ser. SS verlangt 3%, sodaß man dann noch Reserve für Temperaturdrift hat. Gunter
In dem Sourcecode des ersten Postings ist CPU_CLOCK als 7372800 definiert. Definierst Du das noch irgendwo um? Sonst stimmt schon die Berechnung von UBBRL nicht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.