Mikrocontroller: ATtiny13
IDE: Atmel Studio
Ich versuche, eine Hello World-Anwendung zu schreiben, indem ich High an Port PB4 schreibe.
Das funktioniert gut:
int main(void)
{
DDRB = 0x10;
PORTB = 0x10;
while(1)
{
}
}
Bei der Definition von DDRB und PORTB zeigen sie erwartungsgemäß auf 0x17 und 0x18.
Dies funktioniert jedoch nicht:
int main(void)
{
char *dir = (void *)0x17;
char *port = (void *)0x18;
*dir = (unsigned int)0x10;
*port = (unsigned int)0x10;
while(1)
{
}
}
Ist mein Code falsch oder muss ich etwas anderes tun, um Zeiger zu verwenden?
unsigned int
Darsteller machen keinen Sinn; Die Datenrichtungs- und Portregister sind nur 8 Bit breit. Es ist ziemlich unwahrscheinlich, dass es Ihr Problem ist, aber versuchen Sie es mit Castinguint8_t
.0x10
ist 8 Bit breit, nicht wahr?Antworten:
Zeiger sind Zeiger. Das sind sie. Sie werden überhaupt nicht anders behandelt (wie könnten Sie sie anders behandeln?)
Die Hauptunterschiede zwischen X86 und AVR sind:
Außerdem macht Ihr Code keinen Sinn:
Eine Leere * einem Zeichen * zuweisen?
Ich bin momentan nicht für die Kompilierung des ATTiny13 eingerichtet, daher gelten diese Zahlen alle für den ATMega328p:
Der Zugriff auf DDRB und PORTB führt zu dieser Assembly:
Der Zugriff auf einen Zeiger auf einen Speicherort führt zu dieser Assembly:
Wie Sie sehen können, sind DDRB und PORTB keine normalen Variablen. DDRB ist definiert als:
und PORTB als:
_SFR_IO8 () ist ein Makro:
und _MMIO_BYTE ist:
__SFR_OFFSET kann je nach Chip entweder 0 oder 0x20 sein (normalerweise 0x20).
Das muss also bedeuten, dass die Adressen von DDRB und PORTB größer als 0x20 sein müssen.
Mit Blick auf den 328P-Chip ist DDRB 0x04 und PORTB 0x05. Zugriff als 0x24 und 0x25 mit den richtigen Datentypen also:
Ergebnisse in dieser Baugruppe:
Ähnlich aussehend? Der Compiler hat den 0x20-Offset erkannt, erkannt, dass es sich um SFRs handelt, und in den richtigen
out
Anweisungen ohne den 0x20-Offset kompiliert .Der Zugriff auf Ihre Portadressen + 0x20 funktioniert möglicherweise für den ATTiny13.
Wenn man sich nur den ATTiny25 ansieht,
DDRB = 0x10
ergibt sich Folgendes :und der Zugriff auf einen Zeiger an der Adresse 0x37 führt zu:
Das sieht also so aus, als wäre es wahrscheinlich (fügen Sie Ihrer Zeigeradresse 0x20 hinzu).
quelle
0x0
auf0x9F
die Register I / O und SRAM zugegriffen werden kann . Was sind die anderen Adressräume?outportb(0x378, 0x34);
.