direkt in ein Register des Tiny5 schreiben

OP #7935254

Hallo liebe Gemeinde,

ich möchte auf einem AT Tiny5 direkt mit dem Register PCMSK (0x10) arbeiten. Also ungefähr so:

1
PCMSK |= (1<<PCINT0);    //enable pin change interrupt on PB3

Wie macht man so etwas in einem C-Script für avr-gcc?

PCMSK ist doch auch nur eine Definition für irgendetwas, um sich das Leben einfacher zu gestalten.

Vielen Dank im voraus

Svensson

In jeder halbwegs ordentlichen IDE kannst mit gedrückt gehaltener Strg Taste auf PCMSK klicken, dann siehst du, wie es definiert ist. Es ist ein Zeiger mit der Adresse des Registers.

Und PCINT0 ist schlicht eine Zahl und zwar die Nummer dieses Bits.

Direkter als

PCMSK |= (1<<PCINT0);

sowie

PCMSK &= ~(1<<PCINT0);

geht es in C nicht, weil die Programmiersprache keine gesonderte Syntax für Register hat und auch nicht für dem Zugriff auf einzelne Bits. Aber keine Sorge, der Compiler ist so schlau, diese Zeile in einen einzigen CPU Befehl umzusetzen, auch wenn sie eher nach einer Kombo aus read+modify+write back aussieht.

OP

Ich habe in meiner IDE keine vorgegebene io.h für den Tiny5. In der Doku habe ich gelesen, daß PCMSK das Register 0x10 ist.

Ich brauche auch nur diesen einen direkten Befehl, um das eine Bit im PCMSK zu setzen. Der Rest ist dann Standard C.

(Firma: 1984now)

Svensson schrieb:

Ich habe in meiner IDE keine vorgegebene io.h für den Tiny5.

Dann sorg' dafür, dass du eine hast. Der Tiny5 ist dermaßen übersichtlich, das man die zur Not sogar von Hand verfassen könnte. Aber warum sollte man? Gibt's ja schließlich fix und fertig von MC.

Musst du halt die IDE wechseln. Welche ist es den derzeit?

Svensson schrieb:

Ich habe in meiner IDE keine vorgegebene io.h für den Tiny5.

Aber die avr-libc bringt die Header mit.

1
#define __SFR_OFFSET 0x00
2
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
3

4
#define PCMSK _SFR_IO8(0x10)
5
#define PCINT0 0
6
#define PCINT1 1
7
#define PCINT2 2
8
#define PCINT3 3
Angehängte Dateien:
(Firma: 1984now)

Nemopuk schrieb:

Aber die avr-libc bringt die Header mit.

Ja klar. Deswegen führt nur die Beantwortung meiner Frage, welche IDE dee TO eigentlich verwendet (und damit der Frage, welche Toolchain und damit wiederum welche Header).

Genau diese eine zentrale Frage wurde vom TO allerdings negativ bewertet.

Sprich: Das ist ganz offensichtlich ein Troll, der sich darum sorgt, dass sein Troll-Thread zu kurz wird.

Nemopuk schrieb:

1
#define __SFR_OFFSET 0x00
2
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
3
#define PCMSK _SFR_IO8(0x10)

Mir fehlt da der Pointer. Aber ich bin ganz sicher, die Zeilen korrekt aus den Headern heraus kopiert zu haben. Und war da nicht auch was mit volatile?

Vielleicht kann das jemand erklären.

Nemopuk schrieb:

Vielleicht kann das jemand erklären.

Ich hab's selbst gefunden. Ich habe wohl doch die falschen Zeilen kopiert.

So sieht es besser aus:

1
#define __SFR_OFFSET 0x00
2
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
3
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
4
#define PCMSK _SFR_IO8(0x10)

Man kann die Definition von PCMSK so zusammen fassen:

1
#define PCMSK (*(volatile uint8_t *)(0x10))

Also ein Zeiger auf ein volatiles 8 Bit Register an Adresse 0x10. So hatte ich das auch in Erinnerung.

OP

Nemopuk schrieb:

Man kann die Definition von PCMSK so zusammen fassen: #define PCMSK (*(volatile uint8_t *)(0x10))

Also ein Zeiger auf ein volatiles 8 Bit Register an Adresse 0x10. So hatte ich das auch in Erinnerung.

Danke! Das ist genau das, was ich gesucht hatte. Und schon ist der Fehler weg...

Ob S. schrieb:

Der Tiny5 ist dermaßen übersichtlich, das man die zur Not sogar von Hand verfassen könnte.

Das kann man wohl sagen. Das "Programm" ist so ungefähr 20 Zeilen lang. Im Grunde ist es ein Luxus-Timer; ist auch nicht mein Ding - ich soll es nur kompilieren. Kompliliert sind es 470 Byte, also eher übersichtlich.

Ob S. schrieb:

Genau diese eine zentrale Frage wurde vom TO allerdings negativ bewertet.

Ich habe gar nichts bewertet.

Hintergrund: Ich habe schon den ganzen Tag verplempert, um das Miniprogramm zu übersetzen. War schon kurz davor, das gleich in Assembler neu zu schreiben. :-( Beim Atmel Studio 4.19 habe ich wohl vergessen wie es geht, außerdem ist der Tiny5 grau in der Liste. Bei avr-gcc (avr8-gnu-toolchain 3.7.x) erhalte ich die Meldung, daß beim Tiny5 nur Assembler unterstützt wird. Ebenso beim WinAVR. Dann habe ich mir den GCC 10.3 heruntergeladen, aber in der 1000+x-seitigen Doku habe ich nur -mmcu=avrtiny gefunden, der aber nicht laufen will. VS mit PlatformIO habe ich mir auch heruntergeladen, aber das ist auch nichts für mal eben schnell.

OP

Nun, die avr8-gnu-toolchain habe ich von Microchip heruntergeladen. Das war schon die neueste Version (von 2022).

Den gcc habe ich direkt von der Projektwebsite. Da habe ich extra den älteren 10.3 gewählt, weil es doch angeblich mit den neueren irgenwelche Probleme gab.

Svensson schrieb:

Den gcc habe ich direkt von der Projektwebsite. Da habe ich extra den älteren 10.3 gewählt, weil es doch angeblich mit den neueren irgenwelche Probleme gab.

A. B. schrieb:

aktuell ist gcc-15.2.0 von 2025-08-08

1
~$ find /usr/lib/gcc/avr/ /usr/lib/avr -iname "iotn5*.h" -exec grep -E "tiny|PCMSK" {} \;
2
/* avr/iotn5.h - definitions for ATtiny5 */
3
#ifndef _AVR_ATtiny5_H_
4
#define _AVR_ATtiny5_H_ 1
5
#define PCMSK _SFR_IO8(0x10)
6
#endif /* _AVR_ATtiny5_H_ */
1
~$ avr-gcc -v
2
Using built-in specs.
3
Reading specs from /usr/lib/gcc/avr/5.4.0/device-specs/specs-avr2
4
COLLECT_GCC=avr-gcc
5
COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/5.4.0/lto-wrapper
6
Target: avr
7
Configured with: ../gcc/configure -v --enable-languages=c,c++ --prefix=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --bindir=/usr/bin --libexecdir=/usr/lib --libdir=/usr/lib --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-libssp --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=avr CFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-Q3AFj7/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong -Wformat ' CPPFLAGS='-Wdate-time -D_FORTIFY_SOURCE=2' CXXFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-Q3AFj7/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong -Wformat ' FCFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-Q3AFj7/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong' FFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-Q3AFj7/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong' GCJFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-Q3AFj7/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong' LDFLAGS=-Wl,-z,relro OBJCFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-Q3AFj7/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong -Wformat ' OBJCXXFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-Q3AFj7/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong -Wformat '
8
Thread model: single
9
gcc version 5.4.0 (GCC)

Svensson schrieb:

ich möchte auf einem AT Tiny5 direkt mit dem Register PCMSK (0x10) arbeiten. Also ungefähr so:

1
PCMSK |= (1<<PCINT0);    //enable pin change interrupt on PB3

Wie macht man so etwas in einem C-Script für avr-gcc?

Nicht nur ungefähr, sondern genau so. Falls eine Fehlermeldung kommt, hast Du noch diese Zeile vergessen:

1
#include <avr/io.h>

Oder das falsche Target ausgewählt.

OP

Norbert schrieb:

1
> Reading specs from /usr/lib/gcc/avr/5.4.0/device-specs/specs-avr2
2
> ...
3
> gcc version 5.4.0 (GCC)
4
>

Sagt mir das, es wird der gcc in Version 5.4.0 benutzt? Dann wäre das auch nicht "modern".

A. B. schrieb:

aktuell ist gcc-15.2.0 von 2025-08-08

https://github.com/ZakKemble/avr-gcc-build/releases/tag/v15.2.0-1

Tausend Dank! Das ist offensichtlich genau das, was ich gleich hätte verwenden sollen.

Johann L. schrieb:

Das geht so nicht. In C müssen Anweisungen in einer Funktion stehen.

Erbsenzähler. :-) Im Zweifel steht es dann in setup{} oder main{}

OP

Johann L. schrieb:

Das sagt dir$ avr-gcc --version

Und selbst wenn es eine v5.4 ist, bereits damals vor fast 10 Jahren wurde AVRrc (Reduced Core) schon unterstützt:

Ich erhalte als Antwort: avr-gcc (AVR_8_bit_GNU_Zoolchain_3.7.0.1796> 7.3.0

Also müßte der funktionieren, aber das tut er nicht. Es kommt die Meldung, daß nur Assembler unterstützt wird für -mmcu=attiny5.

das ist dann kein C, sondern C++

Der gcc ist doch ein C-Compiler, der gpp ist doch der Compiler für C++, oder?

Außerdem müßte das doch egal sein, denn ein C++-Compiler müßte doch auch Standard-C übersetzen können?

Peter D. schrieb:

Habs eben probiert mit 5.4.0 (= AS7) und 7.3.0, geht beides: int main(void) { PCMSK |= (1<<PCINT0); 28: 80 9a sbi 0x10, 0 ; 16

Das ist aber vermutlich 7.3.0 output, oder? Der alte 5.4.0 erzeugt zumindest bei mir hier nämlich noch einen ganzen Sack mehr. Egal in welcher Optimierungsstufe (O0|O1|O2|Os).

1
#include <avr/io.h>
2
// avr-gcc -Wall -Wextra -pedantic -mmcu=attiny5 -os -o x x.c && avr-objdump -d x > xs.lst
3

4
int main(void) {
5
    PCMSK |= (1<<PCINT0);
6
    return 0;
7
}
1
00000000 <main>:
2
   0:  cf 93         push  r28
3
   2:  df 93         push  r29
4
   4:  cd b7         in  r28, 0x3d  ; 61
5
   6:  de b7         in  r29, 0x3e  ; 62
6
   8:  40 e1         ldi  r20, 0x10  ; 16
7
   a:  50 e0         ldi  r21, 0x00  ; 0
8
   c:  60 e1         ldi  r22, 0x10  ; 16
9
   e:  70 e0         ldi  r23, 0x00  ; 0
10
  10:  e6 2f         mov  r30, r22
11
  12:  f7 2f         mov  r31, r23
12
  14:  60 81         ld  r22, Z
13
  16:  61 60         ori  r22, 0x01  ; 1
14
  18:  e4 2f         mov  r30, r20
15
  1a:  f5 2f         mov  r31, r21
16
  1c:  60 83         st  Z, r22
17
  1e:  40 e0         ldi  r20, 0x00  ; 0
18
  20:  50 e0         ldi  r21, 0x00  ; 0
19
  22:  84 2f         mov  r24, r20
20
  24:  95 2f         mov  r25, r21
21
  26:  df 91         pop  r29
22
  28:  cf 91         pop  r28
23
  2a:  08 95         ret

Edit: Comment korrigiert

Man kann's noch ein wenig quetschen… ;-)

1
#include <avr/io.h>
2
// avr-gcc -Wall -Wextra -pedantic -mmcu=attiny5  -o x x.c && avr-objdump -d x 
3
__attribute__ ((OS_main))
4
int main(void) {
5
    PCMSK |= (1<<PCINT0);
6
    __builtin_unreachable();
7
}
1
00000028 <main>:
2
  28:  cd b7         in  r28, 0x3d  ; 61
3
  2a:  de b7         in  r29, 0x3e  ; 62
4
  2c:  40 e1         ldi  r20, 0x10  ; 16
5
  2e:  50 e0         ldi  r21, 0x00  ; 0
6
  30:  60 e1         ldi  r22, 0x10  ; 16
7
  32:  70 e0         ldi  r23, 0x00  ; 0
8
  34:  e6 2f         mov  r30, r22
9
  36:  f7 2f         mov  r31, r23
10
  38:  60 81         ld  r22, Z
11
  3a:  61 60         ori  r22, 0x01  ; 1
12
  3c:  e4 2f         mov  r30, r20
13
  3e:  f5 2f         mov  r31, r21
14
  40:  60 83         st  Z, r22

Interessant. Da musst du tatsächlich einen anderen 5.4.0 als ich haben.

1
/tmp/norbert$ avr-gcc --version
2
avr-gcc (GCC) 5.4.0
3
Copyright (C) 2015 Free Software Foundation, Inc.
4
This is free software; see the source for copying conditions.  There is NO
5
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Persönliche Seite

Svensson schrieb:

avr-gcc (AVR_8_bit_GNU_Zoolchain_3.7.0.1796> 7.3.0

Also eine von Atmel gepimpte Version.

Also müßte der funktionieren, aber das tut er nicht. Es kommt die Meldung, daß nur Assembler unterstützt wird für -mmcu=attiny5.

Sehr seltsam. Diese Meldung sollte nur kommen für -mmcu= at90s1200, attiny11, attiny12, attiny15 oder attiny28. Alle anderen Devices sollten entweder funktionieren oder komplett abgelehnt werden (specs File nicht gefunden etc.)

Und wo man auf jeden Fall drauf achten sollte, ist dass LDS und STS eine 16-Bit Codierung haben. Ansonsten: Binutils Bug.

Builds for Windows findet man bei Microchip, Zak Kemble oder

https://sourceforge.net/projects/winavr/files/avr-gcc/

Klaus H. schrieb:

Schön wär`s. Der Compiler Explorer hat gemeckert.... Hab deine Option per Copy&Paste eingefügt.

Hätte ich mir von avr-gcc auch gewünscht.

Das Verrückte ist, hab gerade in die bash history geschaut. Weiter oben hatte ich es erst einmal richtig und im weiteren Verlauf mit verschiedenen Optimierungen dann zielsicher durch editieren versaut. ;-)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über ein Jahr alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.