Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: pic16f883 не срабатывают прерывания по изменению
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > PIC
misemikl
Не срабатывают прерывания по изменения ноги, суть заключается в том что приходит сигнал на пятую ножку В, как только приходит постоянный ноль,должно сработать прерывание...помогите пожалуйста...я недавно начал разбараться с пиками...вот программа


#include "I2C_FUNC.h"
void main() {
unsigned short temp_reg = 0;
int dat;
char prev_val1, prev_val2,temp=0;
bit state, state1;


OSCCON = 0b01110101;
ANSEL=0x00;
TRISA = 0b00000000; // Configure PORTA as input 0-output 1 - input
PORTA = 0b00000000;
TRISB = 0b11101111;
PORTB = 0b01011110;
TRISC = 0b00000001;
PORTC = 0b11111000;

INTCON = 0b11001000; //allow all interrupts
IOCB=0b00100000;

I2C1_Init(100000);
Delay_ms(2);
i2c_cycle(0x02,0x00); //inicialization reg 0x02
Delay_ms(2);
i2c_cycle(0x0B,0x10); //inicialization reg 0x0B
Delay_ms(2);
i2c_cycle(0x0C,0x84); //inicialization reg 0x0C
Delay_ms(2);
i2c_cycle(0x09,0x00); //inicialization reg 0x09
Delay_ms(2);
i2c_cycle(0x0A,0x12); //inicialization reg 0x0A
Delay_ms(2);

dat = 0xAC;
i2c_cycle(0x03, dat);
Delay_10ms();
I2C1_Stop(); //issue I2C stop signal //magnitola

// Init Timer0

INTCON.B2 = 0;
INTCON.B0 = 0;
OPTION_REG = 0b00000111; // prescale 1:256 - four times the delay.
TMR0 = 0b00000000; // clear timer


//Init Timer1
PIE1.B0 = 0; // clear roll-over interrupt flag
TMR1H = 0;
TMR1L = 0;
T1CON = 0b00000101;
pir1.b0 = 0;

while(1)
{

}
}
void interrupt()
{
if(IOCB.B5==1)
{
TMR1H = 0;
TMR1L = 0;
intcon.b0 = 0;
pir1.b0 = 0;

TMR0 = 0;
intcon.b2 = 0;
intcon.b0 = 0;

INTCON.B0 = 0;
IOCB.B5=0;
}
}
xemul
Не void interrupt(), а void interrupt имя_функции_не_важно().
misemikl
Я пишу в mikroC PRO, он ругается если вводишь имя функции
xemul
Цитата(misemikl @ Oct 15 2012, 15:06) *
Я пишу в mikroC PRO, он ругается если вводишь имя функции

Тогда подробности смотрите в мануале mikroC.
Сорцы программ оформляйте тегами code, /code (иконка с рулоном бумаги и зелёной стрелкой).

А по программе:
- пишите комменты к 0b1010101010101, лучше в дифайнах и побитово (чтобы не лезть в ДШ из-за склероза);
- прерывание от IOCB может выглядеть как-то так (подробности по именам битов за Вами):
Код
volatile uint8_t prev_PORTB;  // нужно хранить предыдущее состояние входов PORTB

void main(void)
{
...
// где-то после инициализации TRISB
   prev_PORTB = PORTB & (TRISB_CFG & IOCB_CFG);
// 0b01011110 и 0b00100000 в Вашем случае
// ошибку видите?
// & (TRISB_CFG & IOCB_CFG) можно упростить до & IOCB_CFG, если TRISB и IOCB далее не меняются
// если меняются, вероятно стоит завести что-то вроде IOCB_mask = TRISB & IOCB;, обновляемую по случаю.
...
}

void interrupt()
{
   if(RBIF) // приключилось прерывание от разрешённых в IOCB ног
   {
// выделили изменившиеся ноги
      uint8_t tmp = (PORTB ^ prev_PORTB) & IOCB_CFG;
//      uint8_t tmp = (PORTB ^ prev_PORTB) & IOCB_mask;
// далее придётся каким-то образом перебрать все ноги, разрешённые в IOCB (или IOCB_mask);
      if(tmp & (1<<0)) { ... };  // а ногам можно дать осмысленные дифайны
      if(tmp & (1<<1)) { ... };
      ...
// обновить prev_PORTB
      prev_PORTB ^= tmp;
// сбросить RBIF
      RBIF = 0;
   }
}

Цитата
приходит сигнал на пятую ножку В, как только приходит постоянный ноль,должно сработать прерывание

RBIF будет устанавливаться в 1 по _изменению_ любого разрешённого в IOCB бита PORTB, а не по постоянному нулю.
Если до момента "tmp = (PORTB ^ prev_PORTB) & IOCB_CFG;" нога вернётся в прежнее состояние, её изменение, естесно, не будет обработано.
Если состояние ноги изменится после "tmp = ...", но до "RBIF = 0;", это изменение тоже может быть пропущено.
misemikl
// где-то после инициализации TRISB
prev_PORTB = PORTB & (TRISB_CFG & IOCB_CFG);
// 0b01011110 и 0b00100000 в Вашем случае
// ошибку видите?


TRISB = 0b11101111&IOCB=0b00100000;

почему не правильно? вроде трисВ настроен на вход и там и там,а портВ это состояние изначально.
xemul
Цитата(misemikl @ Oct 16 2012, 10:45) *
TRISB = 0b11101111&IOCB=0b00100000;

почему не правильно? вроде трисВ настроен на вход и там и там,а портВ это состояние изначально.

Извините, криво скапипастилось.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.