Đầu tiên một số nền. Trong một avr nhỏ, dữ liệu có thể được lưu trữ trong sổ đăng ký, trong sram, trong eeprom hoặc trong không gian chương trình. Đăng ký và sram là lưu trữ dễ bay hơi trong khi không gian eeprom và chương trình thì không. (Ví dụ:. Dữ liệu nghỉ khi không được hỗ trợ)Trong một avr nhỏ, làm thế nào là dữ liệu có nghĩa là để được lưu trữ trong sram khởi tạo khi vi điều khiển được cấp nguồn?
Khi lập trình trong c (sử dụng các thư viện avr-gcc), một mã điển hình có thể trông giống như:
#define F_CPU 8000000UL
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//This data is put in the eeprom
const uint8_t dat_eeprom EEMEM= 0xab;
//This data is put in the program space
const uint8_t dat_pgm_space PROGMEM= 0xcd;
//This data is stored in the sram
uint8_t dat_sram = 0xef;
int main(){
while(1){
;;
}
}
Biên soạn với:
avr-gcc -g -mmcu=attiny44 -o test.elf test.c
Và giải nén một hex intel từ elf:
avr-objcopy -j .text -j .data -O ihex test.elf test.hex
Chúng tôi nhận được test.hex sau:
:1000000011C023C022C021C020C01FC01EC01DC0FF
:100010001CC01BC01AC019C018C017C016C015C01C
:1000200014C0CD0011241FBECFE5D1E0DEBFCDBF8F
:1000300010E0A0E6B0E0EAE5F0E002C005900D9225
:10004000A236B107D9F702D006C0DACFCF93DF933B
:0A005000CDB7DEB7FFCFF894FFCF65
:02005A00EF00B5
:00000001FF
Và sau dissassembly:
00000000 <.sec1>:
0: 11 c0 rjmp .+34 ; 0x24
<...skipped interrupt vector table...>
20: 14 c0 rjmp .+40 ; 0x4a
22: cd 00 .word 0x00cd ; this is our data stored in the program mem.
24: 11 24 eor r1, r1
26: 1f be out 0x3f, r1 ; 63
28: cf e5 ldi r28, 0x5F ; 95
2a: d1 e0 ldi r29, 0x01 ; 1
2c: de bf out 0x3e, r29 ; 62
2e: cd bf out 0x3d, r28 ; 61
30: 10 e0 ldi r17, 0x00 ; 0
32: a0 e6 ldi r26, 0x60 ; X register low byte ; address of dest. in
34: b0 e0 ldi r27, 0x00 ; X register high byte; sram
36: ea e5 ldi r30, 0x5A ; z register low byte ; address of data in
38: f0 e0 ldi r31, 0x00 ; z register high byte; program memory
3a: 02 c0 rjmp .+4 ; 0x40
3c: 05 90 lpm r0, Z+
3e: 0d 92 st X+, r0
40: a2 36 cpi r26, 0x62 ; 98
42: b1 07 cpc r27, r17
44: d9 f7 brne .-10 ; 0x3c
<...skipped rcall to main...>
5a: ef 00 .word 0x00ef ; this is our data that
should be stored in the sram.
Vậy làm thế nào là dữ liệu (0xef) mà chúng ta muốn đưa vào SRAM khởi tạo?
Câu trả lời là thông qua một thói quen trước khi chính.
Dữ liệu sẽ được lưu trữ trong SRAM tại địa chỉ 0x5a, trong không gian chương trình. Nó được đặt trong sram theo cách sau:
- Ký hiệu x cao và thấp được đặt thành địa chỉ nơi chúng tôi muốn đưa dữ liệu vào SRAM. (0x60) lưu ý rằng địa chỉ này không trong bộ nhớ chương trình nhưng trong bộ nhớ dữ liệu.
- Tương tự cho thanh ghi z, nhưng với địa chỉ nơi dữ liệu nằm trong không gian chương trình (0x5a)
- nội dung của bộ nhớ chương trình tại địa chỉ được lưu trữ trong thanh ghi z được nạp vào thanh ghi r0 qua lpm opcode. Lưu ý rằng giá trị đăng ký z được tăng lên để trỏ vào dữ liệu tiếp theo (cuối cùng, không có ở đây) để tải vào sram.
- dữ liệu trong r0 sau đó được lưu trữ trong sram tại địa chỉ được lưu trữ trong thanh ghi x.
- Lặp lại cho đến khi tất cả dữ liệu phải ở dạng sram đã được khởi tạo.
Điều này xảy ra trước khi diễn ra cuộc gọi chính.
Có câu trả lời tốt hơn/rõ ràng hơn không?
Vâng, bây giờ điều đó hiển nhiên đối với tôi, nhưng tôi đã dành một chút thời gian để tìm ra lý do dữ liệu tôi muốn trong SRAM ở cuối .hex. Hy vọng nó sẽ giúp ai đó. – user1443332