Jump to content

felipe

EstablishedMember
  • Content Count

    8
  • Joined

  • Last visited

Community Reputation

0 Neutral

About felipe

  • Rank
    Newbrie
  1. Hi dersk, yes the single interrupt scheme is peculiar to PICs. See, PICs have one reset vector 0x0000 and one interrupt vector 0x0004. Pics 18FXX and up have two interrupt vector, low priority (0x0004)and a high priority(0x0008, i think) interrupt vectors. On interrupt program flow branches to interrupt vector.Now, for a branching to the interrupt vector to occur three things must happen: 1) That particular interrupt must be eneabled 2) General interrupt bit on intcon register must be set(eneabling general interrupts) 3) The flag of that particular interrupt gets set. Once in interrupt service routine, is up to you to determine(testing the repective interrupt flags) wich one caused the interrupt(that is if you have more that one interrupt enabled, of course). Don´t forget to clear those flags before returning from interrupt. Notice one thing: If you enable one particular interrupt, but do not enable general interrupt, once that interrupt ocurs program flow will continue on the value that program counter had before interrupt + 1. If you want, I´ll put some example in C and assembler, just ask
  2. I think I solve it !! . As I was getting more and more frustrated, I decided to go for a simpler infrared code format wich doesn´t have separate repeat code, is an old bi-phase, six bit code format from siemens. Wich is simpler, so I could concentrate on getting the wake up on interrupt thing going. Well as it turns out, once you come back from interrupt, the ports doesn´t retain the original configuration( analog comparators get turn on when they where off before interrupt). So now, I turn comparators off again, and load values in porta and portb, before coming back from interrupt. Also I put a "while" loop in the interrupt service routine, to compare the value that portb should have with no key pressed, so if the key still pressed I scan the keyboard again BEFORE leaving the interrupt service routine. As soon as I have the time I think I´ll upload a post on dealing with wake up from sleep on interrupts, because I think it might benefit beginners like me.
  3. The idea is: once I have an interrupt, I scan the keyboard to detect wich key was pressed, wich can have three results : A _ No key was pressed(i.e. after debounce no key is detected as valid) B _ New key was pressed. C _ The same key was pressed. In case A, I stop the timer, clear al flags, and set for interrupt on RB7:RB4 change, go back to sleep. I case B, I prepare the timer, transmit key code, interrupt on RB7:RB4 change is NOT set, and got back to sleep. Now since RB change interrupt is not set, the only thing that can wake the processor from sleep is Timer1 overflow change, wich will occur(hopefully) 108 ms after the start of the key code transmition. Once this overflow occurs it produces an interrupt in wich the keyboard will be scaned to see if a "key still pressed" code needs to be transmited, wich is done by function TransmitRepCode(). And in case C, I set timer1 , transmit repetition code(done by TransmitRepCode()) and go back to sleep. Waiting for Timer1 to overflow, to check again if the key still pressed and I nedd to transmit another repetition code, or stop the transmition and go back to sleep. I hope this helps to understand what I need to do, so you or anybody can help me. Because really, I think I tryied everything. And the problems is with the interrupt() function, and retruring from it, and the sleep() function. Is the combinationg of needing to use interrupts and the sleep() function. Also I think the interrupt() and sleep() functions are pourly documented in the BoostC manual. And I haven´t seen examples that use them combined, if you or anybody knows one please let me know. I thank you for your advice and welcome yours and everybody`s ideas on how to solve this problem, wich is a very frustrating one.
  4. Hi everybody, first I want to thank to those who gave me some awnsers , mchristisen and orin. The reason I tooked so long to post again is because I´ve been doing every thing possible to make that code work, with no results I tried not touching GIE, tried sleep() in infinite loop, tried not eneableing general interrupts (wich should make it fetch the next instruction instead of going to interrupt() function), but no luck. just to see if it was a problem in other part I tried changeing the main() routine to this: void main() { CargarTeclas();// Loads individual keys values ConfigPorts(); ConfigTimer1(); while(1) { key = ScanKeys(); if (key != 0) { TransmitKeyCode(key); key = 0; } } } Now this main() routine as you can see, is constantly scaning the keymatrix, if one key is pressed transmits that key code, and then returns to scanning. No interrupts, no sleep(), no preoblem But that is no real solution, as this is supossed to work on two AAA batteries, and the processor HAS to go to sleep mode. So, this is what i need to do : 1)Do all the configuration(ports, timer, interrupts) 2)Configure it to go to interrupt on change of RB7:RB4, or Timer1 overflow. 3) Go to sleep mode 4) Once I have an interrupt, stop timer , scankeybord and throw key code. 5) Go back to sleep Does anybody knows how to do this right ?
  5. Hi everybody, I´m trying to make an IR remote control with PIC 16F628A. Escencially the software configures the ports and then waits for an interrupt from keyboard, once in interrupt service rutine, it scans the keyboard, transmits proper key code, and sets timer 1for interrupt to transmit repetition code, or not(it depend on a new keyboard scan and whether the detected key is the same as allready pressed or not). I simulated it and it seems to work O.K, but in real life is a mess. So here´s some of the code and I would highly welcome any input, thanks. //******************************************************************************** *** #include <system.h> #pragma CLOCK_FREQ 4000000 #pragma DATA _CONFIG, _HS_OSC & _WDT_OFF & _CP_OFF & _LVP_OFF & _MCLRE_OFF & _PWRTE_ON & _BODEN_OFF unsigned char adressHigh = 0b00010000; unsigned char adressLow = 0b00010000; unsigned short keyValue = 0; unsigned char k1, k2, k3, k4, k5, k6,k7, k8, k9,k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, k24; void TimerOn(void); bool keyPressed = false; unsigned char selectedKey = 0; void CargarTeclas(void); void ConfigPorts(void); void ConfigTimer1(void); void TransmitStartCode(void); void TransmitRepCode(void); void TransmitKeyCode(unsigned char); void TransmitPulso(void); void TransmitBit0(void); void TransmitBit1(void); unsigned char ScanKeys(void); void interrupt(void) { clear_bit(intcon, GIE); clear_bit(intcon, RBIE); clear_bit(intcon, PEIE); clear_bit(pie1, TMR1IE); clear_bit(intcon, RBIF); clear_bit(pir1, TMR1IF); clear_bit(t1con, TMR1ON); delay_ms(15); unsigned char key = ScanKeys(); if (key != 0) { if ((key == selectedKey) && (keyPressed == true)) { clear_bit(pir1, TMR1IF);//Borro la bandera TMR1 interrupt set_bit(intcon, PEIE);//Habilita interrupcion de perifericos set_bit(pie1, TMR1IE);//Habilita inrrupcion por timer1 overflow clear_bit(intcon, RBIE); clear_bit(intcon, RBIF); ConfigTimer1(); TimerOn(); TransmitRepCode(); set_bit(intcon, GIE); } else { keyPressed = true; selectedKey = key; clear_bit(pir1, TMR1IF);//Borro la bandera TMR1 interrupt set_bit(intcon, PEIE);//Habilita interrupcion de perifericos set_bit(pie1, TMR1IE);//Habilita inrrupcion por timer1 overflow clear_bit(intcon, RBIE); clear_bit(intcon, RBIF); ConfigTimer1(); TimerOn(); TransmitKeyCode(key); set_bit(intcon, GIE); } } else { keyPressed = false; selectedKey = 0; clear_bit(t1con, TMR1ON); clear_bit(pir1, TMR1IF); clear_bit(pie1, TMR1IE); clear_bit(intcon, PEIE); clear_bit(intcon, RBIF); set_bit(intcon, RBIE); set_bit(intcon, GIE); } } void main() { CargarTeclas(); ConfigPorts(); clear_bit(intcon, RBIF); set_bit(intcon, RBIE); set_bit(intcon, GIE); nop(); sleep(); } void ConfigPorts(void) { cmcon = 0x07; trisa = 0; porta = 0; trisb = 0; portb = 0b01110000; trisb = 0b01110000; clear_bit(option_reg, 7);//activo las resistencias pull up en portb } void ConfigTimer1(void) { t1con = 0b00110100; } void TimerOn(void) { tmr1l = 0x00; tmr1h = 0x00; tmr1l = 0x43; tmr1h = 0xCB; set_bit(t1con, TMR1ON); }
  6. Thanks ! It seems to be working good now. But , Do you have an idea as to what caused the problem ? I think it started after I instaled MPLAB 8, wich I installed two days after BoostC. Is there a compatibility issue ?
  7. Thank you very much for such prompt reply, I´ll try it right away, and I´ll tell you if it worked.
  8. Please I need help, I was starting to use boostc (ver 6.81)and everything went well for two days, now I can´t do anything and the program keeps locking. Is ther some error log that I can send ? Where I can find it ? I tried re-installing it, uninstalling other possible conflicting software(MPLAB 8, DevC++, tec) and nothing. Please, I just can´t use it anymore. My system: CPU: AMD Athlon 2000+ RAM: 512 OS: WinXP SP2
×
×
  • Create New...