roboforum.ru

Технический форум по робототехнике.

Замерить сервосигнал Hi-Tech

Замерить сервосигнал Hi-Tech

Neman2000 » 23 авг 2009, 16:32

Помогите пожалуйста с кодом-неполучается измерить длительность
входного сигналла?,чтобы записать ее в переменную А (для формирования ШИМ.)
при записи вместо А числа 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. В начале каждого фрагмента обработчика, относящегося к своему источнику прерываний, следует
использовать условный оператор, проверяющий состояние соответствующего флага. При этом не стоит забывать о необходимости
сбрасывать этот флаг до того, как завершится обработка прерывания.

Re: Замерить сервосигнал Hi-Tech

nest » 23 авг 2009, 17:26

ы...
что за задача то вообще ?
что за "сервосигнал Hi-Tech" ?

Re: Замерить сервосигнал Hi-Tech

blindman » 23 авг 2009, 18:05

Видимо, управление коллекторным двигателем через стандартную р/у аппаратуру.

Re: Замерить сервосигнал Hi-Tech

Neman2000 » 23 авг 2009, 18:36

Да,управление коллекторным двигателем через стандартную р/у аппаратуру.
Мне нужен алгоритм замера длительности входного сигнала прерываниями от таймера(с помощью RTC-счетчик реального времени),тоесть используя только один TMR0

Re: Замерить сервосигнал Hi-Tech

nest » 23 авг 2009, 19:31

Код: Выделить всёРазвернуть
настроили INT0-прерывание на фронт.
настроили INT1-прерывание на спад.
включили счётчик на нужном предделителе.
сбросили какой нибудь флаг "готовности"
разрешили INT0-прерывание.
..

main цикл{
проверили установку флага "готовности".
если не установлен - крутимся в цикле дальше.
если установлен - считываем счётчик и оперируем с данными,
              а затем взводим прерывания, счётчик и флаги в исходное состояние.
}

..
INT0:
обнулили счётчик.
разрешили INT1-прерывание.
ret

INT1:
остановили счётчик.
запретили INT0-прерывание.
запретили INT1-прерывание.
установили флаг "готовности".
ret


где не понятно ? :)

Re: Замерить сервосигнал Hi-Tech

=DeaD= » 23 авг 2009, 19:43

Еще бы от помех на входе RC-цепь минимальную наверное? :oops:

Re: Замерить сервосигнал Hi-Tech

nest » 23 авг 2009, 19:46

ну ему с кодом надо помогать, а не со схемотехникой.

Re: Замерить сервосигнал Hi-Tech

Masterovoi » 23 авг 2009, 22:27

Советую вам использовать для измерения длины импульса специальный модуль захвата сравнения и генерации ШИМ - CCP. Вот статья подробная с графическими иллюстрациями по режимам модуля CPP PIC - захват и генерация ШИМ, обработка сигналов с энкодеров и измерение скорости - http://stream.ifolder.ru/13668136

Re: Замерить сервосигнал Hi-Tech

krant » 25 авг 2009, 18:44

А почему нельзя через таймер вычислить период ? Хотя точность конечно же будет маленькая, но я думаю небольшая градация всё-таки будет присутсвовать. Алогритм писать ?

P.S. в хелпе протуса можно почитать про захват ШИМ

Re: Замерить сервосигнал Hi-Tech

avr123.nm.ru » 28 авг 2009, 12:59

Neman2000 писал(а):а проектик для MPLAB+Hi-Tech и Протеуса как прикрепить?

Вопросы к вам:
=============
1) Что вы хотели сделать ИМХО СТРАННЫМИ для Си строками ?

Код: Выделить всёРазвернуть
on_RTC != off_RTC; // Время начала и конца сигнала неравны.
off_RTC=RTC;       // Записываем в переменную-off_RTC время начала сигнала
off_RTC-on_RTC100; // Отделяем полезный сигналл(1,5мс) от периода между сигналлами(20мс)
A==off_RTC-on_RTC; //Записываем в переменную А время
                   //разности между прерываниями(время сигналла)


Возможно "язык Си для микроконтроллеров" - http://proavr.narod.ru/05.htm - вам поможет изложить идеи на Си.

=============
2) зачем вам "case" если LED 0 только при 0 а в остальных вариантах выбора он 1 ???

=============
3) Вы хотите измерять импульс 1000-2000 мкС а частота прерываний и инкремента счетчика RTC у вас 132 мкС - грубовато будет.

=============
4) Где у вас ШИМ размером А ?

Вот приложил проекты PROTEUS 7.5 sp3 MPLAB 8.33 и HiTech PICC 9.50 - просто сделайте вместо того к чему у меня вопросы п.1) код определения фронта сигнала и запомните RTC и затем ожидание спада и вычисление разности RTC.

и нехай RTC считается побыстрей.

P.S. прочитайте пожалуйста о параметрах ШИМ сигнала на страничке http://proavr.narod.ru/z8.htm
а то у вас в коментах просто диво дивное понаписано.

Добавлено спустя 5 минут 6 секунд:
krant писал(а): P.S. в хелпе протуса можно почитать про захват ШИМ
Не нашел. Где там подскажите ?!
Вложения
avr123.nm.ru.rar
(43.69 КиБ) Скачиваний: 22


Rambler\'s Top100 Mail.ru counter