AVR C编程:代码不工作(端口引脚不会切换)因为函数在主函数外声明。

huangapple go评论69阅读模式
英文:

AVR C programming: Code Doesn't Work (port pin won't toggled) Because Function Declared Outside of Main Function

问题

I see your code examples and hex code. If you have any specific questions or need assistance with anything related to these code snippets, please let me know, and I'll do my best to help.

英文:

I tried to programmed my arduino using avr-gcc, as you can see i tried to make a function:

#include <avr/io.h>
#include <util/delay.h>

#define ddr (uint8_t*) 0x24
#define port (uint8_t*) 0x25

//func
void blink(uint8_t* DIRECT,uint8_t* PORT,uint8_t val){
 *DIRECT=val;

while(1){
 *PORT=val;
 _delay_ms(1000);
 *PORT=0x0;
 _delay_ms(1000);
}

}

int main(void){
   
 uint8_t* DIRECT=ddr;
 uint8_t* PORT=port;
 blink(ddr,port,0x10);
 return 0;
}

somehow the code only works when the 'blink' function declared inside of the main function.
im using avr-gcc on black arch linux, the compilation process doesnt give any error messages, im using arduino uno board with mcu atmega328p

this is the bash script:

#!/bin/bash

avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o led_func.o led_func.c

avr-gcc -o led_func.bin led_func.o

avr-objcopy -O ihex -R .eeprom led_func.bin led_func.hex

avrdude -F -V -c arduino -p atmega328p -P /dev/ttyACM0 -b 115200 -U flash:w:led_func.hex

i thought it's not normal to declare function inside the main() in c programs base on my experience using c language, but maybe it's different on avr ?

this is the equivalent of the code above with the same problems:

#include <avr/io.h>
#include <util/delay.h>
        
volatile int noob(){return 0;}
        
int main(){
//DDRB-->PORTB5
DDRB=0x10;
        
        
for(;;){
PORTB=0x10;
_delay_ms(1000);
PORTB=0x0;
_delay_ms(1000);
}
PORTB=0;
noob();
//return 0;
}

this is the hex code for the first code:

:10000000CF93DF930F92CDB7DEB7DC01FB014983BD
:1000100089818C93898180830F90DF91CF9108959E
:0C00200080E184B985B980E090E008958B
:00000001FF

this is the hex code for the last code:

:1000000080E184B985B92FEF33ED90E32150304082
:100010009040E1F700C0000015B82FEF33ED90E3FA
:0E002000215030409040E1F700C00000EBCFCF
:00000001FF

答案1

得分: 1

Here is the translation of the provided text:

我反编译了两个十六进制文件。两者都很奇怪。

第一个代码:
这段代码不能正常工作。我认为它只是一个已编译但未链接完成的模块。

第二个代码:
这段代码在R1寄存器为0的情况下可以工作。但R1寄存器未初始化。是否缺少初始化部分?我不知道,也许需要调用链接器。

我的第一个代码的结果是由AVR Studio使用avr-gcc 5.4.0在Windows上汇编的:
这段代码将正常工作。当然,中断向量表可以省略。栈指针初始化也可以省略。但地址0x68上的指令必须保留,因为它清除寄存器R1,然后在主函数中使用。

调用的命令:
(以下是一系列编译和链接命令的输出)

Please note that the translation provided above corresponds to the text segments without code and command invocations. If you have any specific questions or need further assistance, please let me know.

英文:

I decompiled both hex files. Both are weird.

first code:

   0:   cf 93           push    r28
   2:   df 93           push    r29
   4:   0f 92           push    r0
   6:   cd b7           in      r28, 0x3d       ; 61
   8:   de b7           in      r29, 0x3e       ; 62
   a:   dc 01           movw    r26, r24
   c:   fb 01           movw    r30, r22
   e:   49 83           std     Y+1, r20        ; 0x01
  10:   89 81           ldd     r24, Y+1        ; 0x01
  12:   8c 93           st      X, r24
  14:   89 81           ldd     r24, Y+1        ; 0x01
  16:   80 83           st      Z, r24
  18:   0f 90           pop     r0
  1a:   df 91           pop     r29
  1c:   cf 91           pop     r28
  1e:   08 95           ret
  20:   80 e1           ldi     r24, 0x10       ; 16
  22:   84 b9           out     0x04, r24       ; 4
  24:   85 b9           out     0x05, r24       ; 5
  26:   80 e0           ldi     r24, 0x00       ; 0
  28:   90 e0           ldi     r25, 0x00       ; 0
  2a:   08 95           ret

This code cannot work. I think it is only compiled module not linked to finish code.

Second code:

   0:   80 e1           ldi     r24, 0x10       ; 16
   2:   84 b9           out     0x04, r24       ; 4
   4:   85 b9           out     0x05, r24       ; 5
   6:   2f ef           ldi     r18, 0xFF       ; 255
   8:   33 ed           ldi     r19, 0xD3       ; 211
   a:   90 e3           ldi     r25, 0x30       ; 48
   c:   21 50           subi    r18, 0x01       ; 1
   e:   30 40           sbci    r19, 0x00       ; 0
  10:   90 40           sbci    r25, 0x00       ; 0
  12:   e1 f7           brne    .-8             ;  0xc
  14:   00 c0           rjmp    .+0             ;  0x16
  16:   00 00           nop
  18:   15 b8           out     0x05, r1        ; 5
  1a:   2f ef           ldi     r18, 0xFF       ; 255
  1c:   33 ed           ldi     r19, 0xD3       ; 211
  1e:   90 e3           ldi     r25, 0x30       ; 48
  20:   21 50           subi    r18, 0x01       ; 1
  22:   30 40           sbci    r19, 0x00       ; 0
  24:   90 40           sbci    r25, 0x00       ; 0
  26:   e1 f7           brne    .-8             ;  0x20
  28:   00 c0           rjmp    .+0             ;  0x2a
  2a:   00 00           nop
  2c:   eb cf           rjmp    .-42            ;  0x4

This code can work if R1 register is 0. But it is not initialized. Missing init section ?? I don't know maybe the linker need to be called

My result of first code assembled by AVR studio with avr-gcc 5.4.0 on windows:

Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 34 00 	jmp	0x68	; 0x68 <__ctors_end>
   4:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
   8:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
   c:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  10:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  14:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  18:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  1c:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  20:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  24:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  28:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  2c:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  30:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  34:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  38:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  3c:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  40:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  44:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  48:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  4c:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  50:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  54:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  58:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  5c:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  60:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>
  64:	0c 94 3e 00 	jmp	0x7c	; 0x7c <__bad_interrupt>

00000068 <__ctors_end>:
  68:	11 24       	eor	r1, r1
  6a:	1f be       	out	0x3f, r1	; 63
  6c:	cf ef       	ldi	r28, 0xFF	; 255
  6e:	d8 e0       	ldi	r29, 0x08	; 8
  70:	de bf       	out	0x3e, r29	; 62
  72:	cd bf       	out	0x3d, r28	; 61
  74:	0e 94 40 00 	call	0x80	; 0x80 <main>
  78:	0c 94 57 00 	jmp	0xae	; 0xae <_exit>

0000007c <__bad_interrupt>:
  7c:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

00000080 <main>:
  80:	80 e1       	ldi	r24, 0x10	; 16
  82:	84 b9       	out	0x04, r24	; 4
  84:	85 b9       	out	0x05, r24	; 5
  86:	2f e3       	ldi	r18, 0x3F	; 63
  88:	3d e0       	ldi	r19, 0x0D	; 13
  8a:	93 e0       	ldi	r25, 0x03	; 3
  8c:	21 50       	subi	r18, 0x01	; 1
  8e:	30 40       	sbci	r19, 0x00	; 0
  90:	90 40       	sbci	r25, 0x00	; 0
  92:	e1 f7       	brne	.-8      	; 0x8c <main+0xc>
  94:	00 c0       	rjmp	.+0      	; 0x96 <main+0x16>
  96:	00 00       	nop
  98:	15 b8       	out	0x05, r1	; 5
  9a:	2f e3       	ldi	r18, 0x3F	; 63
  9c:	3d e0       	ldi	r19, 0x0D	; 13
  9e:	93 e0       	ldi	r25, 0x03	; 3
  a0:	21 50       	subi	r18, 0x01	; 1
  a2:	30 40       	sbci	r19, 0x00	; 0
  a4:	90 40       	sbci	r25, 0x00	; 0
  a6:	e1 f7       	brne	.-8      	; 0xa0 <main+0x20>
  a8:	00 c0       	rjmp	.+0      	; 0xaa <main+0x2a>
  aa:	00 00       	nop
  ac:	eb cf       	rjmp	.-42     	; 0x84 <main+0x4>

000000ae <_exit>:
  ae:	f8 94       	cli

000000b0 <__stop_program>:
  b0:	ff cf       	rjmp	.-2      	; 0xb0 <__stop_program>

This code will work correctly. Of course interrupt vector table can be omitted. Also stack pointer initialization can be omitted. But instruction on address 0x68 must stay because clear register R1 then used in main.

Invoked commands:

		"C:\Program Files (x86)\Atmel\Studio.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe"  -x c -funsigned-char -funsigned-bitfields -DNDEBUG  -I"C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\ATmega_DFP.3.300\include"  -Os -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -mmcu=atmega328p -B "C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\ATmega_DFP.3.300\gcc\dev\atmega328p" -c -std=gnu99 -MD -MP -MF "main.d" -MT"main.d" -MT"main.o"   -o "main.o" ".././main.c" 
		Finished building: .././main.c
		Building target: GccApplication1.elf
		Invoking: AVR/GNU Linker : 5.4.0
		"C:\Program Files (x86)\Atmel\Studio.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -o GccApplication1.elf  main.o   -Wl,-Map="GccApplication1.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -mmcu=atmega328p -B "C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\ATmega_DFP.3.300\gcc\dev\atmega328p"  
		Finished building target: GccApplication1.elf
		"C:\Program Files (x86)\Atmel\Studio.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "GccApplication1.elf" "GccApplication1.hex"
		"C:\Program Files (x86)\Atmel\Studio.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom  --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0  --no-change-warnings -O ihex "GccApplication1.elf" "GccApplication1.eep" || exit 0
		"C:\Program Files (x86)\Atmel\Studio.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "GccApplication1.elf" > "GccApplication1.lss"
		"C:\Program Files (x86)\Atmel\Studio.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "GccApplication1.elf" "GccApplication1.srec"

huangapple
  • 本文由 发表于 2023年7月18日 09:25:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76708999.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定