|
WinAVR: Как правильно размещать и работать с таблицами данных во Flash (памяти программ) ?, Не читает данные из Flash-памяти! |
|
|
|
Dec 7 2011, 17:58
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Доброго времяни суток! Видимо опять столкнулся с кривизной WinAVR Пример: нужно читать данные из памяти программ, и задействовать из в программе. Чтобы небыло лишних вопросов привожу весь текст программы: Код #include <avr/io.h> #include <avr/interrupt.h> // задает макросы sei() , cli() #include <inttypes.h> #include <avr/pgmspace.h>
uint8_t Cnt1;// фоновый счетчик длительности переключения свдиода volatile int16_t *p;// указатель
volatile register struct { uint8_t bOne : 1; uint8_t bTwo : 1; uint8_t bThree : 1; uint8_t bFour : 1; } RF asm ("r17");
#define sbi(p,b) (p |= (1<<b)) //Установить бит
#define DIRB 0b00010001 #define PUPB 0b00000111 #define Led PB0 /* линия светодиода ("1" - вкл. ч/з резистор на общ.) */
//;---------------------------------------------------------------------------------------------------------------------------------------- //Определение констант:
#define Vl_DBKCnt 101 #define Vl_FLCnt 5
const uint8_t a[] PROGMEM={22,15,233,40,69,39,203,2,1};
//===================================================================== ISR( TIM0_COMPA_vect) { if (!(--Cnt1)) { RF.bOne=0; sbi (PINB,Led);// ________ Переключение свдиода ! } }
//_______________ПОДПРОГРАММЫ_________________ void init (void) { PORTB=PUPB; //иницализация порта B DDRB=DIRB; // задание направления для порта B TIMSK0=(1<<OCIE0A); /* установка разр. прер-ия по совпадению т/сч.0 с регистром OCR0A */ OCR0A=234; //загрузка регистра совпадения OCR0A коэф. деления TCCR0A= (1<<WGM01); //установка режима СТС - обнуление Т/С0 при совпадении с регистром OCR0A TCCR0B=(1<<CS02)|(1<<CS00); // <---- конфигурация и запуск сч-ка в реж. СТС с предделителем ckl/1024 RF.bOne=0; Cnt1=100; //задание начальных значений для счетчиков
p=&a; // Установка указателя на начало таблицы a }
//============================================================================= int main (void) { //_________________________ ИНИЦИАЛИЗАЦИЯ _____________________________ uint16_t temp;
init(); sei ();// Разрешение общего прерывания while (1) { if (RF.bOne==0) { RF.bOne=1; temp=*p; Cnt1=(uint8_t)temp; ++p; } } } После использования команды PROGMEM в задании таблицы из программы удалилась секция где массив копировался в ОЗУ, что собственно и требовалось. Но обращение к таблице не поменялось. Вопрос вызывает только место: Код temp=*p; a6: 81 91 ld r24, Z+ a8: 91 91 ld r25, Z+ Cnt1=(uint8_t)temp; aa: 80 93 62 00 sts 0x0062, r24 Читает неизвестно откуда , только не из программы! Как прочитать данные из программы?
|
|
|
|
|
 |
Ответов
|
Dec 9 2011, 12:06
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Код #include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include <avr/pgmspace.h>
//===================================================================== uint8_t Cnt1;// фоновый счетчик длительности переключения свдиода uint16_t *p;
volatile register struct { uint8_t bOne : 1; uint8_t bTwo : 1; uint8_t bThree : 1; uint8_t bFour : 1; } RF asm ("r17");
#define sbi(p,b) (p |= (1<<b)) //Установить бит
#define DIRB 0b00010001 #define PUPB 0b00000111
//;------------------------------------------------------------------------------- //Определение контактов #define Control1 PB4 /* линия управления VT (1 - откр; 0 - закр ) */ #define Led PB0 /* линия светодиода ("1" - вкл. ч/з резистор на общ.) */
uint8_t a[] PROGMEM={22,15,233,40,69,39,203,2,1};
//===================================================================== ISR( TIM0_COMPA_vect) { if (!(--Cnt1)) { RF.bOne=0; sbi (PINB,Led);// ________ Переключение свдиода ! } }
//_______________ПОДПРОГРАММЫ_________________ void init (void) { PORTB=PUPB; //иницализация порта B DDRB=DIRB; // задание направления для порта B TIMSK0=(1<<OCIE0A); /* установка разр. прер-ия по совпадению т/сч.0 с регистром OCR0A */ OCR0A=234; //загрузка регистра совпадения OCR0A коэф. деления TCCR0A= (1<<WGM01); //установка режима СТС - обнуление Т/С0 при совпадении с регистром OCR0A TCCR0B=(1<<CS02)|(1<<CS00); // <---- конфигурация и запуск сч-ка в реж. СТС с предделителем ckl/1024 RF.bOne=0; RF.bTwo=0; Cnt1=100; //задание начальных значений для счетчиков p=&(a); }
//============================================================================= //============================================================================= int main (void) { init(); sei ();
while (1) { if (RF.bOne==0) { RF.bOne=1; //Cnt1=pgm_read_byte(&(a[p])); // варианте 2 //Cnt1=__LPM(*p); // варианте 3 Cnt1=pgm_read_byte(p); ++p; } } } вот текст программы. были опробованы различные варианты и комбинации , результатов это не принесло !
Сообщение отредактировал MaxiMuz - Dec 9 2011, 12:12
|
|
|
|
|
Dec 9 2011, 13:51
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (MaxiMuz @ Dec 9 2011, 14:06)  вот текст программы. Здесь все, что касается PROGMEM правильно. А вот uint8_t Cnt1; должен быть volatile. В вашем же случае компилятор имеет право строку Cnt1=pgm_read_byte(p); выкинуть совсем. И последний вопрос - файл компилируется как C или как C++? QUOTE QUOTE Следуя вашему FAQ "Как варить яйцо в микроволновке" я стал его варить, но оно взорвалось и сильно испачкало мне аппарат!
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 12 2011, 07:09
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(Сергей Борщ @ Dec 9 2011, 16:51)  И последний вопрос - файл компилируется как C или как C++? Я не знаю как определить как компилируется файл! Есть скопированный makefile, меняю в нем тип МК, имяфайла, оптимизацию , и все. Про яйцо и микроволновку смешно  )) Вы хотите сказать что там где не нужно использовать volatile он был использован и наоборот?
|
|
|
|
Сообщений в этой теме
MaxiMuz WinAVR: Как правильно размещать и работать с таблицами данных во Flash (памяти программ) ? Dec 7 2011, 17:58 Сергей Борщ QUOTE (MaxiMuz @ Dec 7 2011, 19:58) Видим... Dec 7 2011, 18:37 Палыч Цитата(MaxiMuz @ Dec 7 2011, 21:58) Как п... Dec 7 2011, 18:49 Сергей Борщ QUOTE (Палыч @ Dec 7 2011, 20:49) (PROGME... Dec 8 2011, 06:57 Genadi Zawidowski Может, поможет:
Кодvoid uc1601s_put_str_P(con... Dec 8 2011, 08:21 MaxiMuz Цитата(Genadi Zawidowski @ Dec 8 2011, 11... Dec 8 2011, 11:36  Сергей Борщ QUOTE (MaxiMuz @ Dec 8 2011, 13:36) Ничег... Dec 8 2011, 13:03 Genadi Zawidowski А немного пофантазируем...
Скорее всего, человек н... Dec 8 2011, 18:23   demiurg_spb Цитата(MaxiMuz @ Dec 12 2011, 10:09) Я не... Dec 12 2011, 07:56 MaxiMuz _ Dec 9 2011, 12:07 Genadi Zawidowski А это было вообще "шедевр"
Код //Cnt1=... Dec 9 2011, 20:29 MaxiMuz Цитата(Genadi Zawidowski @ Dec 9 2011, 23... Dec 12 2011, 08:20 MaxiMuz Вообщем я понял, из за неприспосбленного и непроду... Dec 12 2011, 10:20 Сергей Борщ QUOTE (MaxiMuz @ Dec 12 2011, 12:20) поче... Dec 12 2011, 10:53  MaxiMuz Цитата(Сергей Борщ @ Dec 12 2011, 13:53) ... Dec 12 2011, 11:48 Genadi Zawidowski КстЦитатаати, это тоже рабочий вариант и ни какой ... Dec 12 2011, 22:05 MaxiMuz Цитата(Genadi Zawidowski @ Dec 13 2011, 01... Dec 13 2011, 11:05  Сергей Борщ QUOTE (MaxiMuz @ Dec 13 2011, 13:05) warn... Dec 13 2011, 12:02 MaxiMuz Заменил p=&a; на p=&a[0]; действительно ... Dec 14 2011, 16:14 AHTOXA И кто будет после этого утверждать, что изучать ас... Dec 14 2011, 19:29 MaxiMuz Проблема решилась выносом p++ за "скобки... Jan 20 2012, 17:24 ARV какая проблема решилась? по-моему, что в скобках, ... Jan 21 2012, 07:34 demiurg_spb Цитата(ARV @ Jan 21 2012, 10:34) по-моему... Jan 23 2012, 05:07 MaxiMuz Цитата(ARV @ Jan 21 2012, 10:34) какая пр... Jan 23 2012, 07:39 AHTOXA Цитата(ARV @ Jan 21 2012, 13:34) какая пр... Jan 23 2012, 05:37
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|