Hallo,
ich beschäftige mich gerade mit der Programmierung des ATmega4809. Wie
ich gelesen habe stammt der Syntax der neuen AVR von den AVR XMEGA ab,
mit denen ich mich noch nie befasst habe. Ich habe folgenden Code:
1
intmain(void)
2
{
3
PORTF.DIR|=PIN5_bm;
4
while(1)
5
{
6
PORTF.DIRSET=PIN5_bm;
7
_delay_ms(500);
8
PORTF.DIRCLR=PIN5_bm;
9
_delay_ms(500);
10
}
11
}
Nun zu meiner Frage: Wann wird PIN5_bm und wann PIN5_bp verwendet?
Dann habe ich noch folgenden Code:
1
voidUSART_init()
2
{
3
USART0.BAUD=(uint16_t)USART0_BAUD_RATE(9600);
4
USART0.CTRLB|=USART_TXEN_bm;
5
stdout=&USART_stream;
6
}
Warum wird bei USART0.BAUD ein einfaches = verwendet und bei
USART0.CTRLB ein |=?
Und dann habe ich noch einen Teil der Timer Initialisierung:
1. bm - bp: bit-mask vs. bit-position, siehe z.B.:
.equ CCL_RUNSTDBY_bm = 0x40 ; Run in Standby bit mask
.equ CCL_RUNSTDBY_bp = 6 ; Run in Standby bit position
2. Weiß nicht, warum ver-odert wird, ich hätte
USART0.CTRLB = USART_TXEN_bm;
verwendet.
3. Ohne Ver-oderung wird mit dem zweiten Befehl der erste zunichte
gemacht, d.h. der vorige Wert überschrieben.
Hallo Felix,
deine Fragen beziehen sich grundlegend alle auf das Thema
Bit-Manipulation von Registerinhalten.
> Nun zu meiner Frage: Wann wird PIN5_bm und wann PIN5_bp verwendet?
PIN5_bm ist ein Define für die Bitmaske. In diesem Fall 0x20, wenn ich
mich nicht irre. Du nutzt ihn in deinem Fall, um das Bit 6 in einem
Register zu setzen. Beispiel: "PORTF.DIRSET = PIN5_bm;" schreibt 0x20 in
das Register DIRSET des PORT F, um die Direction des Pin 5 von Port F
auf auf 1 zu setzen (das müsste "Input" sein).
PIN5_bp ist ein Define für die Bitposition im Register. In diesem Fall
müsste der Wert 6 sein. Beispiel: Das 6.te Bit im Register DIRSET dient
der Einstellung des Pin 5.
> Warum wird bei USART0.BAUD ein einfaches = verwendet und bei> USART0.CTRLB ein |=?
Bei USART0.BAUD überschreibst du das Ganze Register BAUD der USART0 mit
dem Wert.
Mit "USART0.CTRLB |= USART_TXEN_bm;" setzt du nur das Bit TXEN im
Register CTRLB der USART0.
>> Und dann habe ich noch einen Teil der Timer Initialisierung:>
> Wenn ich es wie oben schreibe funktioniert es, allerdings nicht wenn ich> es so schreibe:>
1
>TCA0.SINGLE.CTRLA=TCA_SINGLE_CLKSEL_DIV2_gc;
2
>TCA0.SINGLE.CTRLA=TCA_SINGLE_ENABLE_bm;
3
>
>
Das kann nicht funktionieren, da du bei deinem Beispiel den gesamten
Registerwert von CTRLA wieder überschreibst. Mit der ersten Zeile setzt
du dir über das "|" (oder) mit den beiden Define einen Wert zusammen und
schreibst dann das Resultat.
Ich würde dir empfehlen dich einmal mit dem Thema Bit-Manipulation
auseinander zu setzen. Ich habe jetzt leider keine Guten Tutorials oder
ähnliches zur Hand, aber vielleicht kann jemand anderes aus dem Forum
helfen.
Gruß
Olli
Hallo S. Landolt,
entschuldige ich habe zu spät gesehen, dass du schon geantwortet hast.
Hierzu:
> 2. Weiß nicht, warum ver-odert wird, ich hätte> USART0.CTRLB = USART_TXEN_bm;> verwendet.
Dies wird verwendet, um den Rest des Registers nicht mit 0 zu
überschreiben. Ggf. sind dort einige Bit, die standardmäßig auf 1
gesetzt sind und deren Einstellung man dann ungewollt ändert. Ein "|="
ist an dieser Stelle sicherer.
Gruß
Olli
Vielen Dank für die Antworten, das hilft mir auf jeden Fall.
Oliver L. schrieb:> PIN5_bm ist ein Define für die Bitmaske. In diesem Fall 0x20, wenn ich> mich nicht irre. Du nutzt ihn in deinem Fall, um das Bit 6 in einem> Register zu setzen. Beispiel: "PORTF.DIRSET = PIN5_bm;" schreibt 0x20 in> das Register DIRSET des PORT F, um die Direction des Pin 5 von Port F> auf auf 1 zu setzen (das müsste "Input" sein).
Das bedeutet dann, dass der Befehl
1
PORTF.DIRSET=PIN5_bm;
nur Pin5 auf "high" setzt und alle anderen mit "low" überschreibt? Wenn
ich aber die anderen behalten möchten , dann muss ich ein |= verwenden?
Viele Grüße
Felix
S. Landolt schrieb:>> ... Ggf. sind dort einige Bit ...>> Allenfalls aus der Vorgeschichte des Programms, Reset-Wert von> USART0.CTRLB ist 0.
Ok das stimmt, in diesem Fall geht es. Ich habe es mir nur allgemein
angewöhnt, um keine Probleme zu bekommen, falls es doch einmal anders
ist. :)
> nur Pin5 auf "high" setzt und alle anderen mit "low" überschreibt? Wenn> ich aber die anderen behalten möchten , dann muss ich ein |= verwenden?
Ja das stimmt und man kann es auch so schreiben, wie S. Landolt es
angemerkt hat.
Hier aber noch eine kleine Info:
Das Register DIRSET dient speziell dem setzen der Bit im Register DIR.
Es ist eine Vereinfachung, um schnell ein Bit im Register DIR setzen zu
können. Als Pendant dazu gibt es das Register DIRCLR, mit dem man im
Register DIR das entsprechende Bit löscht.
1
PORTF.DIRSET=PIN5_bm;
führt also dazu, dass Bit 6 im Register DIR gesetzt wird, jedoch nicht,
dass alle anderen Bit im Register DIR gelöscht werden.