реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> PIC18 Compare & PinRB3 CCP2, CCP2CON обслуживание в КАЖДОМ цикле
Мур
сообщение Nov 12 2006, 02:46
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



После 7-летнего перерыва (подсел на AVR после РIC16) вернулся к PIC18...
Вроде получилось! Благо С помогает на ассемблер не отвликаться, а обслуживание регистров легко по формату таблицы, что перед глазами всегда.
twak.gif Затык произошёл от нечёткой информации в даташите. НЕТ предупреждения, что для нормальной работы пина ССР2 требуется в КАЖДОМ цикле возобновлять значение CCP2CON!
Долбался неделю. maniac.gif Наверное сработал привычный AVR-ский подход...Не расслабляйтесь!!!
Флажком на другой ноге прописал програмно штатное поведение ССР2. Убедился ,что живёт...Но оказывается, чтобы родной выход работал, надо в прерывании постоянно подгружать CCP2CON!!

Делюсь находкой tort.gif Удачи пытливым!!!
Go to the top of the page
 
+Quote Post
Alex B._
сообщение Nov 12 2006, 09:27
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274



Что за чушь?
Не надо там конфигурационнй регистр обновлять.
Какой у вас контроллер? Приведитет код.
Go to the top of the page
 
+Quote Post
Мур
сообщение Nov 13 2006, 05:27
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



PIC18F2455 santa2.gif
#pragma interrupt high_isr
void high_isr(void)
{
if(PIR2bits.TMR3IF&&PIE2bits.TMR3IE) //select int COMP
{
WORD temp;
PIE2bits.TMR3IE = 0; //OVF Interrupt disableable bit
CCPR2H =MOD_buffer[mod].byte1 ;
CCPR2L =MOD_buffer[mod].byte0 ;
PIR2bits.TMR3IF = 0;//clr OVF
PIE2bits.TMR3IE = 1; //OVF Interrupt Enable bit
temp._word = MOD_buffer[mod++]._word-SYSTEMATIC ;//+ SYSTEMATIC
TMR3H = temp.v[1] ;//setup begin count!
TMR3L = temp.v[0] ;
TEST_FLAG = !TEST_FLAG;////////////

PIR2bits.TMR3IF = 0;
}
CCP2CON = 0x09; //compare -> low CCP2
}
Я тоже считал это чушью...
Go to the top of the page
 
+Quote Post
Alex B._
сообщение Nov 13 2006, 08:04
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274



Что вы хотите сделать, объясните... ШИМ с изменением скважности каждый период? Это по другому делается. CCP -> в PWM modе, в прерывании от таймера меняйте скважность.

Контроллер работает так, как написано в документации - при совпадении регистров compare модуля со значением таймера, вывод переводится в состояние 0. Все, дальше в 1 вы должны перевести его программно. То что вы делаете - это просто переинициализация модуля - на ноге появляется единица.
Такой вариант позволяет генерировать одиночные импульсы, вам нужно использовать CCP в режиме PWM
Go to the top of the page
 
+Quote Post
Мур
сообщение Nov 13 2006, 12:28
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Да нет же! Назвать это ШИМом нельзя, т.к. в основном этот выход молчит и только при наступлении стартового события формируется переменная(разная в каждом сеансе!) последовательность, где 1-ное значение фиксированной длительности, а информация в периоде. Причём ССР модуль нужен для точности формирования,-аппаратная реализация всё-таки!....Кстати число этих периодов тоже программируемое! blink.gif

Если не делать такой (выделенной в тексте) операции,- импульс появляется на ноге ТОЛЬКО ОДИН раз, хоть таймер и компарирование ведёт себя корректно(флагом это отслеживается..) ! И далее железный 0 cranky.gif

Обратите внимание, после новой инициализации CCP2CON появление 1 на ноге честное, в момент переполнения таймера, а не в момент загрузки CCP2CON, как ВЫ педположили... tongue.gif
Go to the top of the page
 
+Quote Post
Alex B._
сообщение Nov 13 2006, 13:17
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274



Все равно не понял.
Модуль сравнения должен всего навсего устанавливать на выводе определенный лог. уровень при совпадении значения таймера с регистром модуля. У вас выбран режим, в котором устанавливается 0 - откуда там аппратно может появится 1, если вы не сделаете этого сами, или не перенастроите модуль сравнения в соответствующий режим?
Go to the top of the page
 
+Quote Post
Мур
сообщение Nov 13 2006, 15:26
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Важная деталь! PWM имеет всего-лишь 10разрядное разрешение..
Здесь у меня все 16!

Поясню Ваш вопрос рисунком
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Мур
сообщение Nov 13 2006, 16:23
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



tongue.gif Лажанулся я с рисунком!
Еле деточек от компа отогнал, чтобы исправиться...
Систематическая погрешность на время вхождения в прерывания частично решает проблему програмной установки в 1 ножки. Аппаратно в 0 доверяется уже PIC-у.
Это события недельной давности, вот я и запамятовал слегка...Людям голову морочу, блин...
Суть от этого не меняется,- при такой 16разрядной идеологии формирования ШИМ-сигналов неизбежна загрузка в каждом цикле регистра CCP2CON!
Во времени это выглядит так
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Alex B._
сообщение Nov 13 2006, 20:04
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274



ну дак все работает штатно - прочитайте еще раз документацию - все это там написано. Повторюсь третий раз - compare в выбраном вами режиме подразумевает всего навсего сброс ноги в ноль. Установить ее в единицу вы должны сами. У PIC18 переконфигурацией CCPxCON делать это НЕ обязательно, можно работать с этим выводом как с обычным портом.
Go to the top of the page
 
+Quote Post
Мур
сообщение Nov 14 2006, 05:26
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Цитата(Alex B._ @ Nov 14 2006, 00:04) *
У PIC18 переконфигурацией CCPxCON делать это НЕ обязательно, можно работать с этим выводом как с обычным портом.

Другими словами, там, где я кормлю CCP2CON в программе можно поставить установку в 1 линии PORTB? И всё?
Это мне не выгодно, поскольку по логике я должен ещё и полярность сигнала выбирать(0х08,либо 0х09). Тут этого ещё небыло... Тогда мне проще в одном месте это делать, нежели в 2-х местах.
Ну, это уже лирика... А философски,- это недочёт Микрочип! w00t.gif
Надо бы о триггере событий подробнее написать! Это раз!
А главное, таймерные игрища,особенно связанные с установкой режимов, не должны иметь что-то одноразовое! Гляньте на формат регистра,-в запасе ещё 2 бита. Введите условие,-типа- учёт режима однократно\постоянно. И всё! 1111493779.gif
Я благодарен ВСЕМ за опыт! Надеюсь, у некоторых тоже добавилось знаний....
Удачи!
Go to the top of the page
 
+Quote Post
Alex B._
сообщение Nov 14 2006, 09:56
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274



>> Другими словами, там, где я кормлю CCP2CON в программе
>> можно поставить установку в 1 линии PORTB? И всё?
Да, можно.

>> А философски,- это недочёт Микрочип!
Compare работает так как должен. Для генерации последовательность импульсов предназначен режим PWM, я вам об этом уже говорил.

Вот это посмотрите, может быть поможет (формирование J1850-PWM физического уровня):

Код
void interrupt IRQ(void)
{
    u08 port_tmp;
    
    if (PIR1_bit.CCP1IF)
    {
        PIR1_bit.CCP1IF = 0;
        // -----------------------------------------------------------------------------------------
        // J1850-PWM TX Service
        // -----------------------------------------------------------------------------------------
        if (Sys_CurrMode.JTX)
        {
            static u08 data;                        // Transiever reg
            static u08 bit_cnt;                     // Bit counter
            static u08 nxt_l;                       // Next pulse length (for 0 or 1)

            TMR1L = 0;                              // Clear compare timer

            // Falling edge of bit pulse
            // -------------------------
            if      (J1850_T_STM.b.B_F_F)
            {
                CCPR1L = nxt_l;                     // Set compare interval (0 part of data bit)
                J1850_T_STM.full = 0;               // Clear J1850-TX state machine

                // Data BYTE was send
                if (--bit_cnt == 0)
                {
                    if (--DATA_cnt == 0)
                    {
                        // End of packet
                        // -------------
                        J1850_T_STM.b.BYTE_SN = 1;                  // Set next state of state machine
                        CCP1_Comp_Next_Clr();                       // Next edge will be falling (NO EDGE)
                    }
                    else
                    {
                        // End of byte -> load next byte
                        // -----------------------------
                        data = DATA_Buff[DATA_Buff_indx++];         // Load next byte to byte buffer
                        bit_cnt = 8;                                // Update bit per byte counter
                        J1850_T_STM.b.B_R_F = 1;                    // Set next state of state machine
                        CCP1_Comp_Next_Set();                       // Next edge will be rising
                    }
                }
                // Prepare for send next byte
                else
                {
                    // Next bit
                    // --------
                    J1850_T_STM.b.B_R_F = 1;                        // Set next state of state machine
                    CCP1_Comp_Next_Set();                           // Next edge will be rising
                }
            }

            // Rising edge of bit pulse
            // ------------------------
            else if (J1850_T_STM.b.B_R_F)
            {
                // 1 data bit = Set compare interval 8 us,  next interval - 16 us
                if (data & 0x80) {CCPR1L = 40 - 16; nxt_l = 80 - 16;}  
                // 0 data bit = Set compare interval 16 us, next interval - 8  us
                else             {CCPR1L = 80 - 16; nxt_l = 40 - 16;}
                CCP1_Comp_Next_Clr();                               // Next edge will be falling

                data <<= 1;                                         // Shift data byte          
                J1850_T_STM.full = 0; J1850_T_STM.b.B_F_F = 1;      // Set next state of state machine
            }

            // Rise fornt of SOF pulse
            // -----------------------
            else if (J1850_T_STM.b.SOF_R_F)
            {
                CCPR1H = 0; TMR1H  = 0;                             // Clear MSB of compare timer
                CCPR1L = 160 - 16;                                  // Set compare interval (32 us)
                CCP1_Comp_Next_Clr();                               // Next edge will be falling
                
                data = DATA_Buff[DATA_Buff_indx++];                 // Load first data byte
                bit_cnt = 8;                                        // Set bit per byte counter
                J1850_T_STM.full = 0; J1850_T_STM.b.SOF_F_F = 1;    // Set next state of state machine
            }

            // Fall fornt of SOF pulse
            // -----------------------
            else if (J1850_T_STM.b.SOF_F_F)
            {
                CCPR1L = 80 - 16;                                   // Set compare interval (16 us)
                CCP1_Comp_Next_Set();                               // Next edge will be rising
                J1850_T_STM.full = 0; J1850_T_STM.b.B_R_F = 1;      // Set next state of state machine
            }

            // Send EOP - End packet
            // ---------------------
            else if (J1850_T_STM.b.BYTE_SN)
            {
                TMR1H = 0;                                          // Clear MSB of compare timer
                CCPR1H = (360 - 16) >> 8;                           // Load compare reg
                CCPR1L = (360 - 16) & 0xFF;
                J1850_T_STM.full = 0; J1850_T_STM.b.EOF = 1;        // Set next state of state machine
            }

            // EOF was send - PACKET SEND
            // --------------------------
            else if (J1850_T_STM.b.EOF)
            {
                J1850_T_STM.full = 0;                               // Clear J1850-TX state machine
                PIE1_bit.CCP1IE = DISABLE;                          // Disable Compare Interrupts
                Sys_Events = SE_J1850_SEND_FRAME;                   // Set System Event
            }
        }
.......
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 17:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01497 секунд с 7
ELECTRONIX ©2004-2016