Battery Charger - Led Blink Problem

Status
Not open for further replies.

Okada

Banned
Joined
Jun 16, 2016
Messages
1,159
Helped
129
Reputation
252
Reaction score
129
Trophy points
63
Activity points
0
Hi

I am making a simple Battery Charger using PIC12F675. All registers are configured properly. I have used mikroE Timer Calculator to generate 250 ms Timer1 interrupt code. I need to blink the green Led three times at 500 ms when the device starts but it is only blinking once. I don't know what is the problem. I spent 4 hours trying to figure out the problem but not able to find it.

I am attaching mikroC PRO PIC project and Proteus file.

The code inside the timer routine in ISR has two nested if() conditions and if I comment the inner if() condition then Green Led blinks at 500ms continuously.
 

Attachments

  • 12V Battery Charger.rar
    28.1 KB · Views: 100

Here is the code.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#define ON  1
#define OFF 0
 
sbit Relay at GP1_bit;
sbit Mosfet at GP2_bit;
sbit Charged_Led at GP4_bit;
sbit Charging_led at GP5_bit;
 
unsigned char my_flags = 0;
unsigned char state_counter = 0, led_blink_counter = 0, led_blink_count = 2, led_blink_delay_counter = 0, led_blink_delay_count = 3;
double mains_voltage = 0.0, previous_mains_voltage = 0.0;
 
sbit control_relay_and_mosfet_flag at my_flags.B0;
 
//Timer1
//Prescaler 1:4; TMR1 Preload = 3036; Actual Interrupt Time : 250 ms
//Place/Copy this part in declaration section
void InitTimer1() {
    T1CON = 0x21;
    TMR1IF_bit = 0;
    TMR1H = 0x0B;
    TMR1L = 0xDC;
    TMR1IE_bit = 1;
    INTCON = 0xC0;
}
 
void Interrupt() {
    if((TMR1IE_bit) && (TMR1IF_bit)) {
      //Enter your code here
      if(state_counter == 0) {
         if(++led_blink_counter == led_blink_count) {
             Charging_Led = ~Charging_Led;
             led_blink_counter = 0;
 
             if(++led_blink_delay_counter == led_blink_delay_count) {
                  state_counter = 1;
                  led_blink_delay_counter = 0;
                  TMR1IE_bit = 0;
                  control_relay_and_mosfet_flag = 1;
             }
         }
      }
      
      TMR1IF_bit = 0;
      TMR1H = 0x0B;
      TMR1L = 0xDC;
    }
}
 
void main() {
 
    asm clrwdt
    OPTION_REG = 0x8F;
 
    CMCON = 0x07;
 
    ANSEL = 0x51;
    ADCON0 = 0x80;
 
    TRISIO = 0x01;
    GPIO = 0x00;
 
    Delay_ms(100);
 
    state_counter = 0;
    control_relay_and_mosfet_flag = 0;
 
    InitTimer1();
 
    while(1) {
 
          asm clrwdt
 
    }
}

 

What for you checking this flag?
Code:
if(([COLOR="#FF0000"][B]TMR1IE_bit[/B][/COLOR]) && (TMR1IF_bit))
 

TMR1IE_bit is Timer1 Interrupt Enable bit and TMR1IF_bit is Timer1 Interrupt flag bit.

In the code if below if() condition is commented

Code:
if(++led_blink_delay_counter == led_blink_delay_count) {

}

then Charging_Led (Green Led) blinks at 500 ms interval continuously which is correct but if the above if() condition is uncommented then it has to stop after blinking 3 times but it is stopping after blinking 1 time.
 

TMR1IE_bit, once cleared in the ISR, is not set again which bars the ISR to act endlessly.

Code:
#define ON  1
#define OFF 0

sbit Relay at GP1_bit;
sbit Mosfet at GP2_bit;
sbit Charged_Led at GP4_bit;
sbit Charging_led at GP5_bit;

unsigned char my_flags = 0;
unsigned char state_counter = 0, led_blink_counter = 0, led_blink_count = 2, led_blink_delay_counter = 0, led_blink_delay_count = 3;
double mains_voltage = 0.0, previous_mains_voltage = 0.0;

sbit control_relay_and_mosfet_flag at my_flags.B0;

//Timer1
//Prescaler 1:4; TMR1 Preload = 3036; Actual Interrupt Time : 250 ms
//Place/Copy this part in declaration section
void InitTimer1() {
    T1CON = 0x21;
    TMR1IF_bit = 0;
    TMR1H = 0x0B;
    TMR1L = 0xDC;
    TMR1IE_bit = 1;
    INTCON = 0xC0;
}

void Interrupt() {
    if(([COLOR="#FF0000"]TMR1IE_bit[/COLOR]) && (TMR1IF_bit)) {
      //Enter your code here
      if(state_counter == 0) {
         if(++led_blink_counter == led_blink_count) {
             Charging_Led = ~Charging_Led;
             led_blink_counter = 0;

             if(++led_blink_delay_counter == led_blink_delay_count) {
                  state_counter = 1;
                  led_blink_delay_counter = 0;
                  [COLOR="#FF0000"]TMR1IE_bit = 0;[/COLOR]
                  control_relay_and_mosfet_flag = 1;
             }
         }
      }
      
      TMR1IF_bit = 0;
      TMR1H = 0x0B;
      TMR1L = 0xDC;
    }
}

void main() {

    asm clrwdt
    OPTION_REG = 0x8F;

    CMCON = 0x07;

    ANSEL = 0x51;
    ADCON0 = 0x80;

    TRISIO = 0x01;
    GPIO = 0x00;

    Delay_ms(100);

    state_counter = 0;
    control_relay_and_mosfet_flag = 0;

    InitTimer1();

    while(1) {

          asm clrwdt

    }
}
 

As I understood from the code, led_blink_delay_counter reaches led_blink_delay_count value after 3 led toggles (0->1->0->1), but not after 3 blinks, which is in fact 6 toggles.
Try to increase led_blink_delay_count.
 
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
Timer interrupt is for 250 ms

Code:
if(++led_blink_counter == led_blink_count) {

makes Charging_Led to blink at 500 ms Interval

This

Code:
if(++led_blink_delay_counter == led_blink_delay_count) {

condition is executed when after 3x 500ms interrupts and so it has to stop at count 3.


Altaero is right. I have to increase the count from 3 to 6. It works now. Thanks Altaero.
 
Last edited:

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…