Именно такая форма записи не катит, при компиляции пишет: "не определен символ AAA (или както так)". Когда писал под x86 то использовал подобную форму записи:
Код:
uint8_t AAA asm("BSF %0, 7" : "r"(AAA));
Наверняка в XC8 тоже есть нечто подобное, но в мануале на XC8 описано только обычное: asm("_cod_")
Спасибо))) Тоже только что об этом вспомнил, как раз на x86(а может еще где, не помню) вроде бы вызов СИщных функция из АСМа реализован при помощи черточки) Если кому интересно еще можно так:
У меня глупый вопрос про ХС8 )) Берет ли компилятор на себя все связанное с банками, правильным размещением переменных в памяти и прочим?
Дело в том, что у меня в программе происходят странности с кодом, переполнение стека при определенных обстоятельствах и ветвление кода в непредсказуемые места. PIC16F876A. Итак, имеются 2 массива. Первый из них - одномерный const unsigned char SYM[16] содержит символы 7-сегментника. Второй - двухмерный signed char [11][2]. Нулевой столбец последнего содержит цифры (0...9), а в первом располагаются соответствующие им символы для выдачи на индикатор. В процессе работы программы цифры могут меняться пользователем, каждое изменение цифры в нулевом столбце тут же сопровождается подбором его символа в первом столбце командой
dsp[dig][1] = SYM[dsp[dig][0]];
С этим проблем нет.
При старте программы последние введенные цифры загружаются из ЕЕПРОМ (num_load), преобразовываются в символы (dig2sym) и выводятся на дисплей.
Код:
void num_load (void) { static unsigned char a = 0;
EEPGD = 0; // Выбор ЕЕПРОМ области while (a < 11) { EEADR = a; RD = 1; // Запуск чтения dsp[a][0] = EEDATA; // Сохранение a++; } }
Код:
void dig2sym (void) { static unsigned char a = 0;
while (a < 11) { dsp[a][1] = SYM[dsp[a][0]]; a++; } }
Так вот совместно они не работают. Чтение из ЕЕПРОМ происходит, а когда дело доходит до преобразования, программа начинает уходить в такие дебри, где ее никто не ждал. Шагал по ассемблерному коду в Протеусе, но он скорее всего не виноват, ибо код такой получается. Если же я обхожу чтение из ЕЕПРОМ (// num_load), и назначаю цифры вручную, то преобразование (dig2sym) работает нормально. Оно также работает нормально, если комментирую только одну строку: dsp[a][0] = EEDATA. Пробовал делать и через указатели с тем же успехом, но эта тема для меня пока малопонятная, так что пока решил в лес не углубляться. Оптимизацию отключал. Не вариант. Сижу со вчерашнего вечера в ступоре и пытаюсь поумнеть. Поможете?
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
При объявлении переменной компилятор сам определяет ей место в памяти и в дальнейшем управляет банками при пользовании ей. Однако. Существуют СПЕЦИАЛЬНЫЕ квалификаторы переменных, с помощью которых можно ЗАСТАВЛЯТЬ компилятор размещать переменную в определенном банке или области памяти. Смотрите описание на конкретный компилятор.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Назначения адресов массивов вручную ничуть не улучшили ситуацию.
Добавлено after 16 minutes 2 seconds: Добавил еще один массив unsigned char test[11] = {8,9,1,6,1,2,3,4,5,6,7}; В процедуре загрузки из ЕЕПРОМ заменил строку
dsp[a][0] = EEDATA;
на
dsp[a][0] = test[a];
, и все работает правильно. Что не так с чтением из ЕЕПРОМ? Почему она коверкает программу? Привожу ее еще раз для наглядности:
Код:
void num_load (void) { static unsigned char a;
a = 0; EEPGD = 0; while (a < 11) { EEADR = a; RD = 1; dsp[a][0] = EEDATA; a++; } }
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Line Address Opcode Label DisAssy 385 0180 01FB num_load CLRF a 386 0181 1683 BSF STATUS, 0x5 387 0182 1703 BSF STATUS, 0x6 388 0183 138C BCF PIR1, 0x7 ; bit 7 PSPIF(1): Parallel Slave Port Read/Write Interrupt Flag bit 389 0184 300B MOVLW 0xB 390 0185 027B SUBWF a, W 391 0186 1803 BTFSC STATUS, 0x0 ; STATUS,C 392 0187 0008 RETURN 393 0188 087B MOVF a, W 394 0189 1283 BCF STATUS, 0x5 395 018A 1703 BSF STATUS, 0x6 396 018B 008D MOVWF PIR2 ; bit 4 EEIF: EEPROM Write Operation Interrupt Flag bit ???? 397 018C 0000 NOP 398 018D 0000 NOP 399 018E 0000 NOP 400 018F 0000 NOP 401 0190 1683 BSF STATUS, 0x5 402 0191 1703 BSF STATUS, 0x6 403 0192 140C BSF PIR1, 0x0 ; bit 0 TMR1IF: TMR1 Overflow Interrupt Flag bit 404 0193 087B MOVF a, W 405 0194 3E3C ADDLW 0x3C 406 0195 0084 MOVWF FSR 407 0196 1383 BCF STATUS, 0x7 ; bit 7 IRP: Register Bank Select bit 408 0197 0800 MOVF INDF, W 409 0198 1283 BCF STATUS, 0x5 410 0199 1303 BCF STATUS, 0x6 411 019A 00C7 MOVWF 0x47 412 019B 1003 BCF STATUS, 0x0 ; STATUS,C 413 019C 0D7B RLF a, W 414 019D 3E20 ADDLW 0x20 415 019E 0084 MOVWF FSR 416 019F 0847 MOVF 0x47, W 417 01A0 0080 MOVWF INDF 418 01A1 0AFB INCF a, F 419 01A2 2984 GOTO 0x184
Добавлено after 6 minutes 1 second: Резюмирую все сказанное ранее: с самой функцией чтения проблем нет, она читает из ЕЕПРОМ и сохраняет считанное по нужным адресам в массиве. Но функции, которые идут за ней начинают сходить с ума. Программа переходит не по тем адресам, иногда хаотично, иногда на вектор сброса. Но стоит закомментировать вызов num_load, как все начинают ходить куда положено. Ответ лежит где-то на поверхности, но я его не вижу
Добавлено after 5 hours 19 minutes 57 seconds: Переписал чтение из ЕЕПРОМ на асм, ничего не глючит, но и чтение не работает Где-то я накосячил на сонную голову. Завтра буду разбираться, но это не выход. Не для того я ушел от ассемблера, чтобы им же потом свои сишные прорехи залатывать
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Заголовок сообщения: Re: Програмирование pic на СИ.
Добавлено: Чт окт 27, 2016 23:22:28
Модератор
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Цитата:
а когда дело доходит до преобразования, программа начинает уходить в такие дебри, где ее никто не ждал
А в каком конкретном месте она улетает ? При вызове dig2sym или где то внутри функции ? На чём тестируете, только в протезе, или на железе тоже вылезает такой косяк ? Попробуйте заменить всё, что касается чтения, на компиляторскую библиотечную функцию чтения EEPROM. Если не поможет. Создайте проект с минимальным кодом, при котором вылезает такая бяка и выложите всё сюда, вместе с файлом протеза. Если будет время, можно будет погонять код.
Добавлено after 27 minutes 41 second: И ещё. Вы уверены, что в массив dsp[a][0] читаются значения из EEPROM, не выходящие из диапазона 0..15 ? Ведь по этим значениям потом идёт адресация по массиву SYM. Мало того, т.к. константы компилятор разместит во флеш, то адресация идёт через PCL, а это значит, что любые отличия от этого диапазона приведут к прыжку в неизвестном направлении. Обязательно сделайте в программе ограничение, не позволяющее выходить этим значениям из диапазона. Компилятор за Вас этого не сделает. И ещё. Почему массив dsp знаковый ?
Программа уходит налево на команде dsp[a][1] = SYM[dsp[a][0]]; В зависимости от видоизменений в программе это может быть 0, а может и основной цикл. Там всего 3 проверки, после чего она возвращается на а++. И так ходит по кругу. Проверяю в Протеусе. Это не для меня, потому я паять ничего не буду )) Обидно, все готово и работает, а такая мелочь, которая за 5 минут на ходу написалась, всю работу затормозила. Встроенную EEPROM_READ тоже пробовал с тем же результатом. Попробую выкинуть все лишнее и проверить. Старшие 6 байтов в SYM - это буквы и они не используются, так что ухода за пределы 10 первых точно не происходит. Я даже пробовал глупость сотворить: как положено сохранил w, status и pclath перед входом в num_load, и восстановил перед выходом из функции Не помогло. По поводу знака )) Изначально ( и я опять к этому вернулся) массивов переменных было два, один для цифр (num), другой для соответствующих им символов (dsp). Так вот когда в программе пользователем перебираются цифры, проверка на переполнение выше 9 не вызывало беспокойства компилятора (что резонно), а выражение if ((--num[a]) < 0) num[a] = 9; вызывала предупреждение о том, что переменная незнаковая. Компиляция проходила, но я на всякий случай сделал массив знаковым.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
В том-то и дело, что массив заполняется корректно. Если перед этим не читать ЕЕПРОМ ))
Условие для unsigned можно было написать, но, во-первых, лениво, т.к. это вариант для энкодера, а в конечном варианте будет только кнопка для приращения и проверка на убывание будет не нужна. А во-вторых, размерность массива в обоих случаях одинакова, и одна проверка старшего бита программу не испортит
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Заголовок сообщения: Re: Програмирование pic на СИ.
Добавлено: Пт окт 28, 2016 08:39:58
Модератор
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:1 Медали: 1
Zhuk72 писал(а):
Если перед этим не читать ЕЕПРОМ ))
Дак о чём я Вам и говорю, что именно из EEPROM читаются некорректные для индексации массива значения Если Вы работали с ассемблером, то хорошо должны представлять себе выборку из массива, находящегося во флеши, на МК, не имеющих табличного чтения. Поставьте ограничение. Ну или, ради эксперимента, разместите массив SYM в ОЗУ. И всё заработает
Добавлено after 9 minutes 34 seconds: Нужно всего-то добавить пару строк :
Код:
void dig2sym (void) { unsigned char a = 0, i;
while (a < 11) { i=dsp[a][0]; if(i>15) i=15; dsp[a][1] = SYM[i]; a++; } }
Добавлено after 16 minutes 42 seconds: Да, и ещё. static уберите из переменной "a", иначе при втором и последующих вызовах функции, она не будет инициализироваться нулём.
Получается, что в массив копируется не число, а его аски код. Соответственно PCL уводит программу к черту на кулички. Я - дубина! А вам - спасибо, в очередной раз, огромное!
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Проверку на диапазон 0-9 сделаю, потому как возможна некорректная запись в ЕЕПРОМ и последующее чтение кривых данных из него во время старта вызовет кОтОклизму автору, т.е. мне
Еще раз спасибо!
Добавлено after 47 minutes 22 seconds: Этого будет достаточно:
Други, почему не компилится выражение asm("rlcf _test,f,0"); ? Компилятор ХС8, test объявлен как unsigned char. Выдает ошибку синтаксиса.
Отвечаю сам себе: потому что надо писать asm("rlcf _test,f,с"); К тому же это не работает с локальными переменными, только с глобальными.
Спойлер
Цитата:
Newer versions of XC8 generate a "error: (876) syntax error" to the use of the above. It turns out ",1,0" on the end of the addwf and addwfc lines are the issue (even though these numeric values are specified for use in device datasheets).
The '1' needs to change to 'f' for file register.
The '0' needs to change to 'c' for common memory / access ram (the alternative would be 'b' for bank select register.
Сам код безсмъсленнъй. Но ... оказъвается (и про ето прочитал где-то) компилятор сам решает (анализируя кода) какая разрядность у указателей. В етом коде он решил что у s1 и s2 разрядность 1 байт, а у s3 - 2 байта - из за участие s3 в #asm директиве . При попътке скомпилировать етот фрагмент въдает Error [712] C:\Users\botchin......_1829_2.c; 597. can't generate code for this expression
Тот же самъй резултать если попътаемся иницилировать указателей так: s1 = s2 = s3 = ss;
В асемблере двубайтнъй указатель иницилизируется так:
Все нормально если възъваем функцию однократно, но если попътаемся възвать ее более раза то получаем сообщение Error [845] C:\Users\botchin........_1829_2.c; 525. symbol "loop_test" defined more than once Я понимаю, что ето в резултате работъ препроцессора, но все таки - .....
_________________ Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Заголовок сообщения: Re: Програмирование pic на СИ.
Добавлено: Пн ноя 07, 2016 21:35:18
Модератор
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Цитата:
Код:
0178 01D2 CLRF 0x52 //старшая
Это может быть зарегистрированный компилятором регистр. Не могут одинаковые указатели иметь разный размер
botchin писал(а):
Все нормально если възъваем функцию однократно, но если попътаемся възвать ее более раза то получаем сообщение Error [845] C:\Users\botchin........_1829_2.c; 525. symbol "loop_test" defined more than once
Скорее всего, компилятор инлайнит эту функцию. Отсюда и сообщение о дублировании метки.
// Brown-out Reset Voltage (VBOR) set to 2.5 V #define BORV_25 0xFBFF //corr old 0xF7FF
// High-voltage on MCLR/VPP must be used for programming #define LVP_OFF 0xDFFF //corr old 0xBFFF
Вот - в HI-TECH C® for PIC10/12/16 User’s Guide
Цитата:
There are several pointer classifications used with the HI-TECH C Compiler for PIC10/12/16 MCUs, such as those indicated below. • An 8-bit pointer capable of accessing common memory and two consecutive banks, e.g. banks 0 and 1, or banks 7 and 8, etc. • A 16-bit pointer capable of accessing the entire data memory space • An 8-bit pointer capable of accessing up to 256 bytes of program space data • A 16-bit pointer capable of accessing up to 64 kbytes of program space data • A 16-bit pointer capable of accessing the entire data space memory and up to 64 kbytes of program space data
Each data pointer will be allocated one of the available classifications after preliminary scans of the source code. There is no mechanism by which the programmer can specify the style of pointer required (other than by the assignments to the pointer). If the C code does not convey the required information to the compiler, then it is not complete or accurate.
_________________ Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Последний раз редактировалось botchin Пн ноя 07, 2016 22:10:36, всего редактировалось 1 раз.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения