Я пытаюсь запрограммировать PIC10f202 с помощью компилятора XC8, чтобы сравнить значение таймера с переменной, которая будет функцией справочной таблицы. Вот пример кода:
#include <xc.h>
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config WDTE = OFF
Init(void){
TRIS=0;
GPIO=0;
TMR0 = 0;
OPTION = 0b00000011;
}
const unsigned char LUT[250] = {
0b00000000, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000010, 0b00000010,
0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b00000011,
0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000100,
0b00000100, 0b00000100, 0b00000101, 0b00000101, 0b00000101,
0b00000110, 0b00000110, 0b00000110, 0b00000111, 0b00000111,
0b00001000, 0b00001000, 0b00001001, 0b00001001, 0b00001010,
0b00001010, 0b00001011, 0b00001100, 0b00001100, 0b00001101,
0b00001101, 0b00001110, 0b00001111, 0b00010000, 0b00010000,
0b00010001, 0b00010010, 0b00010011, 0b00010011, 0b00010100,
0b00010101, 0b00010110, 0b00010111, 0b00011000, 0b00011001,
0b00011010, 0b00011011, 0b00011100, 0b00011101, 0b00011110,
0b00011111, 0b00100000, 0b00100001, 0b00100010, 0b00100100,
0b00100101, 0b00100110, 0b00100111, 0b00101001, 0b00101010,
0b00101011, 0b00101100, 0b00101110, 0b00101111, 0b00110000,
0b00110010, 0b00110011, 0b00110101, 0b00110110, 0b00111000,
0b00111001, 0b00111011, 0b00111100, 0b00111110, 0b00111111,
0b01000001, 0b01000010, 0b01000100, 0b01000110, 0b01000111,
0b01001001, 0b01001011, 0b01001100, 0b01001110, 0b01010000,
0b01010001, 0b01010011, 0b01010101, 0b01010111, 0b01011000,
0b01011010, 0b01011100, 0b01011110, 0b01100000, 0b01100001,
0b01100011, 0b01100101, 0b01100111, 0b01101001, 0b01101010,
0b01101100, 0b01101110, 0b01110000, 0b01110010, 0b01110100,
0b01110110, 0b01111000, 0b01111001, 0b01111011, 0b01111101,
0b01111111, 0b10000001, 0b10000011, 0b10000101, 0b10000111,
0b10001000, 0b10001010, 0b10001100, 0b10001110, 0b10010000,
0b10010010, 0b10010100, 0b10010110, 0b10010111, 0b10011001,
0b10011011, 0b10011101, 0b10011111, 0b10100000, 0b10100010,
0b10100100, 0b10100110, 0b10101000, 0b10101001, 0b10101011,
0b10101101, 0b10101111, 0b10110000, 0b10110010, 0b10110100,
0b10110101, 0b10110111, 0b10111001, 0b10111010, 0b10111100,
0b10111110, 0b10111111, 0b11000001, 0b11000010, 0b11000100,
0b11000101, 0b11000111, 0b11001000, 0b11001010, 0b11001011,
0b11001101, 0b11001110, 0b11010000, 0b11010001, 0b11010010,
0b11010100, 0b11010101, 0b11010110, 0b11010111, 0b11011001,
0b11011010, 0b11011011, 0b11011100, 0b11011110, 0b11011111,
0b11100000, 0b11100001, 0b11100010, 0b11100011, 0b11100100,
0b11100101, 0b11100110, 0b11100111, 0b11101000, 0b11101001,
0b11101010, 0b11101011, 0b11101100, 0b11101101, 0b11101101,
0b11101110, 0b11101111, 0b11110000, 0b11110000, 0b11110001,
0b11110010, 0b11110011, 0b11110011, 0b11110100, 0b11110100,
0b11110101, 0b11110110, 0b11110110, 0b11110111, 0b11110111,
0b11111000, 0b11111000, 0b11111001, 0b11111001, 0b11111010,
0b11111010, 0b11111010, 0b11111011, 0b11111011, 0b11111011,
0b11111100, 0b11111100, 0b11111100, 0b11111101, 0b11111101,
0b11111101, 0b11111101, 0b11111101, 0b11111110, 0b11111110,
0b11111110, 0b11111110, 0b11111110, 0b11111110, 0b11111111};
unsigned char cnt1=0;
void main(){
Init();
for(;;){
cnt1 = LUT[100];
while(TMR0 > 100){
GPIO=0b00000001;
}
GPIO=0b00000000;
}
}
Таблица поиска составляет 250 символов, потому что это максимальный размер, разрешенный компилятором до того, как он выдал мне ошибку «Не удается найти слова x0FF (x0ff withtotal) для psect «stringtext1» в классе «Entry»». Код компилируется нормально, MPLAB X показывает 55% использования флэш-памяти и 0% использования ОЗУ. Если я изменю условие "пока" на это:
while(TMR0 > cnt1)
Компилятор снова выдаст мне аналогичную ошибку: «Не удается найти слова x0FA (x0fa withtotal) для psect «stringtext1» в классе «Entry»». Я понимаю, что компилятору не хватает памяти для написания кода, но я не понимаю, почему 45% свободного места недостаточно для этой задачи. Кроме того, почему я не могу создать массив из 255 элементов? PIC10f202 имеет 512 слов памяти, это должно быть возможно.
Почему компилятор выдает эти ошибки?
Это прекрасный пример того, как слепое использование компилятора в небольшой системе с ограниченными ресурсами без фактического понимания ограничений машины может привести к неприятностям.
Во-первых, посмотрите, как должна быть реализована таблица констант в памяти программы. Иди читай даташит. Нет, правда, иди читай. Как это тоже нужно сделать? Видите ли вы какой-либо способ чтения памяти программы, например, механизм чтения таблицы, который есть в некоторых других PIC? Единственный способ получить константы из памяти программы — это использовать инструкции, содержащие литералы. Как вы реализуете таблицу с этим? Нет, на самом деле думаюоб этом, прежде чем читать дальше. Взгляните на список инструкций. Единственный способ реализовать интерполяционную таблицу — использовать инструкцию RETLW. Это означает, что вы в основном выполняете вызов подпрограммы для записи в таблице, которая возвращает значение для этой записи в W. Теперь посмотрите на механизм вызова подпрограммы. После того, как вы прочитали то, что должны были сделать перед написанием первой строки кода, должно быть очевидно, почему у вас не может быть более 256 записей в таблице, причем некоторые из этих возможных записей таблицы необходимо использовать для кода.
Покажите, что вы немного прочитали техническое описание, и я смогу углубиться в подробности.
lp: call retAddr
/ retAddr: btfsc temp,7
/ goto gotValue
/ decfsz temp
/ goto lp
, чтобы заставить все слоты стека использовать известный retAddr. Установка бита 7 temp
и запись в PCL приведет к считыванию значения в W и переходу к gotValue
. Не то, что я ожидал от компилятора, но возможно.Поскольку числа в LUT не уникальны, числа монотонно возрастают, а изменения на самом деле выглядят довольно скудно, можно ли написать небольшую функцию для замены LUT?
например, у= х>=1 + х>=23 + .....
Я оставлю это на ваше усмотрение, чтобы выяснить, сколько памяти, если таковая имеется, можно сэкономить таким образом.
Возможно, есть и другие алгоритмы, использующие разреженные методы, которые также могут помочь, возможно, сохраняя уникальные различные значения и значения x, в которых происходят переходы.
PIC10f202 имеет 24 байта оперативной памяти и 750 байт флэш-памяти, согласно этой сводке от Microchip. Если возможно сохранить и запустить таблицу во флэш-памяти, вы сможете разместить небольшую программу, используя оставшуюся часть программной памяти. Но я не вижу в объявлении вашей таблицы ничего похожего на директиву по использованию флэш-памяти, и теперь таблица примерно в 12 раз превышает размер доступной оперативной памяти, даже если к ней не было никаких других требований (таких как стек...) .
const
. В некоторых компиляторах C для PIC это помещает константу во Flash. Но, я не знаю, относится ли это к XC8, потому что я никогда не использовал его.Я не проверял все записи в таблице, но кажется, что записи меняются только на 1 (после нескольких одинаковых записей подряд). Я полагаю, что вы могли бы вместо этого реорганизовать таблицу следующим образом, где каждая точка является точкой, в которой увеличивается значение в старой таблице.
const unsigned char LUT[nn] = {
0, 23, 29, 34, ...
Индекс в новой таблице — это значение, с которым вы сопоставлялись ранее (теперь это поиск по таблице), и значение, возвращаемое из таблицы, совпадает с индексом, который был бы в старой таблице.
Должно быть намного быстрее, и таблица будет намного короче.
июль 059
пользователь3624