Здравствуйте радиоКоты
подскажите кто писал на С. компилятор hitech PICC
Проблема такая: необходимо реализовать подсчет импульсов в асинхронном режиме с внешнего источника тактовых импульсов таймером Timer1, в момент прихода импульса на INT/RB0, прерывание, в программе обработки прерывания значение TMR1 (TMR1H и TMR1L) необходимо преобразовать в ШИМ импульс, с выводом на ноге RB3. Програмку сочинил, вроде все должно работать правильно(в железе не проверял) но в протеусе работает не правильно, почему то считает 3 раза больше импульсов, все перепровериль, даташить перепрочиталь
не могу найти где собака зарыта, или протеус неправильно симулирует. частота кварца 4МГц . Буду весьма благодарень.
тут проект и исходник на C
Вложение:
Комментарий к файлу: проект протеусе и исходник
test_c_imp_to_PWM.rar [14.23 KiB]
Скачиваний: 820
Код:
#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
}