Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

вопрос по Hi tech С реализация 16 битный ШИМ на PIC16F628A

Ср июл 25, 2012 21:50:02

Здравствуйте радиоКоты :) подскажите кто писал на С. компилятор hitech PICC
Проблема такая: необходимо реализовать подсчет импульсов в асинхронном режиме с внешнего источника тактовых импульсов таймером Timer1, в момент прихода импульса на INT/RB0, прерывание, в программе обработки прерывания значение TMR1 (TMR1H и TMR1L) необходимо преобразовать в ШИМ импульс, с выводом на ноге RB3. Програмку сочинил, вроде все должно работать правильно(в железе не проверял) но в протеусе работает не правильно, почему то считает 3 раза больше импульсов, все перепровериль, даташить перепрочиталь :sleep: :cry: не могу найти где собака зарыта, или протеус неправильно симулирует. частота кварца 4МГц . Буду весьма благодарень.
тут проект и исходник на C
test_c_imp_to_PWM.rar
проект протеусе и исходник
(14.23 KiB) Скачиваний: 817



Код:
#include <pic.h>
__CONFIG (INTIO & UNPROTECT & LVPDIS & BOREN & MCLRDIS & PWRTEN & WDTDIS);// осцилятор кварц 4МГц
#define IN_CONVERT_ON RB0 // Вход импульс начала преобразования
#define IN_IMPULS RB6 // Вход счетных импульсов
#define OUT_PWM_IMPULS RB3 // Выход импульса ШИМ
const unsigned char Minimal_PWM = 100;

////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////// Обработчик прерываний///////////////////////////////////////////////////////
void convert(void); // предварительное объявление функции
void interrupt INT_RB0 (void)
         {
            GIE = 0;//запретить все прерывания
         INTE = 0;// запретить прерывание от INT
         INTF = 0;//сбросит флаг внешнего прерывания от входа INT
         convert();
         INTE = 1;
         GIE = 1;    
         }
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// Инициализация модуля CCP в режиме сравнения с установкой HI на выводе CCP1 при совпадении
void init_compare_regim_CCP (void){
    CCP1CON = 0; //выключить модуль ССР
   TMR1H=0; TMR1L=0; //очистить таймер1,
   TRISB &= 11110111; // настроить вывод ССР на выход
   PIE1 = 0; // выключить периферийные прерывания
   PIR1 = 0; //сброс всех флагов периферийных прерываний
   CCP1CON = 0b00001000; // Режим сравнения, установить HI на ССР по соответствию данных
   TMR1ON = 1; // Разрешить приращение TMR1
                 }
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////

void convert(void){

   TMR1ON = 0; // счет TMR1 отключен
   TMR1CS = 0; // тактирование от такта системной синхронизации
   CCPR1L = TMR1L;
   CCPR1H = TMR1H;
   init_compare_regim_CCP();   
   
   
              while (CCP1IF == 0){}//пока не закончится импульс !ШИМ ждать                           
                 CCP1IF = 0;
                 CCP1CON = 0; //отключить модуль CCP1
            
             TMR1L=Minimal_PWM;
             TMR1H=0;
             T1CON = 0b00000111; // асинхронный счет с ноги IN_IMPULS
             }   

////////////////////////////////////////////////////////////////////////////////////////////////////////////
      
   
void main (void){
// подготовка
TRISA = 0b00000000; //
TRISB = 0b01000001; /*RB0-импульс начала конвертирования
                          RB6-счетные_импульсы
                     RB3_ССР1-выход шим импульса с периодом 2мс*/
CMCON = 0x07; // отключение компараторов
PORTA = 0; // очищаем порт А
PORTB = 0; // очищаем порт Б
RBPU  = 1;  // подтягивающие R (0-вкл, 1-выкл)

TMR1H = 0;
TMR1L = 100;
T1CON = 0b00000111;
T0CS = 1;
T0SE = 0;
TMR0=0;
CCPR1H=0;CCPR1L=0; // обнуление регистров сравнения
/////////////////инициализация прерываний///////////////////////////////////
GIE = 0; //глобально запретит
INTE = 0; //от входа INT/RB0 запретить
INTF = 0; // сбросить флаг прерывания от INT/RB0
INTEDG = 0; // прерывания на INT/RB0 по спаду
INTE = 1; //от входа INT/RB0 разрешить
GIE = 1; //глобально разрешить


//---------- прога-------------------------------------
//----------
   while(1){} // ждать прерывания от INT/RB0 

}
Последний раз редактировалось Аlex Ср июл 25, 2012 22:17:15, всего редактировалось 1 раз.
Причина: код
Тема закрыта