AtTiny85 in CTC Mode Oscillate +/- 500 Hz

Discussion in 'Embedded Systems and Microcontrollers' started by gioben, Jul 11, 2016.

  1. gioben

    Thread Starter New Member

    Jul 11, 2016
    6
    0
    So I have been struggling to make this chip output a 2.5 khz signal.

    I think I have managed to output this, but now I need to oscillate up and down +/- 500 Hz.

    So I will need the square signal to go from 2000 to 3000 kHz.

    This is the code I have done to output the signal.
    Code (C):
    1.  
    2. void setup()
    3. {
    4. DDRB |= bit (PB0);     //  Set pin PB0 as output
    5.  
    6. // stop Timer 0
    7. TCCR0A = 0;
    8. TCCR0B = 0;
    9. TCNT0 = 0;
    10.  
    11. // set up Timer 0
    12. TCCR0A |= bit (COM0A0);   //  Toggle OC0A/OC0B on Compare Match
    13. //TCCR0B |= bit (CS01); //With this setting prescaler to 8
    14. //TCCR0B |= bit (CS00);// | bit (CS01);  // Prescaler of 1024
    15. TCCR0B |= bit (CS00) | bit (CS01);  // Prescaler of 64
    16. TCCR0A |= bit (WGM01);    //  Start Timer 0 in CTC mode
    17. OCR0A = 50.05;   // CTC Compare value (count up to 128)
    18. }
    19.  
    20. void loop()
    21. {
    22.  
    23. }  
    24.  
    25.  
    Mod edit: added code tags

    I have used a 64 prescaler, with a 50.05 value of comparison, this after trying several combinations I think this works the best. I need to keep the 50 % duty cycle I am on right now.

    Do you have any ideas, suggestions ??

    Thanks in advance for your time.

    ----------------------------------------------------------------------------------------------------------------

    EDIT

    I was able to output a constant 2.5 kHz, yes. But now my issue is to make it oscillate the 500 Hz. I tried to do that by changing the comparison value from 63.05 to 41.5 which are the values of 2.0 and 3.0 kHz respectively. But it doesn't do that, the duty cycle changes and my actual range of values are from 1.2 to 9 kHz.

    What options do I have ?
     
    Last edited by a moderator: Jul 11, 2016
  2. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    @gioben
    Welcome to AAC!
    Please do not post your question in more than one thread. Doing so causes confusion and dilutes members' efforts to help you.
    This question seems best suited for this forum. I have deleted the other threads.
     
  3. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,394
    497
    You have two frequencies, 2 kHz and 3 kHz. Who selects the frequency?
     
  4. dannyf

    Well-Known Member

    Sep 13, 2015
    1,824
    364
    You want to sweep the output frequency?

    Just change the top of the timer periodically.

    Using pwm is better. And use center aligned pwm to avoid glitches.
     
  5. dannyf

    Well-Known Member

    Sep 13, 2015
    1,824
    364
    This is what I would try, in the loop():

    Code (Text):
    1.  
    2.   //output frequency from low to high
    3.   for (TOP = TOP_HIGH; TOP > TOP_LOW; TOP-=TOP_STEP) delay_ms(DLY_STEP); //waste some time
    4.   //output frequency from high to low
    5.   for (TOP = TOP_LOW; TOP < TOP_HIGH; TOP+=TOP_STEP) delay_ms(DLY_STEP); //waste some time
    6.  
    It will go from low to high, and then high to low, so on and so forth.
     
  6. gioben

    Thread Starter New Member

    Jul 11, 2016
    6
    0
    No, I want just one signal. This should be a signal that oscillates from 2000 - 3000 khz, but I would like to keep the same duty cycle.
     
  7. gioben

    Thread Starter New Member

    Jul 11, 2016
    6
    0
    How would I use PWM for that ? I am using the Tiny in CTC Mode. I tried using Fast Mode, but my duty cycle changed a lot. How will you thinhk the best way of doing this would be?
     
  8. gioben

    Thread Starter New Member

    Jul 11, 2016
    6
    0

    So, TOP will me the address of my top value, TOP high and low respectively are the values of my actual desired max and min ? DLY_STEP is the delay in millisecond in between the toggling ?? So is that my period?
     
  9. gioben

    Thread Starter New Member

    Jul 11, 2016
    6
    0
    Hi I have also tried this code without being able to make it work, this is using PWM.

    Code (Text):
    1. #include <TinySoftPwm.h>
    2. //#include <DigiUSB.h>
    3. #define HW_PWM_PIN               0 /* Used to check HW PWM with analogWrite() */
    4. #define SW_PWM_BUILT_IN_LED_PIN  1 /* Digispark Model A (Rev2) built-in LED pin number (Change it to 2 for Model B) */
    5. //#define TIME_TEST_PIN            5 /* Used to check with oscilloscope micros(), millis() are still OK */
    6. void setup()
    7. {
    8.    TinySoftPwm_begin(5.5556, 0); /* 128 x TinySoftPwm_process() calls before overlap (Frequency tuning), 0 = PWM init for all declared pins */
    9. //   pinMode(TIME_TEST_PIN, OUTPUT);
    10. //   DigiUSB.begin();
    11. }
    12. void loop()
    13. {
    14. static uint32_t PwmStartUs=micros();
    15. static uint32_t PwmStartMs=millis();
    16. static uint8_t  Pwm=0;
    17. static int8_t   Dir=1;
    18. static boolean  State=LOW;
    19. //static uint32_t BlinkStartMs=millis();
    20.   /***********************************************************/
    21.   /* Call TinySoftPwm_process() with a period of 60 us       */
    22.   /* The PWM frequency = 128 x 60 # 7.7 ms -> F # 130Hz      */
    23.   /* 128 is the first argument passed to TinySoftPwm_begin() */
    24.   /***********************************************************/
    25.   if((micros() - PwmStartUs) >= 60)
    26.   {
    27.     /* We arrive here every 60 microseconds */
    28.     PwmStartUs=micros();
    29.     TinySoftPwm_process(); /* This function shall be called periodically (like here, based on micros(), or in a timer ISR) */
    30.   }
    31. /*************************************************************/
    32.   /* Increment/decrement PWM on LED Pin with a period of 10 ms */
    33.   /*************************************************************/
    34.   if((millis()-PwmStartMs) >= 1)
    35.   {
    36.     /* We arrived here every 10 milliseconds */
    37.     PwmStartMs=millis();
    38.     Pwm+=Dir; /* increment or decrement PWM depending of sign of Dir */
    39.     TinySoftPwm_analogWrite(SW_PWM_BUILT_IN_LED_PIN, Pwm); /* Software PWM: Update built-in LED for Digispark */
    40.     analogWrite(HW_PWM_PIN, Pwm); /* Copy Pwm duty cycle to Hardware PWM */
    41.     if(Pwm==200) Dir=-1; /* if PWM reaches the maximum: change direction */
    42.     if(Pwm==15)   Dir=+1; /* if PWM reaches the minimum: change direction */
    43.   }
    44. }
    If you have any input, that will be amazing. Thanks everyone
     
  10. gioben

    Thread Starter New Member

    Jul 11, 2016
    6
    0
    Just in case it helps anyone in the future, here is what I needed.

    Code (Text):
    1. byte divisor = 150;
    2. int delay_value = 10;
    3.  
    4. void setup()
    5. {
    6. pinMode(1, OUTPUT);
    7. TCCR1 = 0b10010101;
    8. OCR1C = divisor;         // set the OCR
    9.  
    10. }
    11.  
    12. void loop()
    13. {
    14.  
    15. for (int i=0; i < 100; i++){
    16.   divisor++;
    17.   OCR1C = divisor;
    18.   delay(delay_value);
    19. }
    20.  
    21. for (int j=0; j < 100; j++){
    22.   divisor--;
    23.   OCR1C = divisor;
    24.   delay(delay_value);
    25. }
    26.  
    27. }
     
  11. dannyf

    Well-Known Member

    Sep 13, 2015
    1,824
    364
    No need to be that complicated.

    Code (Text):
    1.  
    2. #define TOP            OCR0A
    3. #define TOP_LOW        (F_CPU / 64 / F_TOP / 2) //64:1 prescaler, CTC mode
    4. #define TOP_HIGH    (F_CPU / 64 / F_BTM / 2)  //64:1 prescaler, CTC mode
    5. #define TOP_STEP    10
    6. #define STEP_DLY    100            //in ms
    7. #define F_TOP        2500        //high frequency, in Hz
    8. #define F_BTM        1500        //low frequency, in Hz
    9.  
    10. void loop(void) {
    11.     //frequency sweep, from F_BTM to F_TOP and then F_BTM
    12.     for (TOP=TOP_HIGH; TOP>TOP_LOW; TOP--) _delay_ms(STEP_DLY);
    13.     for (TOP=TOP_LOW; TOP<TOP_HIGH; TOP++) _delay_ms(STEP_DLY);
    14. }
    15.  
    16.  
     
Loading...