|
|
View previous topic :: View next topic |
Author |
Message |
tohbas Guest
|
sleep(): // sleep dog |
Posted: Wed Mar 15, 2006 4:15 am |
|
|
/////////////////////////////////////////////////
//this software for remote control of 16F636 ///
/////////////////////////////////////////////////
// function of this remote control consists of
// 1. 6x3 matrix key switchs
// 2. low voltage detection @ about 2.2 volts
// 3. sending alarm code to mother when battery "low"
// 4. turn to safe-mode after 5 second
//////////////////////////////////////////////
// config of 16F636
// 1. internal oscillator @ 4 MHz
//
///////////////////////////////////////////////
// map of key matrix
// +pin+ a0 a1 a2
////////////////////////////////////////////////
// c0 || callout REP hangup
// c1 || 1 2 3
// c2 || 4 5 6
// c3 || 7 8 9
// c4 || * 0 #
// c5 || REC CLR PLAY
////////////////////////////////////////////////
// low low dectec 3 bits low
// 4.5v 111 0x17
// 4.2v 110 0x16
// 4.0v 101 0x15
// 2.3v 100 0x14
// 2.2v 011 0x13
// 2.1v 010 0x12
// 2.0v 001 0x11
// 1.9v 000 0x10
//////////////////////////////////////////////////
#include<16F636.h>
#include"pulse_gendigital.h"
#use fixed_io(c_outputs=PIN_C0, PIN_C1, PIN_C2, PIN_C3, PIN_C4, PIN_C5 )
void main ()
{
setup_oscillator(OSC_8MHZ );
//setup_low_volt_detector(0x13); // 2.2 v 0x13
enable_internal_pullup_pulldown(PUP_RA0 | PUP_RA1 | PUP_RA2);
//ENABLE_INTERRUPTS(INT_LOWVOLT);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(int_timer1);
timer1_counter =0;
enable_interrupts(global);
// going to write scan key and send code
output_c(0);
output_low(rx_output);
header = 0x554a;
output_high(led);
scan_key:
/*
scan_first_row();
scan_second_row();
scan_third_row();
scan_forth_row();
scan_fifth_row();
scan_sixth_row();
*/
if(timer1_counter == 10)
goto sleep_mode;
goto scan_key;
sleep_mode:
disable_interrupts(int_timer1);
timer1_counter =0;
output_low(led);
enable_interrupts(INT_RA);
// setup_oscillator(OSC_8MHZ );
output_c(0);
sleep();
aa:
goto aa;
}
#INT_LOWVOLT
low_volt()
{
battery_low = 0x0956;
}
#INT_TIMER1
TIMR1_counter()
{
timer1_counter++;
}
#int_RA
on_change_wake_up()
{
unsigned char temp;
temp = input_a();
disable_interrupts(INT_RA);
disable_interrupts(global);
#asm
bcf 0xb,0
#endasm
reset_cpu();
}
//after sleep(); my CPU nerver come back again ....
RA changed but it didnt awake ..why |
|
|
Ttelmah Guest
|
|
Posted: Wed Mar 15, 2006 5:10 am |
|
|
First, use the 'code' button, to post code here. It makes it much easier to read.
You do not need a lot of what you are dong. Just have the main code, for a loop, and re-execute when the processor wakes up.
Reset_cpu, is a software emulation of this ability on the 12 chips, just effectively forcing a jump to the start address. Now, what is then going to happen, is that the processor, probably never gets to the sleep operation at all!... When you first set the RA interrupt, if the port has changed since power on, the interrupt flag will already be set. It then jumps directly to the handler code. This doesn't clear the interrupt flag, or the latch to prevent the flag being reset (because, in the first case, you are jumping 'out' of the handler, and skipping the tidying up that is done on exit by the compiler, and in the second case, because you don't read the port). Then when the code comes round again, the flag is still set, and the same occurs.
The alternative, is that one of the other interrupt flags is already set, since the code will then not go to sleep, but 'skip' the instruction, while it calls the interrupt handler, and then fall through, into the infinite loop..
The way to use RA to wake _tidyly_, is:
Code: |
main {
//Do your initialisation here
int8 temp;
while (true) {
//Enable other interrupts in the main body of the loop
enable_interrupts(INT_TIMER1);
enable_interrupts(LOWVOLT);
enable_interrupts(GLOBAL);
//Do your scanning here
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER1);
disable_interrupts(LOWVOLT);
//You don't actually want the processor to 'interrupt'.
enable_interrupts(INT_RA);
//enable the interrupt flag to become set, from RA
//Make sure _only_ the source you want to wake up, is enabled
temp=input_a();
//Do a _dummy_ read of the input port, to reset the latch
clear_interrupts(INT_RA);
//Make sure the interrupt flag is clear
sleep();
//And now sleep till the port changes
disable_interrupt(INT_RA);
//Ensure the interrupt is disabled, before re-enabling the global flag
}
}
|
Now when the input changes, the code will wake up, then disable this interrupt, and re-enable the other interrupts.
Best Wishes |
|
|
tohbas Guest
|
sleep |
Posted: Tue Apr 11, 2006 12:00 am |
|
|
that was ok ..
soory for hard readding i am a starter of this board i will use post code key next time
thanks a lot |
|
|
|
|
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
|