Возник следующий вопрос - как в на асме прочитать байтик из памяти программ? Покопавшись в просторах интернета нашёл следующее:
CODE
ldi ZH, hi8(pm(F64_cos))
ldi ZL, lo8(pm(F64_cos))
lpm r18, Z
F64_cos - таблица значений косинуса. Но чёт это не работает. Код в AVR stidio 4 помнется выглядит примерно так:
CODE
ldi ZH, high(F64_cos*2)
ldi ZL, low(F64_cos*2)
lpm r18, Z
Т.е. в AVR stidio 4 нужно делать сдвиг в лево, что равно умножению на 2. Почитав доки на avr-gcc нашёл что макрос pm надо использовать если нужен доступ к памяти программ, но он равносилен деления на 2 или, что тоже самое, сдвигу на 1 в право. На этом моменте у меня сразу возникло не понимание принципа доступа к памяти программ на ассемблере в avr-gcc.
Может кто в курсе как делается правильно?
Вот весь код на асме, который написал:
CODE
#include "../Headers/asm_ftransform.h"
#include <avr/io.h>
.extern FsummRe // == r9, r8, r7, r6
.extern FsummIM // == r13, r12, r11, r10
.extern CurVal // == r5
.extern Flags
.extern FsinTable
.extern FcosTable
.extern F64_cos
.global DMA_CH0_vect
DMA_CH0_vect:
push r0
push r1
push ZL
push ZH
push r17
push r18
push r19
/* load Sin and Cos */
// calc offset
ldi r17, 0x35
//mul r5, r17 // r1:r0 - offset
// sin addres
ldi ZH, hi8(pm(F64_cos))
ldi ZL, lo8(pm(F64_cos))
//add r16, r0
//adc r17, r1
lpm r18, Z
sts _SFR_IO_ADDR(USARTE0_DATA), r18
// DMA.CH0.CTRLB |= 48; // clear interrupt flags
ldi r26, 0x30
sts _SFR_IO_ADDR(DMA_CH0_CTRLB), r26
// stop ADC
clr r17
sts _SFR_IO_ADDR(ADCA_CTRLA), r17
ldi r17, 2
sts Flags, r17
pop r19
pop r18
pop r17
pop ZH
pop ZL
pop r1
pop r0
reti
Нашел в чём проблема, мой косяк, F64_cos была в ОЗУ. И собственно чтоб прочитать из памяти программ нужно:
ldi ZH, hi8(F64_cos)
ldi ZL, lo8(F64_cos)
lpm r18, Z
без всяких макросов pm().
И новый вопрос: я правильно понимаю, макрос pm() используется для вызова подпрограмм, например:
ldi ZH, hi8(pm(s_func))
ldi ZL, lo8(pm(s_func))
call Z
так?