MPLAB X IDE

Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить
Грызет канифоль
Аватара пользователя
Сообщения: 295
Зарегистрирован: Вс дек 18, 2011 14:41:24
Откуда: Ангарск

Сообщение Linuxoid91 »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4351184#p4351184"][uquote="Linuxoid91",url="/forum/viewtopic.php?p=4351176#p4351176"]Библиотеки или хотя бы база Code Example...[/uquote]
Озвучьте тип МК и задачу, которую вы на нем реализуете[/uquote]
PIC24FJ64GA004. Компилятор XC16. Устройство состоит из DF-Player (для звукового сопровождения, связь по UART), дисплея 1602 (связь по I2C через PCF8574) и кнопочной матрицы 3х4.
С помощью некоторых плясок с бубном, какой-то матери и трех вечеров времени :shock: , из UART, в итоге, выплевывается какой-то сигнал. Пока непригодный в пищу, DFPlayer просто плюется в ответ, не издав ни звука...

В общем, как по мне, путь честного дрыгнанья регистрами мне не очень нравится - довольно трудоемок...
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6499
Зарегистрирован: Сб янв 28, 2006 22:47:24

Сообщение Asmodey »

[uquote="Linuxoid91",url="/forum/viewtopic.php?p=4351277#p4351277"]из UART, в итоге, выплевывается какой-то сигнал. Пока непригодный в пищу, DFPlayer просто плюется в ответ, не издав ни звука...[/uquote]
Тут желательно иметь под рукой PICkit Serial Analyzer и хотя бы простенький лог. анализатор. Чтобы не гадать где косяки возникли.
Астролябия-сама меряет, было бы что мерять!!!
Реклама
Грызет канифоль
Аватара пользователя
Сообщения: 295
Зарегистрирован: Вс дек 18, 2011 14:41:24
Откуда: Ангарск

Сообщение Linuxoid91 »

Есть snap и PIC KIT 3. Возможно, с этим можно работать как с чем-то большим, чем программаторы? Я по буржуйски просто не сильно понимать, поэтому даже не знаю всего того, что там есть... Или как-то посмотреть в MPLAB, к чему, вообще, приводит мой код. Помню еще, симулятор там какой-то был. Попробовал, и ничего не понял. Я ожидал от него большего, чем предупреждения в окошке о переполнении стека от кода, который просто мигает светодиодом. Сам МК в железе при этом от того же кода работает корректно. Хотя бы картиночку с МК, где нарисовано, какие ножки и регистры затронуты...
Друг Кота
Аватара пользователя
Сообщения: 6499
Зарегистрирован: Сб янв 28, 2006 22:47:24

Сообщение Asmodey »

PICkit 3 в принципе может работать логическим анализатором. С родной программой PICkit 3 Programmer. Только возможности программного обеспечения крайне ограничены. Китайские клоны Saleae Logic куда как интереснее в этом плане.
Астролябия-сама меряет, было бы что мерять!!!
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

Господа, есть вопрос по компилятору XC32 камень PIC32MX460F512L
Собираю я данные по уарт, периодически смотрю, собрался весь пакет или нет, и тут я попадаю на грабли, точнее уже не первый раз.
Есть массив unsigned char uart_rx[512], в него по прерыванию прилетают байты, по последовательности байтов алгоритм начинает понимать что пришла посылка и далее начинает её разбирать, чтобы долго не возится была написана структура. В указатель на структуру копируется адрес начала посылки, и далее по логике остается только получить данные из структуры, вроде бы да, но если указатель на начало посылки начинается с нечётного числа то всё вылетает в аут поскольку в структуре присутствуют short, и при попытке получить данные через указатель на short получаю аналогичную шляпу или полную белеберду, поскольку копирует байт не с той стороны.
Есть какое нибудь решение кроме копирования для исправления ошибки смещения? :?
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Судя по некоторым понятным фразам, проблема с выравниванием.
Объясните проблему по подробнее, с кусками кода. Мало что понятно из Вашего поста :roll:
Контактная информация:
Реклама
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

Вечером времени не оказалось :(
Спойлер

Код: Выделить всё

struct Serv485u8// данные выдаются в формате char
{
    unsigned char Addr;  //1 1
    unsigned char contr; //1 2//0x5A  
    unsigned short len;  //2 4 
    unsigned char pak[2];//2 6
    unsigned char c[1024];//передаваемые данные 
};

struct 
{
    unsigned char pac;
    unsigned char read;
}uk;//указатель на точки чтения и записи

unsigned char uart_rx[1024]; // кольцевой буфер приёма
unsigned char adr = 0x50;

void InPac();
bool СheckCRC485(unsigned char *Buff, unsigned short len);
void ReadPac(unsigned char * pcBlock, unsigned short len);

//----------------------------------------------------------
void __ISR(_UART_2_VECTOR, IPL1AUTO) UART2Interrupt(void)//
{    
    unsigned short i0=10;//блокировка зацикливания
    
    
    if(IFS1bits.U2EIF)//проверить на наличие ошибок
    {                   
        CheckError(); //читаем биты ошибок  
    }
    else   
    {   // ошибок нет, читаем 
        do
        {
            uart_rx[uk.pak] = U2RXREG;
            
            if(uk.pak<sizeof(uart_rx)-1)//индекс сдвинули на байт
                uk.pak++; 
            else uk.pak=0;                      
            
            i0--;
        } while(U2STAbits.URXDA && i0);    
    }     
    
    IFS1bits.U2RXIF=0; //сброс флага прерывания
}
//========================
void main()
{
    
    while(1)
    {
        if((uk.pac - uk.read) >4)
            InPac();
        
        // тут ещё много всяких if'ов которые по флагам от таймеров и иных прерываний выполняют различные задания
    }
}
//------------------------------------------------------------------------------
void InPac()
{
    struct Serv485u8 *serv;
    
    while(uk.read!=uk.pac)// пока всё не прочитаем
    // помню что буфер кольцевой, но этот вопрос буду решать позже, главное с выравниванием разобраться
    {
        
        if(uart_rx[uk.read]==adr && uart_rx[uk.read+1]==0x5A)//;
        {//собираем пакет
            serv=(void*)&uart_rx[uk.read];// можно было и так serv=(struct Serv485u8*)&uart_rx[uk.read]; но ничего особо не меняет
            //если uk.read не чётное число, адрес получается тоже нечётный
            //если обратиться к структуре(например serv->len) то тут вылетаем в ошибку
            if(serv->len < (uk.pac - uk.read))//если пришёл весь пакет
            {
                if(СheckCRC485(uart_rx[uk.read], serv485->len-2))
                {
                    ReadPac(uart_rx[uk.read], serv485->len-2);//передаём пакет на разборку
                    uk.read+=serv485->len; // данные считали, двинули указатель чтения
                    if(uk.read>=sizeof(uart_rx))//если вышли за пределы кольцевого массива, вернутся к началу 
                        uk.read-=sizeof(uart_rx); 
                }
                else  uk.read++;
            }
            else break; // выходим, зайдём в следующий раз, возможно к тому моменту успеет всё собраться    
        }
        else// не нашли нужных байт, двигаем указатель чтения
            uk.read++;
    }
    
}// Ну как то так
:tea:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

alex_ писал(а):если обратиться к структуре(например serv->len) то тут вылетаем в ошибку
Естественно. Ошибка вылетает из-за того, что адрес получается невыровненный.
Создайте объект своей структуры и делайте побайтную копию из буфера. А потом уже работайте с ней.

Добавлено after 3 minutes 1 second:
Вопрос. Для чего Вам кольцевой буфер, если Вы данные принимаете в виде готовой структуры ? Не проще сразу в неё и принимать ? Или без кольца - приняли в буфер, скопировали в структуру, обработали.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

Собственно так уже и сделал, при сходстве начальных 2 байт и по достижению заданного размера копирую в другой буфер и уже указатель на структуру приравниваю к выровненному массиву. Я в начале думал, что ему пофиг откуда начинать считать байты, ан нет, он же блин 32разрядный, по 2 байта за раз засылает :tea:
Кольцевой буфер нужен для того чтобы не потерять данные в процессе обработки, к тому же не факт что успеет разобрать пакет до прихода новых данных.
Эх по уму надо на ДМА кольцевой буфер сделать, чтоб вообще без прерываний :roll:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

alex_ писал(а):Кольцевой буфер нужен для того чтобы не потерять данные в процессе обработки
С чего они потеряются, если они уже приняты и их осталось обработать ? Принимать нужно весь пакет от и до, а потом уже заниматься обработкой.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

Да но на камне висит куча других задач, и он просто во время не факт что успеет запрос обработать, я сначала так и делал, собирало всё нормально но когда загрузил камень основными задачами то всё и отвалилось, контроллер начал сваливаться в ресет
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Что-то Вы намудрили, если ресетится проц :)
По поводу "успеет" / "не успеет" обработать. Если Ваш код не успевает с обычным буфером, то кольцевой Вам не поможет. Оно и с ним будет не успевать. Нужно в корне пересматривать структуру программы.
Запустите FreeRtos и, из прерывания, по семафору отдавайте управление в задачу-обработчик, которая будет по приоритету выше остальных. Тогда всё будет успевать :)
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

Я не использую никакие Rtos, обработка идёт в общем цикле while(1) по выставленным флагам, которые выставляются от таймеров и прерываниям а так же по внешнему входу(W5500). Когда было просто на прерываниях то постоянно в ресет вываливался, полагаю что просто попадал на переполнение стека. После сделал обработку по флагам, - кому надо все в очередь.
По прежнему вопросу, сделал пока без кольца, чтобы протестировать, и когда всё запустил программа по окончанию обработки стабильно вываливается в ресет, может опять на переполнение стека попадаю, какие регистры можно посмотреть после рестарта чтобы понять по какой причине вылетаем? Регистр RCON показывает софт ресет, но это фишка MPLABа он при ошибке сам ресетит контроллер, до этого писал на микросях, там контроллер просто вис и перезагружался по собаке.
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

Может кто сталкивался, есть ли возможность поменять в настройках компилятора отключить функцию стирания всей прошивки перед записью, а стирать и писать постранично? При условии что не установлен бит защиты. Для чего это надо: после основного кода прошивки находятся настройки устройства, и он постоянно их затирает, при каждой перезаливке, несмотря на то что я только что откалибровал устройство :?
Согласен можно поставить внешнюю флешку, хотя бы на момент написания и отладки прошивки, но вдруг можно и в софтине настройки поменять :roll:
Родился
Сообщения: 4
Зарегистрирован: Вт сен 08, 2015 08:57:47

Сообщение picpower »

[uquote="alex_",url="/forum/viewtopic.php?p=4355819#p4355819"]Вечером времени не оказалось :(
Спойлер

Код: Выделить всё

struct Serv485u8// данные выдаются в формате char
{
    unsigned char Addr;  //1 1
    unsigned char contr; //1 2//0x5A  
    unsigned short len;  //2 4 
    unsigned char pak[2];//2 6
    unsigned char c[1024];//передаваемые данные 
};

struct 
{
    unsigned char pac;
    unsigned char read;
}uk;//указатель на точки чтения и записи

unsigned char uart_rx[1024]; // кольцевой буфер приёма
unsigned char adr = 0x50;

void InPac();
bool СheckCRC485(unsigned char *Buff, unsigned short len);
void ReadPac(unsigned char * pcBlock, unsigned short len);

//----------
void __ISR(_UART_2_VECTOR, IPL1AUTO) UART2Interrupt(void)//
{    
    unsigned short i0=10;//блокировка зацикливания
    
    
    if(IFS1bits.U2EIF)//проверить на наличие ошибок
    {                   
        CheckError(); //читаем биты ошибок  
    }
    else   
    {   // ошибок нет, читаем 
        do
        {
            uart_rx[uk.pak] = U2RXREG;
            
            if(uk.pak<sizeof(uart_rx)-1)//индекс сдвинули на байт
                uk.pak++; 
            else uk.pak=0;                      
            
            i0--;
        } while(U2STAbits.URXDA && i0);    
    }     
    
    IFS1bits.U2RXIF=0; //сброс флага прерывания
}
//======
void main()
{
    
    while(1)
    {
        if((uk.pac - uk.read) >4)
            InPac();
        
        // тут ещё много всяких if'ов которые по флагам от таймеров и иных прерываний выполняют различные задания
    }
}
//----------
void InPac()
{
    struct Serv485u8 *serv;
    
    while(uk.read!=uk.pac)// пока всё не прочитаем
    // помню что буфер кольцевой, но этот вопрос буду решать позже, главное с выравниванием разобраться
    {
        
        if(uart_rx[uk.read]==adr && uart_rx[uk.read+1]==0x5A)//;
        {//собираем пакет
            serv=(void*)&uart_rx[uk.read];// можно было и так serv=(struct Serv485u8*)&uart_rx[uk.read]; но ничего особо не меняет
            //если uk.read не чётное число, адрес получается тоже нечётный
            //если обратиться к структуре(например serv->len) то тут вылетаем в ошибку
            if(serv->len < (uk.pac - uk.read))//если пришёл весь пакет
            {
                if(СheckCRC485(uart_rx[uk.read], serv485->len-2))
                {
                    ReadPac(uart_rx[uk.read], serv485->len-2);//передаём пакет на разборку
                    uk.read+=serv485->len; // данные считали, двинули указатель чтения
                    if(uk.read>=sizeof(uart_rx))//если вышли за пределы кольцевого массива, вернутся к началу 
                        uk.read-=sizeof(uart_rx); 
                }
                else  uk.read++;
            }
            else break; // выходим, зайдём в следующий раз, возможно к тому моменту успеет всё собраться    
        }
        else// не нашли нужных байт, двигаем указатель чтения
            uk.read++;
    }
    
}// Ну как то так
:tea:[/uquote]

А выровнять структуру при объявлении?

Код: Выделить всё

#pragma pack(push, 1)

struct Serv485u8// данные выдаются в формате char
{
    unsigned char Addr;  //1 1
    unsigned char contr; //1 2//0x5A  
    unsigned short len;  //2 4 
    unsigned char pak[2];//2 6
    unsigned char c[1024];//передаваемые данные 
};

struct 
{
    unsigned char pac;
    unsigned char read;
}uk;//указатель на точки чтения и записи

#pragma pack()
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

Мне кажется тут даже не в выравнивании структуры, а в процессе обращения если указатель(адрес) оказывается нечётным, то всё сразу начинает идти по одному месту, поскольку контроллер 32 битный, 2 байта команда 2 байта данные то смещение на 1 байт ему ну очень не нравиться. Кстати функцию я эту уже полностью переписал, слишком сложно получилось и отнимает дополнительное время у контроллера.
Кстати я пытался копировать структуру по 2 байта через указатель на short работает быстрее чем копировать через указатель на char, но если опять же размер структуры оказывается нечётный или с нечётного адреса то опять слетаем в софт ребут, а с указателем на char дольше но всё стабильно копируется.
Открыл глаза
Сообщения: 60
Зарегистрирован: Пт окт 19, 2018 14:17:14

Сообщение lin17 »

Последнее время иногда компилятор стал зависать на минуту и более, если при этом выключить MPLAB, то он потом так же тормозит с прогрузкой файлов. Есть ощущение, что он что-то пытается по интернету сделать, но это не точно. Версия 6.0.

Периодически ещё выдаёт ошибку XC8 Timeout
Открыл глаза
Сообщения: 60
Зарегистрирован: Пт окт 19, 2018 14:17:14

Сообщение lin17 »

В итоге помогло убивать процесс xclm в диспетчере задач. Хотя так и не понятно, что происходит.
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

Есть мнение, что ПК просто не тянет тяжёлую яву.
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Сб июн 01, 2013 22:24:21
Откуда: ПФО

Сообщение alex_ »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4169752#p4169752"][uquote="alex_",url="/forum/viewtopic.php?p=4169701#p4169701"]Пробовал ли кто эти 2 бита ногодрыгом дослать? :roll:[/uquote]
Ничего не надо досылать. Посылается количество бит, которое БОЛЬШЕ, чем требуемое. Лишние просто будут вытолкнуты в приемнике.[/uquote]
Дисплей на контроллере WS0010, а вот как называется - хрен вам с матрёшкой :tea: Пришлось поднять старую тему и перейти на аппаратный SPI.
Эта зараза не выталкивает не один лишний разряд, отсчитывая свои первые 10 бит их и принимает в обработку :kill:
Не первый день этот дисплей долбаю на аппаратном SPI, с командами вроде разобрался, выдаём 2 байта последние 6 бит просто игнорирует. А вот с догрузкой данных блин косяк, сначала надо выдать 2 бита а потом кратно 8 битам данные :facepalm:
Разработчики данного контроллера походу знают толк в извращениях :))

Добавлено after 3 hours 12 minutes 9 seconds:
Усё сдаюсь, аппаратный SPI здесь работать не будет, идеи кончились, только ногодрыг :( :facepalm:
Ответить

Вернуться в «PIC»