• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

LED it's not blinking at the expected rate

robi10101298

New Member
Hello guys, I'm trying to make a led blink at 3 different frequencies, upon successive keypresses. My problem right now it's that it's only blinking 2 times and I don't understand why. D6 is LED, D4 is the test output. Here it's my main function:
C:
/*********************************************
Project : Test software
**********************************************
Chip type: ATmega164A
Clock frequency: 20 MHz
Compilers:  CVAVR 2.x
*********************************************/

#include <mega164a.h>

#include <stdio.h>
#include <delay.h>  
#include <string.h> 
#include <stdlib.h>
#include "defs.h"    

//*************************************************************************************************
//*********** BEGIN SERIAL STUFF (interrupt-driven, generated by Code Wizard) *********************
//*************************************************************************************************

#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)


/*
 * Timer 1 Output Compare A interrupt is used to blink LED
 */
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
LED1 = ~LED1; // invert LED    
}                                  

/*
 * main function of program
 */
void main (void)
{          


    Init_initController();  // this must be the first "init" action/call!
    #asm("sei")             // enable interrupts
    LED1 = 1;               // initial state, will be changed by timer 1
    while(TRUE)
    {
        wdogtrig();            // call often else processor will reset
                 

        if(SW1 == 0)        // pressed
        {
            delay_ms(30);   // debounce switch
            if(SW1 == 0)    
            {                // LED will blink slow or fast
                while(SW1==0){
                    wdogtrig();    // wait for release
                    }
                // alternate between values and values/4 for OCR1A register
                // 4C40H / 4 = 1310H
                // new frequency = old frequency * 4
                if(OCR1AH == 0x4C)  
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x13; OCR1AL = 0x10;}
                else     
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x4C; OCR1AL = 0x40;}            
            }                
        }                                       
        
        // measure time intervals on oscilloscope connected to pin TESTP
        for(i=0; i<3; i++) {
            TESTP = 1;
            delay_us(1);
            TESTP = 0;   // may check accuracy of 1us interval on oscilloscope     
        }
    } 

            
}// end main loop
And here it's the init.c function:
C:
/* initialization file */



#include <mega164a.h>

#include "defs.h"

                                        



/*

* most intialization values are generated using Code Wizard and depend on clock value

*/

void Init_initController(void)

{

// Crystal Oscillator division factor: 1

#pragma optsize-

CLKPR=0x80;

CLKPR=0x00;

#ifdef _OPTIMIZE_SIZE_

#pragma optsize+

#endif



// Input/Output Ports initialization

// Port A initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTA=0x00;

DDRA=0x00;



// Port B initialization

PORTB=0x00;

DDRB=0x00;



// Port C initialization

PORTC=0x00;

DDRC=0x00;



// Port D initialization

PORTD=0b00100000; // D.5 needs pull-up resistor

DDRD= 0b01010000; // D.6 is LED, D.4 is test output



// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

// Mode: Normal top=FFh

// OC0 output: Disconnected

TCCR0A=0x00;

TCCR0B=0x00;

TCNT0=0x00;

OCR0A=0x00;

OCR0B=0x00;



// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 19.531 kHz = CLOCK/256

// Mode: CTC top=OCR1A

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: On

// Compare B Match Interrupt: Off



TCCR1A=0x00;

TCCR1B=0x0D;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;



// 1 sec = 19531 counts = 4C41H counts, from 0 to 4C40

// 4C40H = 4CH (MSB) and 40H (LSB)

OCR1AH=0x4C;

OCR1AL=0x40;



OCR1BH=0x00;

OCR1BL=0x00;



// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer2 Stopped

// Mode: Normal top=0xFF

// OC2A output: Disconnected

// OC2B output: Disconnected

ASSR=0x00;

TCCR2A=0x00;

TCCR2B=0x00;

TCNT2=0x00;

OCR2A=0x00;

OCR2B=0x00;



// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

// INT2: Off

// Interrupt on any change on pins PCINT0-7: Off

// Interrupt on any change on pins PCINT8-15: Off

// Interrupt on any change on pins PCINT16-23: Off

// Interrupt on any change on pins PCINT24-31: Off

EICRA=0x00;

EIMSK=0x00;

PCICR=0x00;



// Timer/Counter 0,1,2 Interrupt(s) initialization

TIMSK0=0x00;

TIMSK1=0x02;

TIMSK2=0x00;



// USART0 initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART0 Receiver: On

// USART0 Transmitter: On

// USART0 Mode: Asynchronous

// USART0 Baud rate: 9600

UCSR0A=0x00;

UCSR0B=0xD8;

UCSR0C=0x06;

UBRR0H=0x00;

UBRR0L=0x81;



// USART1 initialization

// USART1 disabled

UCSR1B=0x00;





// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

ADCSRB=0x00;

DIDR1=0x00;



// Watchdog Timer initialization

// Watchdog Timer Prescaler: OSC/2048

#pragma optsize-

#asm("wdr")

// Write 2 consecutive values to enable watchdog

// this is NOT a mistake !

WDTCSR=0x18;

WDTCSR=0x08;

#ifdef _OPTIMIZE_SIZE_

#pragma optsize+

#endif



}
And this is how my minimalistic setup looks like:

1606840954147.png
What am I doing wrong?
 
Last edited:

Pommie

Well-Known Member
Most Helpful Member
How do you think you'll get three frequencies from this code?
Code:
               // alternate between values and values/4 for OCR1A register
                // 4C40H / 4 = 1310H
                // new frequency = old frequency * 4
                if(OCR1AH == 0x4C)  
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x13; OCR1AL = 0x10;}
                else     
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x4C; OCR1AL = 0x40;}
Note the use of the word "alternate". Is this your code or something you found somewhere?

Mike.
 

robi10101298

New Member
How do you think you'll get three frequencies from this code?
Code:
               // alternate between values and values/4 for OCR1A register
                // 4C40H / 4 = 1310H
                // new frequency = old frequency * 4
                if(OCR1AH == 0x4C) 
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x13; OCR1AL = 0x10;}
                else    
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x4C; OCR1AL = 0x40;}
Note the use of the word "alternate". Is this your code or something you found somewhere?

Mike.
I'm not familiar with ATmega registers so I don't exactly how can I get 3 frequencies...I only have 1 there
 

Pommie

Well-Known Member
Most Helpful Member
I don't know the ATmega registers either but I know C and so I can modify the above code to give three frequencies. So you don't know ATmega or C?

Mike.
 

Pommie

Well-Known Member
Most Helpful Member
More random stuff. If you'd have answered the questions things would be different.

Bye,

Mike.
 

robi10101298

New Member
More random stuff. If you'd have answered the questions things would be different.

Bye,

Mike.
What question man?? To show a message in C it's very simple, you're asking me if I know to code in C but you didn't mention exactly what should I code...
 

Pommie

Well-Known Member
Most Helpful Member
I was trying to work out your abilities and asked three different questions above. You are claiming to know how to program (not type) in C but can't modify the simple code above!!!

Mike.
 

robi10101298

New Member
I was trying to work out your abilities and asked three different questions above. You are claiming to know how to program (not type) in C but can't modify the simple code above!!!

Mike.
Because I'm not an expert in this and I don't know what to modify..It may be simple, but not for me..
 

Pommie

Well-Known Member
Most Helpful Member
This is not expert level coding but really simple stuff. I suggest you do one of the online C tutorials so you at least know the basics.

In the above code the values 0x1310 and 0x4C40 are being written to the timer register. The average of these two values is 0x2FA9 so to make it flash at three rates requires the three values to be written sequentially,
Code:
                if(OCR1AH == 0x4C)  
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x13; OCR1AL = 0x10;}    //0x1310
                else if(OCR1AH == 0x13)
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x2F; OCR1AL = 0xA9;}    //0x2fa9
                else
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x4C; OCR1AL = 0x40;}    //0x4C40
Mike.
 

robi10101298

New Member
This is not expert level coding but really simple stuff. I suggest you do one of the online C tutorials so you at least know the basics.

In the above code the values 0x1310 and 0x4C40 are being written to the timer register. The average of these two values is 0x2FA9 so to make it flash at three rates requires the three values to be written sequentially,
Code:
                if(OCR1AH == 0x4C) 
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x13; OCR1AL = 0x10;}    //0x1310
                else if(OCR1AH == 0x13)
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x2F; OCR1AL = 0xA9;}    //0x2fa9
                else
                    {TCNT1H=0; TCNT1L=0; OCR1AH = 0x4C; OCR1AL = 0x40;}    //0x4C40
Mike.
Thanks for your code but the leds are still blinking at a chaotic rate(sometimes 3 times, sometimes 4 times)...
 

Pommie

Well-Known Member
Most Helpful Member
They should blink at three different frequencies as you stated in your original post.

Mike.
 

Latest threads

EE World Online Articles

Loading
Top