TommyB
Team Bitschubse
Nein, hast du eben nicht.
Steht da nach wie vor drin.If(year And &B0000_0011) = 0 Then
Steht da nach wie vor drin.If(year And &B0000_0011) = 0 Then
Irgendwo hatte dino glaub ich mal hier ein Tut geschrieben wie man somit (fast) jeden verfusten Chip wieder Leben einhauchen kann. Leider finde ich den grade nicht. Aber vom Prinzip nur den Ausgang vom Oszillator an einen der beiden Crystal Pins, das wars.
Sollte dieses Reserved jetzt intern allerdings bewirken dass garkeine Clock mehr akzeptiert wird, Pech. Dann geht es höchstens noch mit High Voltage programmmern.
' Compiler configuration #library "library/Lcd4.interface" ' 4 bit LCD implementation #library "library/Sleep.interface" ' Sleep / Idle implementation #library "library/Wdt.interface" ' Watchdog timer implementation Avr.Device = atmega8 Avr.Clock = 8000000 Avr.Stack = 64 ' Hardware configuration: LCD Lcd4.PinDB4 = PortD.4 Lcd4.PinDB5 = PortD.5 Lcd4.PinDB6 = PortD.6 Lcd4.PinDB7 = PortD.7 Lcd4.PinRS = PortD.2 Lcd4.PinEN = PortD.3 'Lcd4.PinRW = PortD.1 ' Optional, basically unused anyway Lcd4.Config.Columns = 20 Lcd4.Config.Lines = 2 ' Hardware configuration: Keys #define Key0 As PortB.0 #define Key1 As PortB.1 Key0.Mode = Input, PullUp ' Key0 as Input, with PullUp enabled Key1.Mode = Input, PullUp ' Key1 as Input, with PullUp enabled ' Used variables Dim IRQ As Byte ' Interrupt requests Dim Count1 As Byte ' Software Counter 1 (for 200ms) Dim Count2 As Byte ' Software Counter 2 (for 1s) Dim Year As Byte ' Current year (tenths and ones only) Dim Month As Byte ' Current month Dim Day As Byte ' Current day Dim Hour As Byte ' Current hour Dim Minute As Byte ' Current minute Dim Second As Byte ' Current second ' Initialization ============================================================== ' Variables IRQ = 0 ' We have no Interrupts yet. Year = 19 ' Begin with (20)19 Month = 8 ' August Day = 1 ' The 1st ' LCD Lcd4.Init() ' Initialize display Lcd4.Cursor.Disable() ' Don't show the cursor Lcd4.Screen.Clear() ' Clear the entire screen IRQ.0 = 1 ' Mark screen as dirty (repaint needed) ' Timer 2 (CTC, 8ms) Timer2.Clock = 256 ' 8.000.000 / 256 = 32µs Ticks Timer2.Cmp.Value = 249 ' 8.000.000 / 256 / 249 = 8ms Interrupt Timer2.Cmp.Clear.Enable ' Enable CTC mode Timer2.Cmp.Isr = ISR_Timer2_OV ' Set ISR for Timer2 ' Setup watchdog ' Ok, watchdog implementation is buggy right now... 'Wdt.Clock = 125ms ' More than enough 'Wdt.Mode = Reset ' Reset the chip if stucked ASM PUSH R16 // Save R16 IN R16, WDTCR // Load Watchdog Timer Control Register ORI R16, (1<<WDCE) OR (1<<WDE) OR (1<<WDP2) // Enable WDT and set time OUT WDTCR, R16 // Write modified values POP R16 // Restore R16 EndASM ' Set sleep mode Sleep.Mode = idle ' Lowest sleep mode (we need Timer2) ' Enable interrupts Avr.Interrupts.enable ' Main Loop =================================================================== Do ' Handle IRQ's If IRQ.0 = 1 Then ' IRQ.0 = Display needs repainting Call OnIRQ0 End If ' Kick the dog Wdt.Reset ' Fall asleep Sleep.Now Loop ' Low priority handler below ================================================== ' IRQ.0 = Display is dirty, repaint it. Procedure OnIrq0() ' Display header Lcd4.Cursor.Set(1, 1) Lcd4.Text(" Std. Min. Sek.") ' Display hours Lcd4.Cursor.Set(2, 2) Lcd4.Text(Format("00", Hour)) Lcd4.Text(" : ") ' Display minutes Lcd4.Text(Format("00", Minute)) Lcd4.Text(" : ") ' Display seconds Lcd4.Text(Format("00", Second)) IRQ.0 = 0 ' We handled IRQ0, so reset it EndProc ' Interrupt service routines below ============================================ ' ISR for Timer2 CTC overflow (each 8ms). ISR ISR_Timer2_OV Incr Count1 ' Increment soft counter 1 (for 200ms) If Count1 = 25 Then ' Check for overflow Count1 = 0 ' Reset it Call ISR_Tick_200ms() ' Process Tick routine End If Incr Count2 ' Increment soft counter 2 (for 1s) If Count2 = 125 Then ' Check for overflow Count2 = 0 ' Reset it Call ISR_Tick_1s() ' Process Tick routine End If EndISR ' Called by ISR_Timer2_OV each 200ms. ' Still in ISR mode, hence the prefix. Procedure ISR_Tick_200ms() If Key0 = 0 Then ' If Key0 is pressed Incr Minute ' Increment minute If Minute >= 60 Then ' Check for overflow Minute = 0 ' Reset to 0 End If End If If Key1 = 0 Then ' If Key1 is pressed Incr Hour ' Increment hours If Hour >= 24 Then ' Check for overflow Hour = 0 ' Reset to 0 End If End If If Key0 = 0 And Key1 = 0 Then ' If Key 0 and 1 are pressed Second = 0 ' Reset whole time Minute = 0 ' " Hour = 0 ' " End If Irq.0 = 1 ' Enforce display reset EndProc ' Called by ISR_Timer2_OV each 1000ms (=1s). ' Still in ISR mode, hence the prefix. Procedure ISR_Tick_1s() Incr Second ' Increment seconds If Second >= 60 Then ' Check for overflow Second = 0 ' Reset to 0 Incr Minute ' Increment minutes End If If Minute >= 60 Then ' Check for overflow Minute = 0 ' Reset to 0 Incr Hour ' Increment hours End If If Hour >= 24 Then ' Check for overflow Hour = 0 ' Reset to 0 Incr Day ' Increment day End If Dim DayOv As Byte ' Temp storage for day overflow Select Case Month Case 1, 3, 5, 7, 8, 10, 12 ' Months with 31 days DayOv = 32 ' Set overflow Case 4, 6, 9, 11 ' Months with 30 days DayOv = 31 ' Set overflow Case 2 ' The allmighty februrary If Year And 0b00000011 = 0 Then ' Check for leap year DayOv = 30 ' It is, set overflow (30, cause 29 days) Else ' No leap year DayOv = 29 ' Set overflow (29, cause 28 days) End If End Select If Day >= DayOv Then ' Check for overflow Day = 1 ' Reset to 1 Incr Month ' Increment month End If If Month >= 13 Then ' Check for overflow Month = 1 ' Reset to 1 Incr Year ' Increment year End If If Year >= 100 Then ' Check for overflow (only tenths and ones) Year = 0 ' Reset to 0 End If EndProc
Hmm...@LotadaC Btw, grade getestet. LunaAVR frisst es. Das ist nicht Bayrisch.
If ((Bytevariable AND Bytekonstante)=0) Then...
If (Bytevariable AND Bytekonstante) Then...
Aus diesem Code habe ich Zeile 190 in meinem Code reingesetzt und dafür das selbige aus meinen Dim Anweisungen rausgenommen. Eigentlich nur nur diese Zeile an einen anderen Platz versetzt compile Programm(F7) und Progamm chip(F4). Danach war nichts mehr auf dem Display zu sehen und der Atmega8 wurde nicht mehr erkannt. Dummerweise habe ich auch noch das Programm, ohne zu wissen was mit dem Chip geschehen ist, auf meinem zweiten Board geschrieben.Falls es wen interessiert, hier das Selbe in LunaAVR, diesmal komplett:
Dann müsste das doch einfach so geändert werden, um einen ein Sekundentakt zu erzeugen.jeden Timer ein eigenes TIFR (TIFR0 für Timer0, TIFR1 für Timer1 und TIFR2 für Timer2).
If Tifr0.tov0 = 1 Then 'wenn Timer übergelaufen ist Tifr0.tov0 = 1 'Überlaufflag zurücksetzen Incr Z If Z = 245 Then 'Überläufe zählen (245) Z = 0 'Zähler zurücksetzen Toggle Gruen 'LED toggeln End If End If
Der GCC macht ausInteressant wäre also, wie andere Sprachen (z.B. Mondisch) bestimmte Fälle optimieren können.
Im Prinzip habt Ihr ja:If ((Bytevariable AND Bytekonstante)=0) Then...
Zu erwarten wäre also,
...daß das And aufgelöst wird (ANDI) - Ergebnis ist ein Byte.
...daß der Vergleich mit 0 aufelöst wird (CPI)
...daß in Abhängigkeit des Z-Flags bedingt gesprungen wird (BREQ/BRNE)
if ((zeit.sec & 0x03) == 0) // Die Klammern sind in C zwingend // der Vergleich hat höhere Priorität, als das bitweise UNDfolgendes:
00000359 MOVW R26,R14 Copy register pair 0000035A LD R24,X Load indirect 0000035B ANDI R24,0x03 Logical AND with immediate 0000035C BRNE PC+0x0B Branch if not equalDie ersten beiden Zeilen holen der Sekundenwert aus einer Zeitstruktur (ich habe die Sekunden genommen, da sieht man schneller eine Veränderung als bei den Jahren…), dann folgt vor dem BRNE nur noch ein ANDI.
if (zeit.sec & 0x03)wird nur das BRNE durch ein BREQ ersetzt.
Ok, ich werde in Zukunft nur noch das kopieren, was ich selbst schon geschrieben habe bzw. gelernt und verstanden. Wenn ich also beim Atmega88a den Timer0 im CTC Modus verwenden möchte, kann ich das in Bascom einfach so schreiben. Will ich aber nachschlagen und das Datenblatt sehe, fällt mir auf, dass die Schreibweise ganz anders erfolgt, wie in Bascom.Also, schreibe jede Zele selbst, auch wenn C&P so verführerisch sind.