|
|
View previous topic :: View next topic |
Author |
Message |
bhyatyab
Joined: 26 Jan 2005 Posts: 13
|
Timers |
Posted: Tue Mar 08, 2005 7:58 am |
|
|
Hi
I still have a problem using timers
Could someone please have a look at my code. Im using a 18F452 at a frequncy of 4mhz. After 20secound an led should flash but it doesn't. The program doesn't seem to come out of the timer loop
Thanks
Code: |
#include <18F452.h>
#device ICD=TRUE
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT, WDT128, HS, NOPROTECT, NOOSCSEN, NOBROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
int i;
long secs=0;
long mins=0;
long hrs=0;
long counter=0;
#int_TIMER1
TIMER1_isr() {
counter=counter+1;
secs=secs+1;
set_timer1(0x3CAF);
if (secs==60){
mins=mins+1;
secs=0;
}
if (mins==60){
hrs=hrs+1;
mins=0;
}
if (hrs==24){
hrs=0;
}
set_timer1(0x00);
}
void main(){
/* **************************************************************/
/* INITIALISATION SECTION
/*
/* Part of Bootup Sequence. All peripherals
/* are configured and activated.
/*
/* ************************************************************* */
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
if(secs==20){
output_high(PIN_A1);
delay_ms(1000);
output_low(PIN_A1);
mins=0;
secs=0;
}
}
|
|
|
|
MikeValencia
Joined: 04 Aug 2004 Posts: 238 Location: Chicago
|
Here is sample code... |
Posted: Tue Mar 08, 2005 8:41 am |
|
|
I just slapped this together using example stwt1.c
It counts 20 seconds, then starts blinking. In this case, i used RB1 for the LED pin, so you ought to change your code accordingly. otherwise most of it is cut-and-paste-able...
Code: |
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#define INTS_PER_SECOND 15 // (4000000/(4*1*65536))
int8 seconds; // A running seconds counter
int8 int_count; // Number of interrupts left before a second has elapsed
void reset_one_second_counter(void);
#INT_TIMER1 // This function is called every time
void clock_isr() { // timer 1 overflows (65535->0), which is
// approximately 19 times per second for
if(--int_count==0) { // this program.
++seconds;
int_count = INTS_PER_SECOND;
}
}
void main() {
int_count = INTS_PER_SECOND;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
set_timer1(0);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
reset_one_second_counter();
while (seconds < 20)
{
// wait til 20 secs is up
}
// seconds is now >= 20
while(TRUE)
{
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_ms(1000);
}
}
void reset_one_second_counter(void)
{
int_count = INTS_PER_SECOND;
seconds = 0;
} |
-Mike
(valemike) |
|
|
valemike Guest
|
|
Posted: Tue Mar 08, 2005 8:45 am |
|
|
oops, i forgot to change something...
it should say
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
and not
setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
Other than that, both should work, just the previous program would take a bit longer. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
Re: Timers |
Posted: Tue Mar 08, 2005 9:31 am |
|
|
bhyatyab wrote: | Hi
I still have a problem using timers
Could someone please have a look at my code. Im using a 18F452 at a frequncy of 4mhz. After 20secound an led should flash but it doesn't. The program doesn't seem to come out of the timer loop
Thanks
Code: |
#include <18F452.h>
#device ICD=TRUE
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT, WDT128, HS, NOPROTECT, NOOSCSEN, NOBROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
int i;
long secs=0;
long mins=0;
long hrs=0;
long counter=0;
#int_TIMER1
TIMER1_isr() {
counter=counter+1;
secs=secs+1;
set_timer1(0x3CAF);
if (secs==60){
mins=mins+1;
secs=0;
}
if (mins==60){
hrs=hrs+1;
mins=0;
}
if (hrs==24){
hrs=0;
}
set_timer1(0x00);
}
void main(){
/* **************************************************************/
/* INITIALISATION SECTION
/*
/* Part of Bootup Sequence. All peripherals
/* are configured and activated.
/*
/* ************************************************************* */
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
if(secs==20){
output_high(PIN_A1);
delay_ms(1000);
output_low(PIN_A1);
mins=0;
secs=0;
}
}
|
|
Without looking that closely, the obvious thing that stands out is no endless loop.
Code: |
while(1)
{
if(secs==20){
output_high(PIN_A1);
delay_ms(1000);
output_low(PIN_A1);
mins=0;
secs=0;
}
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Mar 08, 2005 9:43 am |
|
|
And to get the timing correct he has to remove the following line: |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Mar 08, 2005 9:50 am |
|
|
ckielstra wrote: | And to get the timing correct he has to remove the following line: |
Actually his timing is all screwed up. With a divide by 8 and not setting the timer the timer will int every half second so he is going to have to do a count like what Mike suggested. |
|
|
bhyatyab
Joined: 26 Jan 2005 Posts: 13
|
Timers |
Posted: Wed Mar 09, 2005 1:01 am |
|
|
Hi
Ok now say I want this timer to do something say after 2hrs - how do I do this?
Thanks for all the info guys |
|
|
bhyatyab
Joined: 26 Jan 2005 Posts: 13
|
Timer |
Posted: Wed Mar 09, 2005 2:10 am |
|
|
Hi
1. (4000000/(4*1*65536)) - how do we get the figures 4*1? - how will my calculation change if I use a 20MHz Crystal?
2. Will this code work? I want a delay for 2hrs?
Code: |
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#define INTS_PER_SECOND 15 // (4000000/(4*1*65536))
int8 seconds; // A running seconds counter
int8 int_count; // Number of interrupts left before a second has elapsed
int secs=0;
int mins=0;
int hrs=0;
int counter=0;
void reset_one_second_counter(void);
#INT_TIMER1 // This function is called every time
void clock_isr() { // timer 1 overflows (65535->0), which is
// approximately 19 times per second for
secs=secs+1;
if (secs==60){
mins=mins+1;
secs=0;
}
if (mins==60){
hrs=hrs+1;
mins=0;
}
if (hrs==24){
hrs=0;
}
}
void main() {
int_count = INTS_PER_SECOND;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(0);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
reset_one_second_counter();
while (seconds < 20)
{
// wait til 20 secs is up
}
// seconds is now >= 20
while(hrs==2)
{
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_ms(1000);
}
}
void reset_one_second_counter(void)
{
int_count = INTS_PER_SECOND;
seconds = 0;
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 09, 2005 3:31 am |
|
|
Quote: | 1. (4000000/(4*1*65536)) - how do we get the figures 4*1? - how will my calculation change if I use a 20MHz Crystal? | 4000000 = Clock frequency
4 = A fixed value, the number of clock cycles it takes for 1 instruction to execute.
1 = prescaler setting (for example the T1_DIV_BY_1 in the call to setup_timer_1).
65536 = The number of ticks before the timer has an overflow. Timer 1 is a 16 bit timer,hence the 65536. An often applied method is to adjust this value in software; in the timer interrupt routine a new value is written to the timer so it will overflow sooner (see your own first code example where you call set_timer1(0x3CAF)). |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Mar 09, 2005 7:17 am |
|
|
The code will wait until seconds is equal to 20 and then the PIC will goto sleep. The hidden sleep instruction the compiler puts at the end of main. You do not have a while(1) loop. The first time the while(hrs==2) is evaluated it will not be true and simply skip the statements. You probably wanted to do a less than check. Also you seem to know that timer1 is going to interrupt about 15.25 times per second from your calculations. Therefore your seconds are 15.25 times too fast. At 20MHz they will be 5 times faster or 76.29 times too fast. |
|
|
bhyatyab
Joined: 26 Jan 2005 Posts: 13
|
Timers |
Posted: Wed Mar 09, 2005 7:25 am |
|
|
Sorry to be a pain - Im still lost
Ok lets start over - using my code, How do I set off the timer to run some code after 2hrs using a 4Mhz and a 20Mhz crystal? What must I change in my code so that it runs after 2hrs? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Mar 09, 2005 8:15 am |
|
|
Code: |
// wait until hours reaches 2
while(hrs<2);
// signal that the time is up
while(1)
{
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_ms(1000);
}
|
Now your timer1 is wrong. I am going to leave it to you to do a search on the board. There are plenty of examples on this. Search for RTC or Real Time Clock and you should find some examples. |
|
|
bhyatyab
Joined: 26 Jan 2005 Posts: 13
|
Timers |
Posted: Fri Mar 11, 2005 1:18 am |
|
|
Hi
I finally got my timer to work. The problem is that the event time happened, the program just loops. How can I make it exit till the next time.
Quote: |
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#define INTS_PER_SECOND 15 // (4000000/(4*1*65536))
int8 mins=0;
int8 hrs=0;
int8 seconds=0; // A running seconds counter
int8 int_count=0; // Number of interrupts left before a second has elapsed
void reset_one_second_counter(void);
#INT_TIMER1 // This function is called every time
void clock_isr() { // timer 1 overflows (65535->0), which is
// approximately 19 times per second for
if(--int_count==0) { // this program.
++seconds;
if(seconds==60){
mins=mins+1;
seconds=0;
}
if(mins==60){
hrs=hrs+1;
mins=0;
}
if(hrs==24){
hrs=0;
}
int_count = INTS_PER_SECOND;
}
}
void main() {
int_count = INTS_PER_SECOND;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(0);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
reset_one_second_counter();
while (seconds < 10)
{
// wait til 20 secs is up
}
// seconds is now >= 20
while(TRUE)
{
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_ms(1000);
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_cycles( 1 );
}
}
void reset_one_second_counter(void)
{
int_count = INTS_PER_SECOND;
seconds = 0;
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 11, 2005 4:51 am |
|
|
Think for a moment about what happens.
Code: | void main() {
int_count = INTS_PER_SECOND;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(0);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
reset_one_second_counter();
while (seconds < 10) {
// wait til 20 secs is up
}
// seconds is now >= 20
while(TRUE) {
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_ms(1000);
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_cycles( 1 );
}
}
|
When your timer 'expires', you move on into a loop that runs for ever, and will never come out. Also you now have no way of going 'back' to the timer code. So do something like this instead:
Code: |
while (true) {
//This is now the 'main' loop, inside which everything will happen.
while (seconds < 20) {
// wait till 20 secs is up
}
//Immediately reset the seconds, so the timer continues
seconds=0;
// seconds has now reached 20 and restarted
//Just toggle the output twice
//need a variable added called 'count'
for count=0;count<2;count++) {
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_ms(1000);
}
//At this point we loop back to the 'wait', the timer has allready been
//running for about 4 seconds, and we wait again for it to expire.
}
}
|
Best Wishes |
|
|
bhyatyab
Joined: 26 Jan 2005 Posts: 13
|
Timers |
Posted: Tue Mar 15, 2005 2:34 am |
|
|
Hi All
I have a problem with me code. Everything works fine, my clock works 100%. The problem is, when say secs==10, it starts executing the code .... but the timer seems to stop counting than after the code has executed, the timer continues to count. Why is this and how can I resolve it. Thanks guys
Code: |
#include <18F452.h>
#fuses NOWDT, WDT128, HS, NOPROTECT, NOOSCSEN, NOBROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=20000000)
#define INTS_PER_SECOND 76 // (4000000/(4*1*65536)) = 15 for a 4Mhz Crystal - 262144
int8 secs=0; // A running seconds counter
int8 mins=0;
int8 hrs=0;
int8 int_count=0; // Number of interrupts left before a second has elapsed
void reset_one_second_counter(void);
#INT_TIMER1 // This function is called every time
void clock_isr() { // timer 1 overflows (65535->0), which is
// approximately 19 times per second for
if(--int_count==0) { // this program.
++secs;
if(secs==60){
mins=mins+1;
secs=0;
}
if(mins==60){
hrs=hrs+1;
mins=0;
}
if(hrs==24){
hrs=0;
}
int_count = INTS_PER_SECOND;
}
}
void main() {
int_count = INTS_PER_SECOND;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(0);
enable_interrupts(INT_TIMER1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
enable_interrupts(GLOBAL);
reset_one_second_counter();
{
start:
while(secs==10)
{
output_high(PIN_C2); //switch phone OFF
}
goto start;
}
}
void reset_one_second_counter(void)
{
int_count = INTS_PER_SECOND;
secs = 0;
}
|
|
|
|
|
|
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
|