59 сообщений 59 4 спасибо за тему 4
Опции темы
Pugnator

Agassy, и опиши что за баг, чтобы не слишком долго искать того, чего нет

Еще немного добавлю. Сегодня эксперементировал с TMR1, выставил прерывание, с интервалом в 1сек, в обработчик прерывания ввел инверсию бита RB7.
Так вот при отладке в MicroC PRO, все отрабатвает, как задуманно!
В Proteus, инверсия срабатывает только один раз и то через раз smile.gif
PIC 16F628A
Критерием истины - является практика ! (с)
---
Difficult we made yesterday impossible we are making now!
Agassy, больше похоже на то, что в протеусе пик работает под другой частотой. Связано с ошибками при создании проекта в МикроС. Накалывался на такое не раз. Уж что-что, а прерывание по таймеру протеус отрабатывает нормально.
Classic forever!
Oxygen

Agassy, больше похоже на то, что в протеусе пик работает под другой частотой. Связано с ошибками при создании проекта в МикроС. Накалывался на такое не раз. Уж что-что, а прерывание по таймеру протеус отрабатывает нормально.

Да, вроде одинаково выставлено, по 1MHz...тоже накалывался, посему проверяю частенькоwink.gif

Критерием истины - является практика ! (с)
---
Difficult we made yesterday impossible we are making now!
та главное не как потом выставил, а как создал изначально проект.
Я так понимаю при каждом вызове прерывания у тебя идет инверсия, а прерывание раз в секунду?
Classic forever!
Oxygen

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

Может быть, может быть...но мой опыт говорит, что если поменять тактовую, пересобрать проект - все ок!
Можно и открыть проект заново, не вопрос smile.gif

Я так понимаю при каждом вызове прерывания у тебя идет инверсия, а прерывание раз в секунду?

bs.gif
на большое кол-во комментов, не обращай внимания, это был творческий процесс по выходу из тупика smile.gif

Код

void interrupt() {
PORTB.B7=~PORTB.B7;
//if (PIR1.TMR1IF == 1) {
//LED =~LED;
//PORTB.B7^=PORTB.B7;
// }

PIR1.TMR1IF = 0;
TMR1H = 0xB;      // preset for timer1 MSB register
TMR1L = 0xDC;     // preset for timer1 LSB register
}
Критерием истины - является практика ! (с)
---
Difficult we made yesterday impossible we are making now!
Для проекта на 8МГц. Ты решил через CCP1 но это геморный и ненужный путь
Кроме того ты инвертируешь неправильно.
LED!=LED;
Это утверждение, что 1 не 1. Оно не верно и все.

Вот 3 способа перевернуть бит
LED=!LED;
LED=~LED;
LED^=1;

Вот тахометр с описанием. Используется ТМР0 для замера времени и INT0 прерывания для подсчета импульсов

Код
//Для частоты 8МГц
//PC16F628A
//Переменная хранит счетчик таймера для подсчета точной секунды
unsigned long time;
//Счетчик импульса зажигания
unsigned counter;
//Переменная хранит обороты мотора
unsigned rpm;
//Буфер для ЖКИ
char out1[8];
//4 пробела для быстрой очистки 4 знаков оборотов, например если было 1000
//и стало 999, дабы убрать 0. Вызов LCD_CLEAR гораздо тормознее и будет виден
//как мигание
char clear[8]={"    "};

//Инициализируем ЖКИ

sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;
sbit LCD_D6 at RA2_bit;
sbit LCD_D7 at RA3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISA2_bit;
sbit LCD_D7_Direction at TRISA3_bit;

void init()
{
//Запуск прерываний всех
  GIE_bit  = 1;
  
  /* TMR0 */
  TMR0IE_bit = 1;
  TMR0IF_bit = 0;
//ТМР0 будет считать 1 секунду, из-за известного ограничения, чтобы считать
//точно, ТМР0 крутится без делителя и без управления сам по себе на полной
//скорости
  T0CS_bit = 0;
  T0SE_bit = 0;
  PSA_bit  = 1;
  PS2_bit  = 0;
  PS1_bit  = 0;
  PS0_bit  = 0;
//Единственная начальная установка счетчика
  TMR0 = 0;
//Ногу RB0/INT ставим на вход, на неё будет подаваться импульсы тахометра
  TRISB.RB0=1;
//Заводим ЖКИ
  LCD_init();
//Ждем 0.1сек пока Экран запустится
  delay_ms(100);

}
//Прерывания
void interrupt()
{
//На каждом переполнении ТМР0
  if(TMR0IF_bit)
     {
     TMR0IF_bit=0;
     //прибавляем значение 256 (8бит)
     time+=256;
     //Если для частоты 8МГц прошла 1 секунда
     if(time >= 1000000)
    {
    //Вертаем назад, но не обнуляем, тем самым убирая любую ошибку
    time -= 1000000;
    //Сохраняем обороты
    rpm=counter;
    //Обнуляем счетчик
    counter=0;
    }
     }
     //На каждом импульсе на ноге
  if (INTF_bit)
     {
     INTF_bit = 0;
     //Инкрементируем. Для 4-х цилиндров ничего делать не надо
     //Тут итак будет F/2
     counter++;
     }
}
void main()
{
//Собственно, инициализируем всё железо
  init();
//Очищаем экран
  lcd_cmd(_LCD_CLEAR);
//Выключаем курсор
  lcd_cmd(_LCD_CURSOR_OFF);
//Раз и навсегда вывдим на экран RPM:
  lcd_out(1,1,"RPM:";);
//Бесконечный цикл
  for(;; )
      {
      //Обновляем экран раз в секунду
      delay_ms(1000);
      //Умножаем на 60 и получаем об/мин
      rpm*=60;
      //Конвертим обороты в строку
      IntToStr(rpm,out1);
      //Удаляем незначащие пробелы слева
      lTrim(out1);
      //Убираем старое значение всегда, для простоты
      lcd_out(1,5,clear);
      //Выводим на экран обороты
      lcd_out(1,5,out1);
      }
}
Excuses are like assholes: everybody's got one
Agassy, Погодь, а что за переменная ЛЕД у тебя?
Classic forever!
Pugnator

Для проекта на 8МГц. Ты решил через CCP1 но это геморный и ненужный путь
Кроме того ты инвертируешь неправильно.
LED!=LED;
Это утверждение, что 1 не 1. Оно не верно и все.

Вот 3 способа перевернуть бит
LED=!LED;
LED=~LED;
LED^=1;

...

c LED!=LED, это уже описался...smile.gif
но даже остальные два варианта, не работают!

За код спасибо! всегда интересно посмотретьsmile.gif

Но вопрос, был немного другой, отрабатывает ли в Proteus в обработчике прерывания, инверсия бита?

Oxygen

Agassy, Погодь, а что за переменная ЛЕД у тебя?

были такие варианты...

//sbit LED at RB7_bit;
//sbit LED at PORTB.B7;

пс Мужики! Можт отдельную тему, про контроллеры замутим?
Это, конечно радостно, что в теме о негативе, появляются позитивные постыsmile.gif, но так будет сложнее отыскать мудрые мысли, по теме контроллеров. smile.gif
Критерием истины - является практика ! (с)
---
Difficult we made yesterday impossible we are making now!
Agassy, работает инверсия и мигает.
Создай тему, чо
Excuses are like assholes: everybody's got one
Pugnator

Agassy, работает инверсия и мигает.
Создай тему, чо

ок! Спасибо! буду копать дальше wink.gif
Создать, то не вопрос - я посты боюсь не перенесу...
Критерием истины - является практика ! (с)
---
Difficult we made yesterday impossible we are making now!
спс 1 Кто сказал спасибо Agassy +1 1 Кто согласен с автором Agassy
Сабж
Excuses are like assholes: everybody's got one
точно! подписался.

Agassy,
Тогда погоди...
не совсем курю синтаксис Си, но вот объясни:
----------------
//LED =~LED;
//PORTB.B7^=PORTB.B7;
----------------

Что ты хотел сделать первой строчкой, а что - второй?
Classic forever!
Oxygen

точно! подписался.

Agassy,
Тогда погоди...
не совсем курю синтаксис Си, но вот объясни:
----------------
//LED =~LED;
//PORTB.B7^=PORTB.B7;
----------------

Что ты хотел сделать первой строчкой, а что - второй?


Наверное проскочил пост Pugnator

Pugnator

Для проекта на 8МГц. Ты решил через CCP1 но это геморный и ненужный путь
Кроме того ты инвертируешь неправильно.
LED!=LED;
Это утверждение, что 1 не 1. Оно не верно и все.

Вот 3 способа перевернуть бит
LED=!LED;
LED=~LED;
LED^=1;

...
Критерием истины - является практика ! (с)
---
Difficult we made yesterday impossible we are making now!
а ты уверен что никакое другое прерывание не вызывается? Ведь в конечном коде ты инвертируешь при любом прерывании. Мало ли чего оно прерывается, например, насколько помню, в конфиге есть бит прерывания перехода на внутренний кварц при фейле внешнего. А у тебя как раз внешнего в протеусе не присрано.
Ну, как вариант.
Classic forever!
Oxygen, не,не. протеус кварц не симулирует внешний так и так.
PORTB.B7^=PORTB.B7;

Такое работать не будет
Excuses are like assholes: everybody's got one

Войти, чтобы ответить.