Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Re: Програмирование pic на СИ.

Пн авг 07, 2017 14:43:19

сори за коменты в конфигурации не совпадают.

#pragma config FOSC = INTOSC
#pragma config WDTE = ON
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config BOREN = ON
#pragma config CLKOUTEN = OFF

// CONFIG2
#pragma config WRT = OFF
#pragma config STVREN = ON
#pragma config BORV = HI
#pragma config LPBOR = OFF
#pragma config LVP = ON


Да, вот тут сбрасываю, как написано в даташите
PCONbits.nRMCLR = 1;
PCONbits.nBOR = 1;
PCONbits.nPOR = 1;

Re: Програмирование pic на СИ.

Пн авг 07, 2017 16:19:52

Не понятно, что вы от нас хотите? Хрустальных шаров у нас нет. А из приведенной вами информации:

    В комментарии написано WDT выключен
    В коде на самом деле включен
    контроллер сбрасывается каждые пол-секунды.
... :dont_know: Возможно, срабатывает ватчдог.

Хотя с другой стороны такой эффект может вызвать сто и одна ошибка в коде. или глючный источник питания.

Re: Програмирование pic на СИ.

Пт сен 08, 2017 11:16:30

Подскажите начинающему PICоводу. Есть устройство на pic18f2550 на котором реализована PS2 to hid клавиатура плюс дополнительные функции обработки ввода с ps2 клавиатуры. Если USB подключен к ПК то все работает нормально но если USB отключить то как я понял контроллер зацикливается на прерывании от USB и не выполняется основной код.
Использую среду mikroC for PIC PRO и стандартную библиотеку USB. Подскажите, может нужно как то определять подключения USB и если не подключен то отключать его в коде до появления физического подключения? Хотя я думал это должно быть реализовано в библиотеке. Кто работает с подобными проектами может смогут подсказать. Второй день мануалы курю безрезультатно. Спасибо

Код:
#include "main.h"
#include "kb.h"

unsigned char readbuff[64] absolute 0x500;
unsigned char writebuff[64] absolute 0x540;
unsigned char modifier=0b00000000;
unsigned char reserved=0;
unsigned char keycode[6];
unsigned char progPass[17] = {0};

void interrupt(){
     USB_Interrupt_Proc();        // USB servicing is done inside the interrupt
     PS2_interrupt();             //Ïðåðûâàíèå ïî INT0 ïðè ïîñòóïëåíèè äàííûõ ñ PS2
}
void interrupt_low(){
     PS2_Timeout_Interrupt();     //Ïðåðûâàíèå ïî timer0 ÷åðåç 1ìñ â ñëó÷àå îøèáî÷íûõ äàííûõ ïî PS2
}

void Led_Indicate(unsigned char blink){
  unsigned char i;
  for(i=0; i<=blink; i++){
     LED_PIN = ~LED_PIN;
     delay_ms(100);
  }
  LED_PIN = 0;
}

unsigned char ArrCmp(unsigned char * arr1, unsigned char * arr2, unsigned char pos, unsigned char ln){
   unsigned char i;
   for (i=0; i<ln; i++){
      if(arr1[i+pos] != arr2[i]) return 0;
   }
   return 1;
}

void main(){
unsigned char i;
        INTCON = 0;
        //Initialize ports
        ADCON1 = 0x0F;  // Configure all PORT pins as digital
        //----------
        TRISA= 0b00010000;
        TRISB= 0b00000011;
        TRISC= 0b10111000;
       
        //Initialize periferal
        init_kb();
        HID_Enable(readbuff,writebuff);
        UART1_Init(9600);                      // Initialize hardware UART1 and establish communication at 9600 bps
        delay_ms(100);
        INTCON2.RBPU = 0;                     //Âêëó÷èòü ïîäòÿæêó
        //OK indicator
        Led_Indicate(2);
        PWR12 = 1;                           
        INTCON |= (1<<GIE)|(1<<PEIE);
        //Main cycle
        while(1) {


       if(button(&PORTC, RC7, 200, 0)){
           LED_PIN = 1;
           PWR5 = 1;                         
           VIDEO_PIN = 1;                   
           delay_ms(300);
           LED_PIN = 0;
        }

        if(keycode[0] == 0x45){
           uart_write(30);
        }
        if(ArrCmp(&progPass, &progStr, 0, 16)){
           switch(progPass[16]){
              case 0x1E: UART1_Write(201); break;
              case 0x1F: UART1_Write(202); break;
              case 0x20: UART1_Write(203); break;
              case 0x21: UART1_Write(204); break;
              default: break;
           }
           progPass[0] = 0;
        }else if(ArrCmp(&progPass, &delStr, 8, 8)){
           switch(progPass[16]){
              case 0x1E: UART1_Write(205); break;
              case 0x1F: UART1_Write(206); break;
              case 0x20: UART1_Write(207); break;
              case 0x21: UART1_Write(208); break;
              case 0x22: UART1_Write(209); break;
              default: break;
           }
           progPass[8] = 0;
        }
        //////////////////////////////////////////////////////////////
//----------
                //USB
               writebuff[0]=modifier;
               writebuff[1]=reserved;
               writebuff[2]=keycode[0];
               writebuff[3]=keycode[1];
               writebuff[4]=keycode[2];
               writebuff[5]=keycode[3];
               writebuff[6]=keycode[4];
               writebuff[7]=keycode[5];
               while(!HID_Write(writebuff,8));
               delay_ms(30);
        }
HID_Disable();
}

Re: Програмирование pic на СИ.

Пт сен 08, 2017 15:10:33

как я понял контроллер зацикливается на прерывании от USB и не выполняется основной код.

Стек HID USB device- это машина состояний, где исполнение функций в цикле while (1) определяется этим самым состоянием. Стек не может зацикливаться в прерывании от USB в состоянии DETACHED по определению, потому что эти самые прерывания могут возникать лишь при наличии входящих пакетов от хоста. Впрочем, он вообще не может циклиться в прерывании.
Свой код должен быть вставлен в этот цикл и так же управляться машиной состояний стека (когда нужно - забирать передавать данные, когда нужно - выполнять код режима отключения).
А вообще, у Микрочипа есть MLA, где имеется и HID USB device. Даже пример для клавиатуры есть. Из него, полагаю, можно запилить и мост из PS/2

Re: Програмирование pic на СИ.

Пт сен 08, 2017 16:53:13

Пример из mikroc тоже прекрасно работает пока USB подключен. Может есть возможность определить подключен ли USB? Может кусочек кода у кого есть? Спасибо.

Re: Програмирование pic на СИ.

Сб сен 09, 2017 21:03:22

Разберите код из самой библиотеки (стека). Скорее всего, код пользователя там исполняется лишь в режимах обмена. Тогда поймете что там нужно допилить.

Re: Програмирование pic на СИ.

Вс сен 17, 2017 12:38:37

Подскажите, как из ассемблерного кода обратиться к биту структуры? Есть структура:
Код:
struct {
    volatile unsigned char  seconds             : 1 ;
    volatile unsigned char  frame               : 1 ;
    volatile unsigned char  update              : 1 ;
} flag;

И есть кусок программы на ассемблере. Мне нужно выставить флаг update.
Код:
    GLOBAL   _flag
...
    BSF       _flag, 2
Столько есть и работает. А вот как быть с "2"?
MPLAB X, XC.

Re: Програмирование pic на СИ.

Вс сен 17, 2017 13:12:28

2 - это номер бита в переменной _flag, который Вы устанавливаете командой bsf.
Поскольку в определении структуры этот бит третий, то естественно, что его номер будет 2 (счет от 0)

Re: Програмирование pic на СИ.

Вс сен 17, 2017 13:18:45

Э... я считать умею. Суть вопроса в том, что если я переопределю структуру, в ассемблере у меня этот BSF "уплывёт". Можно ли избавиться от константы "2"?

Re: Програмирование pic на СИ.

Вс сен 17, 2017 13:37:53

Можете ее задефайнить, но она останется константой. Не существует способа сделать битовый доступ без специальных приемов типа bit banding в АРМах.

Re: Програмирование pic на СИ.

Вс сен 17, 2017 15:10:09

Суть вопроса в том, что если я переопределю структуру, в ассемблере у меня этот BSF "уплывёт".

Можно уйти с битовых полей на маски:

Код:
#define SecondsOffset  0  // этих как нибудь ;-)
#define FrameOffset    1  //   синхронизируем
#define UpdateOffset   2  //     с ASM заголовком

#define SecondsMask  (1 << SecondsOffset)
#define FrameMask    (1 << FrameOffset)
#define UpdateMask   (1 << UpdateOffset)

[...]
flags |= UpdateMask;
[...]
if (UpdateMask == (UpdateMask & flags))
   flags &= ~UpdateMask;

Re: Програмирование pic на СИ.

Вс сен 17, 2017 15:20:25

Эээ! Весь смысл был в структуре. Выкидывать ребенка вместе с водой наверное смысла нет...

Re: Програмирование pic на СИ.

Вс сен 17, 2017 16:18:38

Уважаемые гуру.Пытаюсь освоить СИ.
Почему MPLAB не пишет ошибки?
Вот и все.

Executing: "C:\Program Files\HI-TECH Software\PICC\9.50\BIN\PICC.EXE" -C -E"flex_lcd.cce" "flex_lcd.c" -O"flex_lcd.obj" -Zg9 -O -ASMLIST -Q -MPLAB -16F873A
Halting build on first failure as requested.
BUILD FAILED: Sun Sep 17 20:13:48 2017

Re: Програмирование pic на СИ.

Чт ноя 02, 2017 15:24:54

доброе время суток, ой понимаю что тема заезжена, но код я так и не нашёл, глаза уже болят, а гугол помойка, поэтому прошу, есть ли у кого эффективный код конвертации числа формата long в двоично-десятичное .

Re: Програмирование pic на СИ.

Ср ноя 29, 2017 11:25:36

Привет всем.
Есть несколько вопросов к профи по си. На асме более менее пишу, но всё чаще посматриваю в сторону си. Литература разная на компе есть, давно уже накачал. Начинаю читать, вроде понимаю о чем конкретно говорится в том или ином предложении, но как это применять, мозг работает в ассемблерном стиле. Никак не могу понять как соотнести асм и си. Может кто что посоветует? Такое ощущение что не могу словить какую-то фишку.

И ещё вопрос, связанный уже с удобством написания на си. Я понимаю, что сишный компилятор многое берет на себя. Обратился к переменной - не надо думать о банке....итп. Но как понять границы этой "интеллектуальности". К примеру, я определил начало прерываний org 0x04, и тут же возникает вопрос, - а контекст надо сохранять, или компиль сам поймёт к чему я обращаюсь в прерываниях и соответственно всё устроит лучшим образом? То же самое например с таблицами: достаточно описать алгоритм с несколькими сценариями как функцию и он сам создаст таблицу, или же всё таки мне её вручную создавать (как это я делаю сейчас на асме)? Короче, не могу уложить такие вещи в голове, а без этого даже что-либо начать, прикинуть не могу. Например я видел в чужих кодах при инициализации строчки типа: porta=0. По сути это как в асме, я бы написал clrf porta, и получается, что разница в данном случае не существенна, а это сбивает с толку.

Re: Програмирование pic на СИ.

Ср ноя 29, 2017 11:56:20

Сходите на микрочиповский сайт и скачайте MPLAB_XC8_C_Compiler_User_Guide.pdf - там написано всё. Кстати, занимательное чтиво.

Re: Програмирование pic на СИ.

Чт ноя 30, 2017 07:49:24

uldemir:

С компиляторы для PIC не ограничиваются только XC8. Как минимум, есть еще MikroC и CCS, которые довольно сильно отличаются от XC8 в деталях реализации особенностей PIC. Особенно этим отличается CCS. Поэтому надо сначала определиться с компилятором. XC8 бесплатный в варианте "совсем без оптимизации", а этого хватает не всегда. Вариант PRO "с подпиской", где оптимизация работает хорошо, но каждый месяц нужно платить за продление лицензии в России не продается. Да, он есть на Microchip Direct, но купить его нельзя, отправляют в Гамму, а там говорят, что недоступно из-за особенностей законодательства и купить можно только бессрочную лицензию (по цене это примерно 3 года, с хвостиком, лицензии с подпиской). Mikro C бесплатный для программ размером кода после компиляции до 2 кБ и не работает под Linux (под Wine работает, но подглючивает). CCS только платный.

groot:

Для начала надо сам С изучить, многие вопросы отпадут в принципе. В частности, станет понятно, что в С есть нормальные операторы управления потоком, которые исключают необходимость таблиц переходов. Но если они сильно нужны, то есть указатели на функции, которые, естественно, можно собрать в массив. Процедуры обработки прерываний делают все сами, и размещаются там, где надо сами. Только такую процедуру надо описывать как interrupt, а вот тонки такого описания в разных компиляторах различаются. Например в CCS это делается через pragma. И контекст такие процедуры сами сохранят.

Ну и никакие таблицы с константами через retlw не нужны. Просто описываете инициализированный массив и получаете нужно значение обратившись по индексу. Все остальное сделает сам компилятор.

С не только исключает необходимость следить за банками RAM и страницами ROM, там еще и стек не ограничивается 8 уровнями (midrange). Понятно, что аппаратный стек никуда не девается, но если его не хватает, то используется программный стек полностью управляемый компилятором. Фактически, там вместо call и return используется прямое обращение к PC и PCLATH. Но есть и ограничения, по сравнению со стандартом С. Например, размер структуры или массива не должен выходить за границы банка, а размер процедуры быть больше страницы. Опять таки, это может зависеть от компилятора.

Еще на С не очень удобно работать со сдвигами. Например, вывод байта в разряд порта (программный URT или I2C) на asm легко делается через сдвиги (циклические сдвиги, если надо сохранить байт) и бит C в STATUS. На С нет циклических сдвигов, обычные есть.

В общем, к мышлению в стиле С, конечно, придется привыкать. Но не так это и страшно. Кстати, всегда можно посмотреть asm файл сгенерированный компилятором, что позволит лучше понять взаимосвязь конструкций. Ну и ошибки найти, я вот в CCS нашел одну, обещали исправить.

Re: Програмирование pic на СИ.

Чт ноя 30, 2017 16:08:35

ektsysto, благодарю за развернутый ответ. Кстати, а каким тогда лучше всего компилятором пользоваться, если получается что там не всё так просто и много всяких ограничений и прочих нюансов?
А насчёт изучать си - по возможности я и так читаю разную литературу и в принципе понимаю каждое предложение. Но проблема с применением этих знаний. К примеру, идёт описание if...else, и я понимаю, что если выражение истинно то выполняется то, что "здесь", а если ложно, то "там". Ладно, что тут не ясного. Вот только возникает куча вопросов, - как это всё будет в ассемблере, как часто это будет происходить в коде, зачем, например, мне постоянно дёргать ногой, если нужно всего один раз, то есть я хочу контролировать код на уровне асма, понимать что в итоге получается, но здесь с этим непонятка.

К примеру есть задача, которая на асме решается без проблем: при нажатии кнопки, led загорелся, при следующем нажатии - потух; иными словами простой делитель на два. На асме я могу сделать так: создаю флаг, который поднимается в прерываниях (каждые 20ms) и всегда проверяю его в основном цикле. В итоге я периодически (20ms) опрашиваю ножку порта и сравниваю её текущий уровень с флагом (дублирующим). Однажды происходит расхождение и я получаю два четких сценария исполняемых однократно: либо нажали, либо отжали, и там пишу все то, что хочу сделать по любому из этих фактов (инвертировать led), а потом при выходе инвертирую дублирующий флаг (устраняю несоответствие) и все происходит вновь. Таких процедур может работать одновременно сколько угодно от любого количества ног и ничего ничему не будет мешать или задерживать. Но главное я прекрасно понимаю как это работает непосредственно на уровне асма. А как к примеру реализовать этот же алгоритм на си?

Re: Програмирование pic на СИ.

Чт ноя 30, 2017 17:34:59

Разница в компиляторах начинается на уровне нюансов. Оптимальным, на мой взгляд, является XC8. К тому же потом можно легко перейти на XC16 и XC32. Но, как я уже сказал, бесплатная версия отличается полным отсутствием оптимизации. По моим наблюдениям это дает раза в 2 - 2.5 больший объем кода и скорость работы раза в 3 ниже, чем с оптимизацией лицензии PRO (там есть возможность 2 месяца бесплатно тестировать PRO). Стоимость лицензии PRO для XC8 варианта "рабочая станция" составляет 995 USD, что многовато для начинающих и тех, кто не зарабатывает этим деньги. Подписка в России не продается, проверял сам.

Mikro C бесплатно позволяет генерировать до 2 кБ кода. Не работает под Linux (для меня очень критично). Платная версия стоит 249 USD. Особого ничего сказать не могу, только немного погонял на простеньком примере. IDE навороченная, но это к компиляции имеет довольно опосредованное отношение. Кстати, этот же производитель делает и компилятор Pascal и Basic.

CCS использую сам. Версия командной строки для Linux. Есть и версия с IDE. Без IDE может компилировать только один файл, но это легко обходится через include, хотя добавляет неудобств. У компилятора разные версии, PCB, PCM, PCH, PCD под base-range, mid-range, extended mid-range, PIC24. И покупать их надо по отдельности. От прочих компиляторов отличается скрытостью описаний контроллеров и некой оберткой маскирующей физические отличия контроллеров. То есть, прочитав документацию на контроллер прямо так один в один к компилятору ее не применить. Зато появляется переносимость, так как функции работы, например с PWM будут работать на любом контроллере, даже если у него регистры по иному устроены. Опять таки, у него приличная библиотека, встроенная. Например, там можно писать программу совершенно не обращая внимания есть встроенный I2C master в контроллере, или он будет эмулироваться программно встроенной библиотекой. При этом можно получить и стандартные имена, например, бита запуска таймера, но они будут не в .h фале, а в программе функцией genenv (отрабатывает на уровне компиляции, а не выполнения). То есть, всю эту обертку можно легко обойти, если надо. У меня PCML, версия командной строки Linux, покупал за 150 USD.

Что касается трансляции команд С в команды контроллера, то ничего мистического там нет и все видно в asm файле для любого компилятора. Конечно, там будет много такого, чего Вы не напишете сами, но это необходимо, так как в любом случае есть некая "среда времени выполнения" (run-time environment). Она есть у любого компилятора для любой целевой архитектуры. Но если Вы пишете действительно большую программу, то объем кода на ассемблере будут сравнимым со сгенерированным компилятором С кодом. Зато пишется быстрее.

И ничего там само не будет выполняться. Все точно так же, как на ассемблере. Есть проверка в программе на ассемблере, выполняется пару раз за программу, точно так же будет и для С с оператором if. Цикл так цикл. Только надо учитывать, что цикл лучше делать не с автоинкрементом, а с автодекрементом. Просто в итоговом коде это будет чуть быстрее. И "дерганье ногой" делается элементарно. И прерывания будут работать точно так же.

Что бы стало понятнее, можете прислать мне пример программы на ассемблере, для начала простой. Я отвечу, как это будет на C. Оттранслирую в XC8 и CCS, пришлю lst файлы, добавив туда немного комментариев для большей понятности. Конечно, полностью сгенерироваггый код комментировать и описывать не буду, но основные моменты помечу.

Но вообще, если разберетесь собственно с С и будете понимать, как работает контроллер, то разобраться в другом компиляторе не составит большого труда. Переписать программу будет немного муторно, но вполне выполнимо. Сложнее, когда новый компилятор менее функционален и наворочен, чем ранее используемый.

Поверьте, для Вас будет гораздо большим открытием тот факт, что не всегда написанное на С будет выполняться :-) Про модификатор voltile для переменных промолчу, тут регистров общего назначения нет, почти все делается через WREG, так что они все volatile получаются. А вот логические выражения запросто могут закончить вычисляться до окончания собственно выражения, просто результат станет известен заранее. И если Вы в таком выражении используете автоинкремент, например, а эта часть выражения окажется пропущенной, причем во время выполнения, то автоинремента не будет. И искать, без понимания того, как логические выражения вычисляются, Вы это будете долго. И отладчик не поможет, так как такой пропуск может выполняться не каждый раз (например, не каждую итерацию цикла). Кстати, это работа оптимизатора компилятора.

Re: Програмирование pic на СИ.

Пт дек 01, 2017 11:45:59

Оптимальным, на мой взгляд, является XC8.
...
Mikro C бесплатно позволяет генерировать до 2 кБ кода.
...
CCS использую сам.


Увы и ах, XC8 не "оптимальный" а единственно верный выбор.
МикроС от микроЕ это компилятор языка похожего на С и весьма далекого от вменяемого С.
Это скорей врапер фрэймвока изоБреденного микроЕ, аналог аурдуньи.
CCS хоть и позволяет ограничено писать на вменяемом С, но выбирают его новички из-за встроенных "плюшек" кои так же далеки от стандартного С.

Так что, чтобы не было в последствии мучительно больно от осознания что изучал "с для пЫк" , единственно верный выбор XC8.

ektsysto, вопрос- если сами еще плаваете, зачем поучать других? Гуру медвежьих услуг?
Ответить