входного сигналла?,чтобы записать ее в переменную А (для формирования ШИМ.)
при записи вместо А числа 0.....149-ШИМ работает нормально.
Пытался получить число-длительность(А) как разность тиков счетчика-RTC в прерывании по изменению сигнала.
Прилагаю текст шаблона Предко исходник на Си,
а проектик для MPLAB+Hi-Tech и Протеуса как прикрепить?.
- Код: Выделить всё • Развернуть
//###-РЕГУЛЯТОР ОБОРОТОВ КОЛЛЕКТОРНОГО МОТОРА-###
// При изменении длины сигнала(1...2мс) меняется ШИМ от 0вольт до +5вольт
//
// ---------------- Вход сигнала-6я нога ,выход ШИМа-17я нога------------------------
//
// Сигнал
// +--+
// ПЕРИОД | | ПЕРИОД
// ---------+ +--------
//
// 20 ms |1,5ms| 20 ms |
//
// ------------------- PIC16F628 Running 4MGz---------------------------------
#include <pic.h>
#define SIGNAL RB0 //Вход сигнала(сигналл равен ЕДИНИЦЕ(+5в))
#define LED RA0 //Вывод ШИМа
#define trisLED TRISA0
#define ZAPIS_TMR0 200 // Число для записи в TMR0
//*****Переменные для формирования програмного ШИМа//*********
unsigned char Ciklov; // Счетчик циклов от 0 до 150
unsigned char Dlitel; // Длительность импульса
//**********Переменные замера входного СИГНАЛА*****************
unsigned int on_RTC; // Начало сигналла(по нарастанию фронта)
unsigned int off_RTC; // Конец сигналла(по спаду)
unsigned char A;// Переменная А численно равна длине сигнала
volatile unsigned int RTC=0; //Счетчик реального времени
//*******************-------- Биты конфигурации ----------*******************
__CONFIG (INTIO //Внутренний генератор,
& UNPROTECT //выключить защиту памяти,
& BORDIS //включить контроль питания,
& MCLRDIS //отключить вывод начальной установки,
& PWRTDIS //включить таймер задержки запуска,
& WDTDIS //выключить сторожевой таймер,
& LVPDIS ); //запретить низковольтное программирование.
//*******Предварительные объявления подпрограмм*******************
//********Обработчик прерываний от таймера:*********************
void interrupt tmr0_int(void) //Обработчик прерываний
{
if (T0IF) //сбросить флаг
{
TMR0=ZAPIS_TMR0; // Запись в регистр TMR0 числа для сокращения
//время счета(256тиков - 200тиков=56тиков)
// Если запрос на прерывание поступил от таймера ТМR0,
T0IF = 0; // то сбросить флаг прерывания
//*****Здесь можно описать дополнительные действия для обработки прерываний от таймера*****
RTC++; // Каждый цикл прибавлять по единице
switch(Dlitel)
{ // Проверить на крайние значения
case 0: // Если задана нулевая ширина импульсов
LED = 0; // То держать низкий уровень
break;
case 150: //Если ширина импульсов равна периоду
LED = 1; // То держать высокий уровень
break;
default: //В противном случае
// Если значение счетчика циклов меньше заданной ширины импульса
if (Ciklov <= Dlitel)
LED = 1; // то держать высокий уровень
else // Впротивном случае низкий уровень
LED = 0;
} // Конец оператора switch
if (Ciklov ++ == 150)// Длительность перида ШИМа-150ступеней,
//переполнений таймера-TMR0(по 56тиков одно переполнение)
{ // Конец текущего периода?
Ciklov = 0; // Да,сброс счетчика циклов
} // endif
} // endif
//*****Здесь можно разместить код для установки других прерываний*******
if(INTF) // Прерывание по входу PORT B0
{
on_RTC=RTC; // Записываем в переменную-on_RTC время окончания сигнала
on_RTC != off_RTC; // Время начала и конца сигнала неравны.
off_RTC=RTC; // Записываем в переменную-off_RTC время начала сигнала
off_RTC-on_RTC<100; // Отделяем полезный сигналл(1,5мс)
//от периода между сигналлами(20мс)
A==off_RTC-on_RTC; //Записываем в переменную А время
//разности между прерываниями(время сигналла)
INTF=0; // сбросить флаг
}
} // Конец обработчика прерывани
//#############СЛУЖЕБНАЯ ПРОГРАММА##################
void enableLED(int LEDstate) // Установить состояние светодиода
{
//В соответствие со значением LEDstate
LED = 0; // Сначала светодиод негорит
if (LEDstate)
{
Ciklov = 0; // Обнулить счетчик циклов
Dlitel=A; // РАЗМЕР ШИМа ОПРЕДЕЛЯЕТ А,
//если вместо а подставить цифру от 1 до 149 то ШИМ работает,
// а при подстановке А неработает?????
trisLED = 0; // Вывод управления светодиодом переводим в режим выходного
}
else
trisLED = 1; // Вывод управления светодиодом переводим в режим входного
//Светодиод потушен
} //Конец служебной программы
//##########ГЛАВНАЯ ПРОГРАММА:###################
void main (void) //Начало основной программы
{
OPTION = OPTION = 0b11010000; // использовать предделитель
//совместнос таймером ТМR0, коэффициент
// деления 2.( последние три разряда справа 111-/256,110-/128,
//101-/64,100-/32,011-/16,010-/8,001-/4,000-/2.)
TMR0 = 0; // Начальный сброс таймера TMR0
T0IE = 1; // Разрешить прерывания от таймера.
GIE = 1; // Разрешить обработку всех прерываний.
//**** Здесь надо выполнить инипиализапию периферийных устройств.*****
RBIE=1; // Разрешить прерывания по изменению сигнала на входе
INTE=1; // Разрешить прерывания по INT96 нога проца)
enableLED(1); //Включить светодиод и выполнить инициализацию параметров
while (1==1) //Бесконечный цикл
{ // endif
} // endwhile Конец оператора while.
} // End of Mainline Конец главной программы.
Переменная RТС является глобальной. Она объявлена в программе вне какой бы то ни было функции и поэтому может быть
использована для чтения и/или записи внутри любой из них, в том числе и в процедуре обработки прерываний. Модификатор
volatile указывает, что компилятор не будет оптимизировать доступ к этой переменной, пытаясь подставлять во все выражения
ее предыдущее значение, ведь оно может в любой момент (незаметно для главной программы) измениться в результате выполнения
обработчика прерываний.
Переменная RТС описана как беззнаковая (unsigned), поэтому ее значение может быть в диапазоне от 0 до 65535 (0х0FFFF).
Напомним, что возможные значения обычных переменных типа iпi лежат в диапазоне от -32768 до +32767.
Код процедуры обработки прерываний располагается отдельно от остальной программы, в микроконтроллерах Рic miсrо он начинается
с адреса 0х0004. Главная программа и вызываемые функции размещаются в конце памяти программ.
Функция, описанная как обработчик прерываний (с модификатором interrupt), будет вызываться каждый раз, когда произойдет
какое-нибудь прерывание. Поэтому в первую очередь требуется определить источник запроса. Для этого мы проверяем, установлен
ли флаг TOIF прерывания от таймера. Если он установлен, значит произошло переполнение таймера и надо выполнить инкремент
счетчика RТС. В противном случае прерывание было запрошено другим устройством, поэтому никаких действий со счетчиком
реального времени выполнять не следует.
Если в нашем приложении требуется обрабатывать запросы и других источников, то соответствующий код надо поместить после
условного оператора if. В начале каждого фрагмента обработчика, относящегося к своему источнику прерываний, следует
использовать условный оператор, проверяющий состояние соответствующего флага. При этом не стоит забывать о необходимости
сбрасывать этот флаг до того, как завершится обработка прерывания.