AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
02.02.2018, 15:31
|
|
Вид на жительство
Регистрация: 29.03.2009
Адрес: Бровары, Украина
Сообщений: 326
Сказал спасибо: 1,409
Сказали Спасибо 82 раз(а) в 46 сообщении(ях)
|
Atmel studio, как правильно таскать данные с flash памяти?
Добрый день,
когда - то сделал себе DDS генератор на меге 16, в среде WinAVR. Все хорошо работает. описания полно в сети.
вот главная процедура:
Код:
|
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{
asm volatile( "eor r18, r18 ;r18‹-0" "\n\t"
"eor r19, r19 ;r19‹-0" "\n\t"
"1:" "\n\t"
"add r18, %[BtL] ;1 cycle" "\n\t"
"adc r19, %[BtM] ;1 cycle" "\n\t"
"adc %A[Adr], %[BtH] ;1 cycle" "\n\t"
"lpm ;3 cycles" "\n\t"
"out %[Out], __tmp_reg__ ;1 cycle" "\n\t"
"sbis %[Add], 2 ;1 cycle if no skip" "\n\t"
"rjmp 1b ;2 cycles. Total 10 cycles" "\n\t"
:
:[BtL] "r" (ad0), [BtM] "r" (ad1), [BtH] "r" (ad2), [Adr] "e" (signal), [Out] "I" (_SFR_IO_ADDR(PORTA)), [Add] "I" (_SFR_IO_ADDR(SPCR))
:"r18", "r19"
);
} |
Которая вызывается вот так:
Код:
|
Signal_OUT(SIGNALS[SG.mode],
(uint8_t)((uint32_t)SG.acc››16),
(uint8_t)((uint32_t)SG.acc››8),
(uint8_t)SG.acc); |
signals - это набор кривых
Код:
|
const uint8_t *SIGNALS[] =
{
Sinewave,
Meandr25,
Meandr50,
Meandr75,
Triangle,
SawTooth,
RevSawTooth,
ECG,
Siski
}; |
каждая из 9-и кривых объявлена таким макаром:
Код:
|
const uint8_t Sinewave[] __attribute__ ((section (".MySection1"))) = //sine 256 values
{
Т256 значений
}; |
с номерами MySection от 1 до 9
В makefile прописаны адреса секций
Код:
|
#Define sections where to store signal tables
LDFLAGS += -Wl,-section-start=.MySection1=0x3700
LDFLAGS += -Wl,-section-start=.MySection2=0x3800
LDFLAGS += -Wl,-section-start=.MySection3=0x3900
LDFLAGS += -Wl,-section-start=.MySection4=0x3A00
LDFLAGS += -Wl,-section-start=.MySection5=0x3B00
LDFLAGS += -Wl,-section-start=.MySection6=0x3C00
LDFLAGS += -Wl,-section-start=.MySection7=0x3D00
LDFLAGS += -Wl,-section-start=.MySection8=0x3E00
LDFLAGS += -Wl,-section-start=.MySection9=0x3F00 |
Все это работает отлично.
Сегодня захотел покрутить этот генератор в атмел студио.
Просто скопированный код заработал, но процедура DDS цепляет данные с масивов других кривых, т.е. в синусе есть врагменты прямоугольника, а в прямоугольнике - треугольника.
Пробовал в свойствах проекта включить внешний makefile - компилятор дал ошибку.
пробовал явно указать области памяти таким образом:
Код:
|
const uint8_t Sinewave[] __attribute__ ((section ("0x3700"))) = //sine 256 values
{
массив синуса
};
const uint8_t Meandr25[] __attribute__ ((section ("0x3800"))) = //Meandr 25% 256 values
{
массив меандра с 25% заполнением
}; |
Тоже не помогло, синус загажывается данными с масива для меандра.
Как правильно объявить массивы кривых в памяти?
Последний раз редактировалось -vitalik-; 02.02.2018 в 15:36.
|
|
|
|
05.02.2018, 18:27
|
|
Вид на жительство
Регистрация: 29.03.2009
Адрес: Бровары, Украина
Сообщений: 326
Сказал спасибо: 1,409
Сказали Спасибо 82 раз(а) в 46 сообщении(ях)
|
Re: Atmel studio, как правильно таскать данные с flash памяти?
дополнение:
все масивы кривых загоняются в память программ
Код:
|
const uint8_t Sinewave[] __attribute__ ((progmem)) = //sine 256 values
{
256 елементов
}; |
в откомпилированом hex-файле - их отлично видно. Но масивы размещены в обратном порядке.
Набор указателей на массивы выглядит так:
Код:
|
const uint8_t *SIGNALS[] =
{
Sinewave,
Meandr25,
Meandr50,
Meandr75,
Triangle,
SawTooth,
RevSawTooth,
ECG,
Siski
}; |
При запуске генерации - данные выбираются со смещением.
при попытке указать "const uint8_t *SIGNALS[] PROGMEM =" - компилятор ругается "Error 1 variable 'SIGNALS' must be const in order to be put into read-only section by means of '__attribute__((progmem))' "
Как решить проблему?
|
|
|
|
07.02.2018, 15:25
|
|
Вид на жительство
Регистрация: 29.03.2009
Адрес: Бровары, Украина
Сообщений: 326
Сказал спасибо: 1,409
Сказали Спасибо 82 раз(а) в 46 сообщении(ях)
|
Re: Atmel studio, как правильно таскать данные с flash памяти?
Проблема решена.
Начальные элементы масивов программа брала с адресов, кратных :хххх0000. В распечатке hex файла отлично было видно, как c :100B0000 начиналось считывание, а это была середина масива меандра. Сразу за ним - шел масив синуса. И при генерации синуса - хваталась вторая половина для меандра и первая половина для синуса.
Как заставить компилятор запхнуть масивы так, что бы начала их ложились в нужные адреса - я не знаю.
Поэтому было решено в лоб - сместить масивы в памяти, путем добавления мусора в hex. Три десятка байт - хватило для счастья. Не жалко, ибо у атмеги их аж 16к.
Цель достигнута, данные считываются корректно.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 01:50.
|
|