Давайте по порядку по поводу "правды" (лично для ALEKS1102X-а)
Повторим суть вопроса - "Родэрик" указал что при команде
const uint8_t R1 = 0xAA;
неправильно вычисляется адрес константы на PIC16F886 !
EEADR=(uint8_t)&R1;
EEADRH=((uint16_t)&R1)>>8;
// в данном случае &R1 - адрес R1 ( !! 16 бит )
// загружаем младший и старший байт адреса
// в переменные EEADR , EEADRH
скорее всего планируется работа с данной "константой"
// а почему нет? если знаем адрес, то можно и изменить!
в случае PIC12F1572 - работает - адрес вычисляется правильно
в случае когда задаём адрес напрямую - то всё работает
const uint8_t R1 @0x18D0=0xAA;
а также работает комбинация
const uint8_t R1 = 0xAA;
const uint8_t R2 @0x1FFF;
----------
смоделировал данную ситуацию
MPLABX 6.05 + XC8 2.41
pic16f690 ( как аналог по коду pic16f886 )
pic16f1827 ( как аналог по коду pic12f1572 )
// пустая программа и
1) const uint8_t R1 = 0xAA;
2) const uint8_t R1 __at(0x800) = 0xAA;
3) const uint8_t R1 = 0xAA;
const uint8_t R2 __at(0x800);
EEADR=(uint8_t)&R1;
EEADRH=((uint16_t)&R1)>>8;
// xc8 2.41 - не знает @
----------
и удивительно - проблема есть для pic16f690!
в листинге всё прекрасно видно что делает компилятор
для записи в память программ константы всегда используется RETLW
1. для pic16f690 получилось что R1
разместился по адресу 0x0007
а адрес назначается 0x8001
для pic16f1827 получилось что R1
разместился по адресу 0x0800
а адрес назначается 0x8800
2. для pic16f690 получилось что R1
разместился по адресу 0x0800
а адрес назначается 0x0800
для pic16f1827 получилось что R1
разместился по адресу 0x0800
а адрес назначается 0x0800
3. для pic16f690 получилось что R1
разместился по адресу 0x0908
а адрес назначается 0x8908
R2 разместился по адресу 0x0800
для pic16f1827 получилось что R1
разместился по адресу 0x0801
а адрес назначается 0x8801
R2 разместился по адресу 0x0800
для расширенной серии pic12f1xxx - pic16f1xxx
есть мапирование памяти программ на память озу с адреса 0x8000
(только младшие байты памяти программ)
используя указатели можно читать таблицы очень быстро
поэтому назначаемый адрес и входит в диапазон 0x8xxx
и сегмент stringX - организуется правильно
для обычных pic16 - xc8 переклинивает и адрес неверно расчитывается
если адрес явно задан для константы или
есть хотя бы одна константа с явным адресом
то сегменты srtringX назначаются правильно
старший бит15 в данном случае - неважен,
так как при записи в EEADRH - отбрасывается
данные манипуляции нужны только для изменения константы
// вычисляем адрес и записываем стандартным алгоритмом
// новые данные по этому адресу
---------- дополнительно ----------
для pic16f1xxx команда
EEADR = &R1
правильно запишет 16 бит адрес в старший и младший байт
команда
EEADR=(uint8_t)&R1;
также пишет 16 бит адрес, игнорируя приведение типа
Последний раз редактировалось
Zikon Ср сен 20, 2023 06:37:20, всего редактировалось 1 раз.