oberallgeier
09.02.2015, 14:34
... in meinem betagten Alter ja was vorgenommen ... Zur Zeit habe ich Studio4 von Atmel auf dem Nootebok ...Hallo Rolf,
du bist nicht der einzige Grauhaardackel oder UHU (Unter HUndert) hier im Forum. Ich habe übrigens vor ein paar Jahren mit Assembler auf AVRs angefangen (mit Blick auf alte Z80-Erfahrungen mit Assembler und FORTRAN), bin aber nach ein, zwei Jahren auf C übergegangen. Das ist bei mir immer noch eine Art sehr persönlicher Dialekt, sprich "Cäh" *ggg* aber es geht so.
Zu Studio4 kann ich nur sagen, dass ich nach Ausflügen in die Version AVRStudio5 und -6 wieder zu Version vier zurückkam (Version 4.18 Build 700 auf WIN7pro64). Gerade die Version 6 hat einen hübsch großen Overhead, der für richtig große Projekte bestimmt sinnvoll ist. Bei meinem aktuell größten Projekt, einem Roboter mit aktuell sieben (Controller-)Platinen, dazu MOtortreiberplatine etc., insgesamt vermutlich irgendwo bei dreissig- bis vierzigtausend Zeilen C, ist das für mich immer noch übersichtlich genug. Andererseits findet sich ein junger Programmierer aus meinem Umfeld (19J, Jugend-forscht-Team) prächtig wohl mit der 6er-Version auf nem Notebook für ein mega328er Projekt und an die dreitausend Codezeilen.
Nun mal ein kleiner Appetithappen. Peter hat schon davon geschrieben: "...C-Compiler ... Option ... C-Code erzeugt und zusätzlich ... Assembler ...".
Beispiel ist hier der so genannte *.lls-file aus einem meiner Projektchen als Teil des Compilats aus dem Studio4; vollständig und ohne Änderungen. Darin findest Du einiges an Assemblermnemonics und verteilt darin die originalen C-Sequenzen. Durch diese eingestreuten Quellzeilen ist eine perfekte Navigation von Deinem C-Code aus durch die maschinenlauffähige Programmversion möglich - siehe rot markierte Zeile "int main(void) //. " in beiden Beispielen.
tstu.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000290 00000000 00000000 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000022 00800060 00000290 00000304 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .debug_aranges 00000020 00000000 00000000 00000326 2**0
CONTENTS, READONLY, DEBUGGING
3 .debug_pubnames 000000ae 00000000 00000000 00000346 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_info 000007f8 00000000 00000000 000003f4 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_abbrev 0000017b 00000000 00000000 00000bec 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_line 000004bf 00000000 00000000 00000d67 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_frame 000000c0 00000000 00000000 00001228 2**2
CONTENTS, READONLY, DEBUGGING
8 .debug_str 0000014f 00000000 00000000 000012e8 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_loc 000002b7 00000000 00000000 00001437 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 2a 00 jmp 0x54 ; 0x54 <__ctors_end>
4: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
8: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
c: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
10: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
14: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
18: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
1c: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
20: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
24: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
28: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
2c: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
30: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
34: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
38: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
3c: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
40: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
44: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
48: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
4c: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
50: 0c 94 3f 00 jmp 0x7e ; 0x7e <__bad_interrupt>
00000054 <__ctors_end>:
54: 11 24 eor r1, r1
56: 1f be out 0x3f, r1 ; 63
58: cf e5 ldi r28, 0x5F ; 95
5a: d8 e0 ldi r29, 0x08 ; 8
5c: de bf out 0x3e, r29 ; 62
5e: cd bf out 0x3d, r28 ; 61
00000060 <__do_copy_data>:
60: 10 e0 ldi r17, 0x00 ; 0
62: a0 e6 ldi r26, 0x60 ; 96
64: b0 e0 ldi r27, 0x00 ; 0
66: e0 e9 ldi r30, 0x90 ; 144
68: f2 e0 ldi r31, 0x02 ; 2
6a: 02 c0 rjmp .+4 ; 0x70 <.do_copy_data_start>
0000006c <.do_copy_data_loop>:
6c: 05 90 lpm r0, Z+
6e: 0d 92 st X+, r0
00000070 <.do_copy_data_start>:
70: a2 38 cpi r26, 0x82 ; 130
72: b1 07 cpc r27, r17
74: d9 f7 brne .-10 ; 0x6c <.do_copy_data_loop>
76: 0e 94 ee 00 call 0x1dc ; 0x1dc <main>
7a: 0c 94 46 01 jmp 0x28c ; 0x28c <_exit>
0000007e <__bad_interrupt>:
7e: 0c 94 00 00 jmp 0 ; 0x0 <__vectors>
00000082 <lcd_send>:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//Eigentliche LCD-Zugriffs-Funktion; 4-Bit-Modus
void lcd_send(unsigned char data) {
// oberes Nibble setzen
LCD_PORT = (LCD_PORT & 0xF0) | ((data >> 4) & 0x0F);
82: 98 b3 in r25, 0x18 ; 24
84: 28 2f mov r18, r24
86: 22 95 swap r18
88: 2f 70 andi r18, 0x0F ; 15
8a: 90 7f andi r25, 0xF0 ; 240
8c: 29 2b or r18, r25
8e: 28 bb out 0x18, r18 ; 24
can be achieved.
*/
void
_delay_loop_1(uint8_t __count)
{
__asm__ volatile (
90: 31 e0 ldi r19, 0x01 ; 1
92: 93 2f mov r25, r19
94: 9a 95 dec r25
96: f1 f7 brne .-4 ; 0x94 <lcd_send+0x12>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// erzeugt den Enable-Puls
void lcd_enable(void)
{
LCD_PORT |= (1<<LCD_EN1);
98: c5 9a sbi 0x18, 5 ; 24
9a: 23 e0 ldi r18, 0x03 ; 3
9c: 92 2f mov r25, r18
9e: 9a 95 dec r25
a0: f1 f7 brne .-4 ; 0x9e <lcd_send+0x1c>
_delay_us(10); // kurze Pause
// Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
// http://www.mikrocontroller.net/topic/80900
LCD_PORT &= ~(1<<LCD_EN1);
a2: c5 98 cbi 0x18, 5 ; 24
// oberes Nibble setzen
LCD_PORT = (LCD_PORT & 0xF0) | ((data >> 4) & 0x0F);
_delay_us(5);
lcd_enable();
// unteres Nibble setzen
LCD_PORT = (LCD_PORT & 0xF0) | (data & 0x0F);
a4: 98 b3 in r25, 0x18 ; 24
a6: 8f 70 andi r24, 0x0F ; 15
a8: 90 7f andi r25, 0xF0 ; 240
aa: 98 2b or r25, r24
ac: 98 bb out 0x18, r25 ; 24
ae: 3a 95 dec r19
b0: f1 f7 brne .-4 ; 0xae <lcd_send+0x2c>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// erzeugt den Enable-Puls
void lcd_enable(void)
{
LCD_PORT |= (1<<LCD_EN1);
b2: c5 9a sbi 0x18, 5 ; 24
b4: 2a 95 dec r18
b6: f1 f7 brne .-4 ; 0xb4 <lcd_send+0x32>
_delay_us(10); // kurze Pause
// Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
// http://www.mikrocontroller.net/topic/80900
LCD_PORT &= ~(1<<LCD_EN1);
b8: c5 98 cbi 0x18, 5 ; 24
ba: 84 e1 ldi r24, 0x14 ; 20
bc: 8a 95 dec r24
be: f1 f7 brne .-4 ; 0xbc <lcd_send+0x3a>
// unteres Nibble setzen
LCD_PORT = (LCD_PORT & 0xF0) | (data & 0x0F);
_delay_us(5);
lcd_enable();
_delay_us(60);
LCD_PORT &= 0xF0;
c0: 88 b3 in r24, 0x18 ; 24
c2: 80 7f andi r24, 0xF0 ; 240
c4: 88 bb out 0x18, r24 ; 24
}
c6: 08 95 ret
000000c8 <lcd_command>:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// sendet einen Befehl an das LCD
void lcd_command(unsigned char temp1)
{
LCD_PORT &= ~(1<<LCD_RS); // RS auf 0 setzen
c8: c4 98 cbi 0x18, 4 ; 24
lcd_send(temp1);
ca: 0e 94 41 00 call 0x82 ; 0x82 <lcd_send>
}
ce: 08 95 ret
000000d0 <lcd_data>:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// sendet ein Datenbyte an das LCD
void lcd_data(unsigned char temp1)
{
LCD_PORT |= (1<<LCD_RS); // RS auf 1 setzen
d0: c4 9a sbi 0x18, 4 ; 24
lcd_send(temp1);
d2: 0e 94 41 00 call 0x82 ; 0x82 <lcd_send>
}
d6: 08 95 ret
000000d8 <lcd_enable>:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// erzeugt den Enable-Puls
void lcd_enable(void)
{
LCD_PORT |= (1<<LCD_EN1);
d8: c5 9a sbi 0x18, 5 ; 24
da: 83 e0 ldi r24, 0x03 ; 3
dc: 8a 95 dec r24
de: f1 f7 brne .-4 ; 0xdc <lcd_enable+0x4>
_delay_us(10); // kurze Pause
// Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
// http://www.mikrocontroller.net/topic/80900
LCD_PORT &= ~(1<<LCD_EN1);
e0: c5 98 cbi 0x18, 5 ; 24
}
e2: 08 95 ret
000000e4 <lcd_clear>:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Sendet den Befehl zur Löschung des Displays
void lcd_clear(void)
{
lcd_command(CLEAR_DISPLAY);
e4: 81 e0 ldi r24, 0x01 ; 1
e6: 0e 94 64 00 call 0xc8 ; 0xc8 <lcd_command>
milliseconds can be achieved.
*/
void
_delay_loop_2(uint16_t __count)
{
__asm__ volatile (
ea: 82 ee ldi r24, 0xE2 ; 226
ec: 94 e0 ldi r25, 0x04 ; 4
ee: 01 97 sbiw r24, 0x01 ; 1
f0: f1 f7 brne .-4 ; 0xee <lcd_clear+0xa>
_delay_ms(5);
}
f2: 08 95 ret
000000f4 <lcd_init>:
// Initialisierung:
// Muss ganz am Anfang des Programms aufgerufen werden.
void lcd_init(void)
{
LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN1); // Port auf Ausgang schalten
f4: 87 b3 in r24, 0x17 ; 23
f6: 8f 63 ori r24, 0x3F ; 63
f8: 87 bb out 0x17, r24 ; 23
fa: 8c e4 ldi r24, 0x4C ; 76
fc: 9d e1 ldi r25, 0x1D ; 29
fe: 01 97 sbiw r24, 0x01 ; 1
100: f1 f7 brne .-4 ; 0xfe <lcd_init+0xa>
// muss 3mal hintereinander gesendet werden zur Initialisierung
_delay_ms(30);
LCD_PORT = (LCD_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x03;
102: 88 b3 in r24, 0x18 ; 24
104: 80 7e andi r24, 0xE0 ; 224
106: 83 60 ori r24, 0x03 ; 3
108: 88 bb out 0x18, r24 ; 24
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// erzeugt den Enable-Puls
void lcd_enable(void)
{
LCD_PORT |= (1<<LCD_EN1);
10a: c5 9a sbi 0x18, 5 ; 24
can be achieved.
*/
void
_delay_loop_1(uint8_t __count)
{
__asm__ volatile (
10c: 93 e0 ldi r25, 0x03 ; 3
10e: 89 2f mov r24, r25
110: 8a 95 dec r24
112: f1 f7 brne .-4 ; 0x110 <lcd_init+0x1c>
_delay_us(10); // kurze Pause
// Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
// http://www.mikrocontroller.net/topic/80900
LCD_PORT &= ~(1<<LCD_EN1);
114: c5 98 cbi 0x18, 5 ; 24
milliseconds can be achieved.
*/
void
_delay_loop_2(uint16_t __count)
{
__asm__ volatile (
116: e2 ee ldi r30, 0xE2 ; 226
118: f4 e0 ldi r31, 0x04 ; 4
11a: 31 97 sbiw r30, 0x01 ; 1
11c: f1 f7 brne .-4 ; 0x11a <lcd_init+0x26>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// erzeugt den Enable-Puls
void lcd_enable(void)
{
LCD_PORT |= (1<<LCD_EN1);
11e: c5 9a sbi 0x18, 5 ; 24
can be achieved.
*/
void
_delay_loop_1(uint8_t __count)
{
__asm__ volatile (
120: 89 2f mov r24, r25
122: 8a 95 dec r24
124: f1 f7 brne .-4 ; 0x122 <lcd_init+0x2e>
_delay_us(10); // kurze Pause
// Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
// http://www.mikrocontroller.net/topic/80900
LCD_PORT &= ~(1<<LCD_EN1);
126: c5 98 cbi 0x18, 5 ; 24
milliseconds can be achieved.
*/
void
_delay_loop_2(uint16_t __count)
{
__asm__ volatile (
128: 2a ef ldi r18, 0xFA ; 250
12a: 30 e0 ldi r19, 0x00 ; 0
12c: f9 01 movw r30, r18
12e: 31 97 sbiw r30, 0x01 ; 1
130: f1 f7 brne .-4 ; 0x12e <lcd_init+0x3a>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// erzeugt den Enable-Puls
void lcd_enable(void)
{
LCD_PORT |= (1<<LCD_EN1);
132: c5 9a sbi 0x18, 5 ; 24
can be achieved.
*/
void
_delay_loop_1(uint8_t __count)
{
__asm__ volatile (
134: 89 2f mov r24, r25
136: 8a 95 dec r24
138: f1 f7 brne .-4 ; 0x136 <lcd_init+0x42>
_delay_us(10); // kurze Pause
// Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
// http://www.mikrocontroller.net/topic/80900
LCD_PORT &= ~(1<<LCD_EN1);
13a: c5 98 cbi 0x18, 5 ; 24
milliseconds can be achieved.
*/
void
_delay_loop_2(uint16_t __count)
{
__asm__ volatile (
13c: f9 01 movw r30, r18
13e: 31 97 sbiw r30, 0x01 ; 1
140: f1 f7 brne .-4 ; 0x13e <lcd_init+0x4a>
lcd_enable();
_delay_ms(1);
lcd_enable();
_delay_ms(1);
LCD_PORT = (LCD_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x02;
142: 88 b3 in r24, 0x18 ; 24
144: 80 7e andi r24, 0xE0 ; 224
146: 82 60 ori r24, 0x02 ; 2
148: 88 bb out 0x18, r24 ; 24
14a: f9 01 movw r30, r18
14c: 31 97 sbiw r30, 0x01 ; 1
14e: f1 f7 brne .-4 ; 0x14c <lcd_init+0x58>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// erzeugt den Enable-Puls
void lcd_enable(void)
{
LCD_PORT |= (1<<LCD_EN1);
150: c5 9a sbi 0x18, 5 ; 24
can be achieved.
*/
void
_delay_loop_1(uint8_t __count)
{
__asm__ volatile (
152: 9a 95 dec r25
154: f1 f7 brne .-4 ; 0x152 <lcd_init+0x5e>
_delay_us(10); // kurze Pause
// Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
// http://www.mikrocontroller.net/topic/80900
LCD_PORT &= ~(1<<LCD_EN1);
156: c5 98 cbi 0x18, 5 ; 24
milliseconds can be achieved.
*/
void
_delay_loop_2(uint16_t __count)
{
__asm__ volatile (
158: c9 01 movw r24, r18
15a: 01 97 sbiw r24, 0x01 ; 1
15c: f1 f7 brne .-4 ; 0x15a <lcd_init+0x66>
_delay_ms(1);
lcd_enable();
_delay_ms(1);
// 4Bit / 2 Zeilen / 5x7
lcd_command(CMD_SetIFOptions | 0x08);
15e: 88 e2 ldi r24, 0x28 ; 40
160: 0e 94 64 00 call 0xc8 ; 0xc8 <lcd_command>
// Display ein / Cursor aus / kein Blinken
lcd_command(CMD_SetDisplayAndCursor | 0x04);
164: 8c e0 ldi r24, 0x0C ; 12
166: 0e 94 64 00 call 0xc8 ; 0xc8 <lcd_command>
// inkrement / kein Scrollen
lcd_command(CMD_SetEntryMode | 0x02);
16a: 86 e0 ldi r24, 0x06 ; 6
16c: 0e 94 64 00 call 0xc8 ; 0xc8 <lcd_command>
lcd_clear();
170: 0e 94 72 00 call 0xe4 ; 0xe4 <lcd_clear>
}
174: 08 95 ret
00000176 <lcd_string>:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Schreibt einen String auf das LCD
void lcd_string(char *data)
{
176: cf 93 push r28
178: df 93 push r29
17a: ec 01 movw r28, r24
17c: 03 c0 rjmp .+6 ; 0x184 <lcd_string+0xe>
while(*data) {
lcd_data(*data);
17e: 0e 94 68 00 call 0xd0 ; 0xd0 <lcd_data>
data++;
182: 21 96 adiw r28, 0x01 ; 1
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Schreibt einen String auf das LCD
void lcd_string(char *data)
{
while(*data) {
184: 88 81 ld r24, Y
186: 88 23 and r24, r24
188: d1 f7 brne .-12 ; 0x17e <lcd_string+0x8>
lcd_data(*data);
data++;
}
}
18a: df 91 pop r29
18c: cf 91 pop r28
18e: 08 95 ret
00000190 <lcd_generatechar>:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Schreibt ein Zeichen in den Character Generator RAM
// Daten liegen direkt im RAM
void lcd_generatechar(uint8_t code, const uint8_t *data)
{ //
190: 0f 93 push r16
192: 1f 93 push r17
194: cf 93 push r28
196: df 93 push r29
198: 8b 01 movw r16, r22
lcd_command(LCD_SET_CGADR|(code<<3)); // Startposition des Zeichens einstellen
19a: 88 0f add r24, r24
19c: 88 0f add r24, r24
19e: 88 0f add r24, r24
1a0: 80 64 ori r24, 0x40 ; 64
1a2: 0e 94 64 00 call 0xc8 ; 0xc8 <lcd_command>
1a6: c0 e0 ldi r28, 0x00 ; 0
1a8: d0 e0 ldi r29, 0x00 ; 0
for (uint8_t i=0; i<8; i++) // Bitmuster übertragen
{ //
lcd_data(data[i]); //
1aa: f8 01 movw r30, r16
1ac: ec 0f add r30, r28
1ae: fd 1f adc r31, r29
1b0: 80 81 ld r24, Z
1b2: 0e 94 68 00 call 0xd0 ; 0xd0 <lcd_data>
1b6: 21 96 adiw r28, 0x01 ; 1
// Schreibt ein Zeichen in den Character Generator RAM
// Daten liegen direkt im RAM
void lcd_generatechar(uint8_t code, const uint8_t *data)
{ //
lcd_command(LCD_SET_CGADR|(code<<3)); // Startposition des Zeichens einstellen
for (uint8_t i=0; i<8; i++) // Bitmuster übertragen
1b8: c8 30 cpi r28, 0x08 ; 8
1ba: d1 05 cpc r29, r1
1bc: b1 f7 brne .-20 ; 0x1aa <lcd_generatechar+0x1a>
{ //
lcd_data(data[i]); //
} //
} // Ende void lcd_generatechar(uint8_t code,
1be: df 91 pop r29
1c0: cf 91 pop r28
1c2: 1f 91 pop r17
1c4: 0f 91 pop r16
1c6: 08 95 ret
000001c8 <wms>:
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
{
uint16_t __c = 1600;
__asm__ volatile (
1c8: 20 e4 ldi r18, 0x40 ; 64
1ca: 36 e0 ldi r19, 0x06 ; 6
1cc: 04 c0 rjmp .+8 ; 0x1d6 <wms+0xe>
1ce: f9 01 movw r30, r18
1d0: 31 97 sbiw r30, 0x01 ; 1
1d2: f1 f7 brne .-4 ; 0x1d0 <wms+0x8>
// ================================================== =========================== =
// ================================================== =========================== =
//### Programm pausieren lassen !! Der Pausenwert ist nur experimentell !
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
1d4: 01 97 sbiw r24, 0x01 ; 1
1d6: 00 97 sbiw r24, 0x00 ; 0
1d8: d1 f7 brne .-12 ; 0x1ce <wms+0x6>
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}
1da: 08 95 ret
000001dc <main>:
// === HAUPTProgramm ================================================== ======== =
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(void) //
{ //
// - - - - - - - - - - - - - - -
DDRA = 0b00000000; // Alles auf Eingang mit (0)
1dc: 1a ba out 0x1a, r1 ; 26
PORTA = 0b11111111; // mit PullUp (1)
1de: 8f ef ldi r24, 0xFF ; 255
1e0: 8b bb out 0x1b, r24 ; 27
//
DDRB = 0b11111111; // Ausgänge mit (1)
1e2: 87 bb out 0x17, r24 ; 23
PORTB = 0b00000000; //
1e4: 18 ba out 0x18, r1 ; 24
//
DDRC = 0b11000000; //
1e6: 90 ec ldi r25, 0xC0 ; 192
1e8: 94 bb out 0x14, r25 ; 20
PORTC = 0b00111111; //
1ea: 9f e3 ldi r25, 0x3F ; 63
1ec: 95 bb out 0x15, r25 ; 21
//
DDRD = 0b00000000; //
1ee: 11 ba out 0x11, r1 ; 17
PORTD = 0b11111111; //
1f0: 82 bb out 0x12, r24 ; 18
1f2: 88 ee ldi r24, 0xE8 ; 232
1f4: 93 e0 ldi r25, 0x03 ; 3
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
{
uint16_t __c = 1600;
__asm__ volatile (
1f6: 20 e4 ldi r18, 0x40 ; 64
1f8: 36 e0 ldi r19, 0x06 ; 6
1fa: f9 01 movw r30, r18
1fc: 31 97 sbiw r30, 0x01 ; 1
1fe: f1 f7 brne .-4 ; 0x1fc <main+0x20>
// ================================================== =========================== =
// ================================================== =========================== =
//### Programm pausieren lassen !! Der Pausenwert ist nur experimentell !
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
200: 01 97 sbiw r24, 0x01 ; 1
202: d9 f7 brne .-10 ; 0x1fa <main+0x1e>
// NC (TasteC) SCK, PB7 NC Pin8 |___________________________
// GND Pin9
// Vcc Pn10 | Anmerkg: ENABLE line !
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
wms( 1000 ); // Wait
lcd_init(); //
204: 0e 94 7a 00 call 0xf4 ; 0xf4 <lcd_init>
208: 88 ee ldi r24, 0xE8 ; 232
20a: 93 e0 ldi r25, 0x03 ; 3
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
{
uint16_t __c = 1600;
__asm__ volatile (
20c: 20 e4 ldi r18, 0x40 ; 64
20e: 36 e0 ldi r19, 0x06 ; 6
210: f9 01 movw r30, r18
212: 31 97 sbiw r30, 0x01 ; 1
214: f1 f7 brne .-4 ; 0x212 <main+0x36>
// ================================================== =========================== =
// ================================================== =========================== =
//### Programm pausieren lassen !! Der Pausenwert ist nur experimentell !
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
216: 01 97 sbiw r24, 0x01 ; 1
218: d9 f7 brne .-10 ; 0x210 <main+0x34>
// Vcc Pn10 | Anmerkg: ENABLE line !
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
wms( 1000 ); // Wait
lcd_init(); //
wms( 1000 ); // Wait
lcd_clear(); // Vor LCD-Ausgabe Display leeren
21a: 0e 94 72 00 call 0xe4 ; 0xe4 <lcd_clear>
21e: 88 ee ldi r24, 0xE8 ; 232
220: 93 e0 ldi r25, 0x03 ; 3
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
{
uint16_t __c = 1600;
__asm__ volatile (
222: 20 e4 ldi r18, 0x40 ; 64
224: 36 e0 ldi r19, 0x06 ; 6
226: f9 01 movw r30, r18
228: 31 97 sbiw r30, 0x01 ; 1
22a: f1 f7 brne .-4 ; 0x228 <main+0x4c>
// ================================================== =========================== =
// ================================================== =========================== =
//### Programm pausieren lassen !! Der Pausenwert ist nur experimentell !
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
22c: 01 97 sbiw r24, 0x01 ; 1
22e: d9 f7 brne .-10 ; 0x226 <main+0x4a>
wms( 1000 ); // Wait
// - - - - - - - - - - - - - - -
//lcd_string("Grußoberallgeier");
//lcd_string("Gruss 18.9.19:23");
lcd_string("ABCDefghIJKLmnop");
230: 80 e6 ldi r24, 0x60 ; 96
232: 90 e0 ldi r25, 0x00 ; 0
234: 0e 94 bb 00 call 0x176 ; 0x176 <lcd_string>
238: 88 ee ldi r24, 0xE8 ; 232
23a: 93 e0 ldi r25, 0x03 ; 3
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
{
uint16_t __c = 1600;
__asm__ volatile (
23c: 20 e4 ldi r18, 0x40 ; 64
23e: 36 e0 ldi r19, 0x06 ; 6
240: f9 01 movw r30, r18
242: 31 97 sbiw r30, 0x01 ; 1
244: f1 f7 brne .-4 ; 0x242 <main+0x66>
// ================================================== =========================== =
// ================================================== =========================== =
//### Programm pausieren lassen !! Der Pausenwert ist nur experimentell !
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
246: 01 97 sbiw r24, 0x01 ; 1
248: d9 f7 brne .-10 ; 0x240 <main+0x64>
// - - - - - - - - - - - - - - -
//void wms(uint16_t ms) // Waitroutine
wms( 1000 ); // Wait
// - - - - - - - - - - - - - - -
Line2(); // An den Anfang der 2. Zeile springen
24a: 80 ec ldi r24, 0xC0 ; 192
24c: 0e 94 64 00 call 0xc8 ; 0xc8 <lcd_command>
lcd_string(" So gehts ;-) "); // Zeile löschen
250: 81 e7 ldi r24, 0x71 ; 113
252: 90 e0 ldi r25, 0x00 ; 0
254: 0e 94 bb 00 call 0x176 ; 0x176 <lcd_string>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
return 0; //
} //
258: 80 e0 ldi r24, 0x00 ; 0
25a: 90 e0 ldi r25, 0x00 ; 0
25c: 08 95 ret
0000025e <lcd_eep_string>:
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//String aus EEPROM laden und an LCD senden
void lcd_eep_string(const unsigned char *data)
{ //
25e: cf 93 push r28
260: df 93 push r29
262: ec 01 movw r28, r24
unsigned char c;
while(1) //
{ //
c = eeprom_read_byte(data); //
264: ce 01 movw r24, r28
266: 0e 94 3e 01 call 0x27c ; 0x27c <__eerd_byte_m32>
if(c==0) return; //
26a: 88 23 and r24, r24
26c: 21 f0 breq .+8 ; 0x276 <lcd_eep_string+0x18>
lcd_data(c); //
26e: 0e 94 68 00 call 0xd0 ; 0xd0 <lcd_data>
data++; //
272: 21 96 adiw r28, 0x01 ; 1
274: f7 cf rjmp .-18 ; 0x264 <lcd_eep_string+0x6>
}
} // Ende void lcd_eep_string(const
276: df 91 pop r29
278: cf 91 pop r28
27a: 08 95 ret
0000027c <__eerd_byte_m32>:
27c: e1 99 sbic 0x1c, 1 ; 28
27e: fe cf rjmp .-4 ; 0x27c <__eerd_byte_m32>
280: 9f bb out 0x1f, r25 ; 31
282: 8e bb out 0x1e, r24 ; 30
284: e0 9a sbi 0x1c, 0 ; 28
286: 99 27 eor r25, r25
288: 8d b3 in r24, 0x1d ; 29
28a: 08 95 ret
0000028c <_exit>:
28c: f8 94 cli
0000028e <__stop_program>:
28e: ff cf rjmp .-2 ; 0x28e <__stop_program>
Ach so - noch eben das Mainmodul dazu:
/* >>
Stand ..\C3\tstu\tstu_mega32.c
================================================== ============================= =
*** Aufgabenstellung : LCD auf Port B !!! des mega644/8 MHz int. Osc.
================================================== ============================ */
#define F_CPU 1e6
// - - - - - - - - - - - - - - - -
#include <lcd_162_xta.c> // LCD-Lib ähnlich Tr-Tester, akt. PORTB, PB0..7
//#include <lcd_162_mini-no-wait.c> // LCD-Lib ähnl Tr-Tester, PORTB, PB0..7
// ================================================== =========================== =
// ================================================== =========================== =
// ================================================== =========================== =
//### Programm pausieren lassen !! Der Pausenwert ist nur experimentell !
void wms(uint16_t ms) //
{
for(; ms>0; ms--)
{
uint16_t __c = 1600;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}
// ================================================== =========================== =
// ================================================== =========================== =
// === HAUPTProgramm ================================================== ======== =
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(void) //
{ //
// - - - - - - - - - - - - - - -
DDRA = 0b00000000; // Alles auf Eingang mit (0)
PORTA = 0b11111111; // mit PullUp (1)
//
DDRB = 0b11111111; // Ausgänge mit (1)
PORTB = 0b00000000; //
//
DDRC = 0b11000000; //
PORTC = 0b00111111; //
//
DDRD = 0b00000000; //
PORTD = 0b11111111; //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - -
// ####>>>> Initialisierung/Anschlüsse von PORT B für LCD DEM 16x2
// data bit 4 PB0 0 A WS Pin1 |
// data bit 5 PB1 1 A Pin2 | -- Der 10-polige Wannenstecker
// data bit 6 PB2 2 A Pin3 | ist an die Belegung
// data bit 7 SCK, PB3 3 A Pin4 | des Transitortester angepasst
// RS line PB4 RS Pin5 | es kommen noch
// ENABLE line MOSI, PB5 EN1 Pin6 | Pin 9 GND und
// R/W (offen) MISO, PB6 R/W Pin7 | Pin 10 Vcc dazu
// NC (TasteC) SCK, PB7 NC Pin8 |___________________________
// GND Pin9
// Vcc Pn10 | Anmerkg: ENABLE line !
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
wms( 1000 ); // Wait
lcd_init(); //
wms( 1000 ); // Wait
lcd_clear(); // Vor LCD-Ausgabe Display leeren
// - - - - - - - - - - - - - - -
wms( 1000 ); // Wait
// - - - - - - - - - - - - - - -
lcd_string("ABCDefghIJKLmnop");
// - - - - - - - - - - - - - - -
//void wms(uint16_t ms) // Waitroutine
wms( 1000 ); // Wait
// - - - - - - - - - - - - - - -
Line2(); // An den Anfang der 2. Zeile springen
lcd_string(" So gehts ;-) "); // Zeile löschen
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
return 0; //
} //
// ===== Ende des Testabschnittes, er kann aus mehreren Abschnitten bestehen ====
// ================================================== =============================
/* Übersetzungskommentar (tstu) Programsize Datasize
Build 20.1.2014 at 11:50:13 11224 bytes (34.3% Full) 1960 bytes (95.7% Full)
================================================== ========== */
oberallgeier
12.02.2015, 10:49
Hallo Rolf!
... mir raucht der Kopf! ...
// muß ich doch vor einem Kommentar setzen.
Aber was ist das denn..//#include <lcd_162_mini-no-wait.c> auch ein Kommentar?
Rauchen ist beim Kopf zulässig, beim IC bedeutet es meist nix Gutes.
Doppel-Schrägstrich beginnt einen Kommentar bis zum Zeilenende - auch wenns im Prinzip Code ist.
/* (Schrägstrich Stern) beginnt einen Kommentar - der kann mehrzeilig sein und wird mit */ beendet.
A) Bitte schreibe das nächste Mal Deinen Code ins Codefenster. Das bekommst Du im Editor mit dem Button [#] - wenn Du den nicht siehst, dann drücke bitte auf "Erweiterte Ansicht". Im Editor sieht das dann so aus: [.CODE][./CODE] . Im Editor steht aber kein Leerzeichen nach der ersten Klammer. Und das Fenster ist dann erstmal leer. Nun die Schreibweise mit "nix" zwischen [ und C bzw. [ und /:
.Dieses Beispiel ist tricky, funktioniert "normalerweise" nicht *gggg*.
B) Schau mal nach meinem Posting vom 09.02.2015, 14:34, bei "main Modul".
Bei Dir könnte das etwa so aussehen:
// Jetzt fängt der Code an mit Einschluss von Bibliotheken und
// Definitionen
#include <avr/io.h>
#include <util/delay.h> // Hier ist eine "Wartefunktion" enthalten
#define Takt 1000000 // Systemtakt 1 MHz intern
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void main (void) // Hauptfunktion, was ist das?
// Das ist das eigentliche Hauptprogramm,
// die Unterprogramme müssen vorher schon
// geschrieben sein oder includierte werden
// siehe dazu z.B. die o.g. Bibliotheken io.h etc
// - - - - - - - - - - - - - - - -
// Nun werden mal die Ports konfiguriert
// Ports+Pins als Ein- (0) od. Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren
// - - - - - - - - - - - - - - - -
DDRA = 0b00000000; // Alle Pins auf Eingang
PORTA = 0b11100101; // Pinn 0, 2 sowie fünf bis sieben mit Pullup
//
DDRB = 0b11111111; // Alle Pins auf Ausgang
PORTB = 0b00001111; // Pinn 0-3 high => LEDs an, 4-7 auf low => LEDs aus
//
DDRC = 0b00111111; // Pinn 0-5 auf Ausgang, 2 Eingänge
PORTC = 0b11000000; // Ausgänge 0-4 auf low, 5 auf high, PullUp für 6+7
//
DDRD = 0b00000000; // Alles Eingänge
PORTD = 0b00001111; // Pullups einschalten (Schalter schaltet gegen GND)
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Wir bewundern mal die LEDs - an oder aus
_delay_ms( 1000); // ... ne ganze Sekunde
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
for ( uint8_t i=0; i< 100; i++) // LEDs 100 mal blinken lassen
{ // Schleifenanfang
// - - - - - - - - - - - -
PORTB |= (1<<PB6}; // LED auf PB6 einschalten
PORTB &= ~(1<<PB1); // LED auf PB1 ausschalten
_delay_ms( 500); // Nun warten wir ne halbe Sekunde (LED bewundern)
PORTB &= ~(1<<PB6}; // LED auf PB6 ausschalten
PORTB |= (1<<PB1); // LED auf PB1 einschalten
_delay_ms( 500); // Nun warten wir ne halbe Sekunde (LED bewundern)
} // Ende von for ( uint8_t i=0; i< 100; i++)
// - - - - - - - - - - - -
return 0; // Ende des Programms
/* und zum Schluss noch ein mehrzeiliger Kommentar:
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse ...
*/
Wenn ich ausreichend gefrühstückt habe müsstesollte das funktionieren. Ohne Tastendruck und nur hundert Blinkies.
C sollte man eigentlich anhand eines Buches oder eines der verfügbaren Tutorials auf einem PC lernen. Da liefert einem der Rechner alles, was man braucht: die Tastatur als Input, den Bildschirm als Output sowie Tools, wie einen Debugger, ohne Ende. Unter Linux sind die erforderlichen Programme sowieso frei und unter Windows gibt es Visual Studio Express ebenfalls kostenlos. Da gibt es dann online Syntax-Checks, Single Step, die komplette Sicht auf alle Variablen und eine Menge andere Hilfe. Wenn man dann mit der Sprache einigermaßen klar kommt, kann man auf (irgend)einen µC umsteigen.
Und man sollte garnicht erst versuchen, die Sichtweise des Assenblerprogrammierers auf den Rechner in C nachzuvollziehen. Und sich von Prozessorregistern, Carryflag oder Stackpointer zu lösen, gelingt einem leichter auf einem PC. Danach spielt es dann auch keine Rolle mehr, ob man für AVR, PIC, ARM oder X86 programmiert.
Hallo Rolf, natürlich gabs in Assembler nicht die vielen kryptischen Zeichen
Aber selbstverständlich gibt es die, eher noch mehr. Und natürlich kann jeder Assembler Zahlen in jeder nur denkbaren Schreibweise verarbeiten, von binär bis oktal und natürlich auch als ASCII Zeichen. Dafür schleppt er aber das alte Fortran-Lochkartenformat mit sich rum, und es hat ziemlich lange gedauert, bis Labels mit mehr als 8 Zeichen zulässig waren. Und moderne Assembler benutzen sogar den C-Präprozessor weils einfach praktisch ist.
MfG Klebwax
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.