CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Question about KBD with INT_RB and sleep

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ritz



Joined: 06 Mar 2009
Posts: 8
Location: Bucharest

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

Question about KBD with INT_RB and sleep
PostPosted: Mon Mar 14, 2016 2:59 pm     Reply with quote

Hello all!
I need again a little help.
I made a program for PIC18F2520 who reads a keyboard (KBD.c from CCS with some minor changes) connected to port B, a stopwatch with timer1 (external quartz 32768), and save this parameters to internal eeprom. The Pic go in sleep mode after 15 seconds from power on. I want to wake up pic from INT_RB (when any key is pressed for to save data from keyboard). But if I have "enable_interrupts(INT_RB)" active, the PIC not go in sleep mode. Without this, the program work ok, but I can't wake up the PIC. The program works ok without sleep mode and INT_RB.
For all that write me here: yes, I'm beginner, I still have many gaps.
I edited my post, for saving space forum.
Code :

Code:
#include "18F2520.h"
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)
#use delay(clock=8000000)
#fuses NOWDT, HS, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include "KBD.c"  //from CCS with minor changes( 4x4 keypad and another chars)and port B address is ->#byte kbd = 0xF81
#use fast_io(B)

#define LED     PIN_C5

const int save_sec = 10;
static char kb[8];
static byte  kb_count;
static char c;
static unsigned int32 i, ticks30, oldticks, powerticks;
#Byte TMR1H = 0xFCF   // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD  //TIMER1 CONFIG REGISTER LOOK DATASHEET
int8 dummy;

void save_all() {

       kb_count = 0;  //reset kb_count
        output_high(LED); delay_ms(100); //signals that saved
       output_low(LED);
       }
     

#INT_RB
void rb_isr(void)
{
    dummy=input_b();
   ticks30=powerticks; //reset condition for sleep mode(counted 15 seconds)
}


#int_timer1
clock_t1(){
 bit_clear(T1CON,7);  //Enable access to the individual bytes of the timer register
   Bit_Set(TMR1H,7);   //Add 32768 to timer1 by setting high bit or timer register       
   Bit_Set(T1CON,7);   //Disable access to the individual bytes of the timer register
powerticks++; // increment for every second

}


void setup() {  // initialization PIC
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT);
 
  setup_timer_2(T2_DISABLED,0,1);
  setup_spi(FALSE);
   port_b_pullups(TRUE);
   delay_us(10);
   dummy=input_b(); //read whole port
 // set_tris_b(0b00001111);  //orig
  set_tris_b(0b11110000);
  set_tris_c(0b10010100);
 
  kbd_init();
 set_timer1(0);
 ticks30=powerticks;
  clear_interrupt(INT_RB);
   enable_interrupts(INT_TIMER1);
  enable_interrupts(GLOBAL);
   enable_interrupts(INT_RB);
}

void main()
{
   
   setup(); //init PIC
  powerticks = make32(read_eeprom(1), read_eeprom(2), read_eeprom(3), read_eeprom(4));//read internal eep at address and make powerticks like number and //at this eeprom address,first time write with 0 value

   kb_count = 0;
   output_high(LED); delay_ms(100); //only for signaling power
   output_low(LED); delay_ms(100);
   output_high(LED); delay_ms(100);
   output_low(LED);
   while (1) { // main loop
      if (powerticks % 100 == 0) { //save powerticks in internal eep in format hours,minutes,seconds
      i = powerticks;
       write_eeprom(4, i % 256);
       i = i >> 8;
       write_eeprom(3, i % 256);
       i = i >> 8;
       write_eeprom(2, i % 256);
       i = i >> 8;
       write_eeprom(1, i); }
     
     c = kbd_getc();
     if ((kb_count>0)&&(powerticks - oldticks > 1 * save_sec  )){save_all();} //if a key is pressed and during the past after being pressed >10 sec-->saved
     if (c != 0) {     
       kb_count++;
       kb[kb_count - 1] = c;
      if( kb_count==1){oldticks=powerticks;} //if a key is pressed -> reset time elapsed
       if( (c == 'Z') ||(kb_count == 8)||(powerticks - oldticks > 1 * save_sec ) ){save_all();} //if key pressed is 'Z' or pressed
eight keys are eight,or time elapsed is great of 10 sec --> saved 
     }
 
  if (powerticks-ticks30 > 15){sleep();}  // go to sleep after 15 seconds from power on
   
   }

}



If someone can give me an advice,thank you very much.And thank you for help to all.
For the present for answer to your comments, my programs are only for tests,are not implemented,only want to learn.KBD have minor changes(keypad 4x4 and another chars for A,B,C,D)and was tested and work.
@Mike Walne : thank you Mike, I changed post(I did not know how to use button CODE,but I saw now Smile ).
@temtronic : thank you for observation,but yes,I saved with this name(mykbd.c)
@asmboy : 1-- Thank you, yes, I added in program, but here I have removed everything not interested.2-- for this observation, I do not know exactly how to implement.
Well,I need for this application to put PIC in sleep mode after some seconds from power on and wake up if key pressed for normal operation
_________________
ritz


Last edited by ritz on Mon Mar 14, 2016 6:44 pm; edited 1 time in total
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 4:11 pm     Reply with quote

Address the problem head on.

Post short (<10 lines) code which shows what is going wrong.
Ignore anything not needed.
It's easier if we can copy and paste to test your code.
Learn to use the code button so that your formatting is preserved.

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9163
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 4:16 pm     Reply with quote

Yes, use code button please !
Among other things..
This line of code...

i = powerticks /1;

... doesn't make any sense to me.

Also you say you've modified the KBD.C driver. You _should_ ONLY modify a COPY of that driver, save as MY_KDB.C and use it. Modifying ANY original driver can be disasterous !!Not only can your changes cause problems but now you no longer have ORIGINAL source code. As well, anyone trying to help you will assume that the driver is original, although you do say you modified it, most will be thinking how the ORIGINAL driver works, and without 'your' driver can't see if the problem is in 'your' driver.


Jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Mar 14, 2016 5:31 pm     Reply with quote

1-add errors to your #use rs232 statement
2- rather than using sleep - another idea might be to go with the INTERNAL 8mhz oscillator instead of an external 8 mhz crystal ( using FUSE HS i see)- and instead of sleep - setup the oscillator for 32khz - get rid of the B port interrupt altogether- go into a tight loop and just POLL the lines you care about.

THEN on port B detection of the change you want - setup for 8mhz again. Because it is the INTERNAL Fosc you dont have to worry about the PUT timer when you flip clocks either.
I have done this with systems that need to both save power and be intrinsically "safe" and it can work very well on vanishingly low power - 31khz clock -just reading some pins is VERY easy on the power supply

BTW- FUSE NOPUT when actually using a crystal is NOT something i would
choose to do.

LASTLY: the trust you have in read / write EEPROM is much greater than mine. If this is for school - than what the heck - but if no-kidding for a product - i urge you to investigate adding an error checking code to your stored EEPROM values and to develop a robust safe stategy for what to do when reading back bad eeprom data ......
OR how you GOT the initial data INTO EEPROM for a first run after programming scenario
ritz



Joined: 06 Mar 2009
Posts: 8
Location: Bucharest

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

KBD with int_rb and sleep
PostPosted: Mon Mar 14, 2016 6:47 pm     Reply with quote

I edited my post and I removed the mistakes.
Thank you
_________________
ritz
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Mar 15, 2016 4:48 am     Reply with quote

Heavily editing your original post after you've had replies makes the thread confusing.
It means the items our comments refer to are no longer there, and therefore meaningless.

However, I say again, attack the problem head-on.
You've got a problem with sleep and int's.

So, ignore anything not needed, (EEPROM, kbd, etc).

Post SHORT code to:-

Startup and show that code runs (say flash LED) then sleep, wake, etc

Work on the KISS principal, remove all the distractions, only keep what's absolutely necessary.

Mike
ritz



Joined: 06 Mar 2009
Posts: 8
Location: Bucharest

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

About KBD,INT_RB and sleep
PostPosted: Tue Mar 15, 2016 3:17 pm     Reply with quote

I split into two problems.The first it is this :

Simple code :

Code:
#include "18F2520.h"
#use delay(internal=8Mhz)
#fuses NOWDT, INTRC_IO, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use fast_io(B)

#define LED     PIN_C5
#DEFINE LED1    PIN_C2


#INT_RB
void rb_isr(void)
{
    dummy=input_b();
   output_toggle(LED1);
}


void setup() {
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  setup_timer_2(T2_DISABLED,0,1);
  setup_spi(FALSE);
   port_b_pullups(TRUE);
   delay_us(10);
   dummy=input_b(); //read whole port
  set_tris_b(0b11110000);
  set_tris_c(0b10010100);
 output_low(LED1);
   clear_interrupt(INT_RB);
  enable_interrupts(GLOBAL);
   enable_interrupts(INT_RB);
}

void main()
{
 
   setup();
   output_high(LED); delay_ms(100);
   output_low(LED);
   
   while (1) { // main loop
   sleep();
     }
  }


For this code, I connected a keyboard 4x4 to port B in this mode: B0,B1,B2,B3 to L1,L2,L3,L4 and B4,B5,B6,B7 to C1,C2,C3,C4 (B7-B4 are inputs, B0-B3 are outputs).
The PIC go to sleep, and wake up when a key is pressed and LED1 flash.
But not all key work. Line 2 and line 3 not work (keys 4,5,6,B and 7,8,9,C). The keyboard are ok, I checked. It's not a hardware problem, because when have KBD.c in program, all keys are functional.
I don't know what happen.
Second problem is with KBD. For wait a character from keyboard, I have this line inside a while loop in MAIN : "c = kbd_getc();".CCS manual say that:
GETC() will always wait for a character to become available. Because of this line, PIC never enter in sleep mode. I ask for a solution.
Piece of code for trap keys are this :

Code:
void main() {

 while (1) { // main loop
   
   
    c = kbd_getc();
     if (c != 0) {   
     
       kb_count++;
       kb[kb_count - 1] = c;
   
       if (c == 'B') {save_all();} // save data to internal eeprom
       }
    sleep(); 
     }

   }


I simplified as much as possible and I hope that managed to be clear.
And please all,excuse me for all the mistakes
thank you
_________________
ritz
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 15, 2016 4:29 pm     Reply with quote

Quote:
For wait a character from keyboard, I have this line inside a while loop in
MAIN : "c = kbd_getc();".CCS manual say that:
GETC() will always wait for a character to become available.

That refers to getc() for the UART, not kbd_getc() for the keypad.
kbd_getc() must be called continously. It doesn't wait for a character.
temtronic



Joined: 01 Jul 2010
Posts: 9163
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Mar 15, 2016 5:11 pm     Reply with quote

re: ...
because when have KBD.c in program, all keys are functional.

This says that your modified version of kbd.c is NOT the same as kbd.c, which you says works. Simply printout both and see what you've changed

Also normally for 99.99% of program you do not need to code fast_io() and set_tris...(). Let the compiler do it for you. It is possible that your kbd driver alters the I/O pin configuration....maybe that's where the problem is ??


Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 16, 2016 2:43 am     Reply with quote

Quote:

For wait a character from keyboard, I have this line inside a while loop in MAIN:
c = kbd_getc();

That line doesn't wait for a keypad character.

But, you can create a routine that does wait for a keypad character.
See this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=41848&start=4
ritz



Joined: 06 Mar 2009
Posts: 8
Location: Bucharest

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Wed Mar 16, 2016 2:53 pm     Reply with quote

Thank you all for help!
Thank you PCM programer. I read your post and I think it will work. I will try soon.
_________________
ritz
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group