|
|
View previous topic :: View next topic |
Author |
Message |
ritz
Joined: 06 Mar 2009 Posts: 8 Location: Bucharest
|
Question about KBD with INT_RB and sleep |
Posted: Mon Mar 14, 2016 2:59 pm |
|
|
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 ).
@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
|
|
Posted: Mon Mar 14, 2016 4:11 pm |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Mon Mar 14, 2016 4:16 pm |
|
|
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
|
|
Posted: Mon Mar 14, 2016 5:31 pm |
|
|
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
|
KBD with int_rb and sleep |
Posted: Mon Mar 14, 2016 6:47 pm |
|
|
I edited my post and I removed the mistakes.
Thank you _________________ ritz |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Mar 15, 2016 4:48 am |
|
|
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
|
About KBD,INT_RB and sleep |
Posted: Tue Mar 15, 2016 3:17 pm |
|
|
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
|
|
Posted: Tue Mar 15, 2016 4:29 pm |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Mar 15, 2016 5:11 pm |
|
|
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
|
|
Posted: Wed Mar 16, 2016 2:43 am |
|
|
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
|
|
Posted: Wed Mar 16, 2016 2:53 pm |
|
|
Thank you all for help!
Thank you PCM programer. I read your post and I think it will work. I will try soon. _________________ ritz |
|
|
|
|
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
|