1. 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.
    Dismiss Notice

Attiny861 Duty Cycle variation

Discussion in 'AVR' started by firstoption, Aug 6, 2014.

  1. firstoption

    firstoption New Member

    Joined:
    May 27, 2014
    Messages:
    3
    Likes:
    0
    Good day to all,
    Please i need your support.I am Controlling Led brightness with PWM Signal and at the same time Displaying the duty cycle(represented in %) on an Lcd Display.The Problem i am having is that the percentage of the duty cycle shown on the oscilloscope is different from the value shown on my Lcd Display.For example when the oscilloscope showed 50% duty cycle the value shown on the LCD was 38%.I would be glad if somebody could help me have a look at my code may be there is something i am not doing correctly.Below are my lines of code.Thank you for the usual Support.
    Best regards.

    Code (text):

    # define F_CPU 1000000UL
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/delay.h>
    #include "NewHeaven_LCD.h"
    #include "USI_TWI_Master.h"
    #define SLAVE_ADDR  0x50
    #define MESSAGEBUF_SIZE  20
    #define TWI_GEN_CALL  0x00  // The General Call address is 0
    // Sample TWI transmission commands
    //#define TWI_CMD_MASTER_WRITE 0x28
    //#define TWI_CMD_MASTER_READ  0x29
    // Sample TWI transmission states, used in the main application.
    #define SEND_DATA  0x01
    #define REQUEST_DATA  0x02
    #define READ_DATA_FROM_BUFFER 0x03
    #define RTC_ADDRRESS  0x34 //0x68
    #define RTC_REG_POINTER  0x00
    unsigned char messageBuf[MESSAGEBUF_SIZE];
    unsigned char TWI_DisplaySlaveAddress,TWI_RTCSlaveAddress, temp, pressedButton, myCounter=0;
    unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg )
    {
      // A failure has occurred, use TWIerrorMsg to determine the nature of the failure
      // and take appropriate actions.
      // Se header file for a list of possible failures messages.
      asm volatile ("nop");
     
      return TWIerrorMsg;
    }

    unsigned char Reset_RTC()
    {
     messageBuf[0]=(TWI_RTCSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
      messageBuf[1] = RTC_REG_POINTER;
      messageBuf[2] = 0;
     messageBuf[3] = 0;
     messageBuf[4] = 0;
     messageBuf[5] = 0;
     messageBuf[6] = 0;
     messageBuf[7] = 0;
     USI_TWI_Start_Transceiver_With_Data(messageBuf,8);
     
     return 0;
    }
    int main( void )
    {
      char  time_array[10];//HH:MM:SS
      unsigned char repeat=1;
      unsigned char sec,min,hr;
      unsigned char i,check=1;
     
     
      unsigned char mode=0;  // mode=0 : Power_Setting  ;;;; mode=1 : Time_Setting
      int LED_Power=1;
      int On_Time=0;
      int LED_on=0;
      int Duration=0;
      int RTC_Seconds=0;
     
      TWI_DisplaySlaveAddress  = 0x28;
      TWI_RTCSlaveAddress  = 0x68;
      sei();
      USI_TWI_Master_Initialise();
     
      messageBuf[0]=(TWI_DisplaySlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);  // Display an 0x28 schreibend ansprechen
      messageBuf[1]=0xFE;
      messageBuf[2]=0x53;
      messageBuf[3]=8;
     
     
      USI_TWI_Start_Transceiver_With_Data(messageBuf,4);
     
      // Set PWM-Port PB4
      PORTB = 0x00;
      DDRB  |=(1<<PB4) ;  //PWM output pin
      TCCR1A |= ((1 << PWM1B));  // Enable Fast PWM for OCR1B
      TCCR1C |= ( (1 << PWM1D) );  // Enable Fast PWM for OCR1D
      TCCR1C |= ( (1 << COM1D0) );  // OC1D & OC1D^ are connected,Clear on Compare Match
      OCR1C  = 77;
      OCR1D  = LED_Power;  
      //Invert output
      TCCR1B |= (1 << PWM1X);
      // Start timer1
      TCCR1B |= (1 << CS10)|(1 << CS11)|(1 << CS12);
     
      //Switch internal pullups on
      PORTA |= (1<<PA7) | (1<<PA6) |(1<<PA5) |(1<<PA4);
      PORTB |= (1<<PB6);
      Clear_LCD();
     
      for(i=0;i<8;i++)
     
      {
     
      time_array[i]='0';
      }
     
      time_array[2]=time_array[5]=':';
     
      /*Convert ASCII to BCD coded data and store in RTC registers*/
     
      for(i=0; i < 8; i++)
     
      {
      if ((i==2) || (i==5))
     
      ;  //do nothing
      else
      {
      time_array[i] -= 48;
      }
      }
     sec = (((time_array[6] << 4) & 0xf0) | (time_array[7]));
     min = (((time_array[3] << 4) & 0xf0) | (time_array[4]));
     hr =  (((time_array[0] << 4) & 0xf0) | (time_array[1]));
     
      /*Write data (time ) in RTC*/
     
      messageBuf[0]=(TWI_RTCSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
      messageBuf[1] = RTC_REG_POINTER;
      messageBuf[2] = sec;
     messageBuf[3] = min;
     messageBuf[4] = hr;
      USI_TWI_Start_Transceiver_With_Data(messageBuf,5);
     
      while(1==1)
      {
     
     if (mode==0)  // Power_Setting
     {
     if (!(PINA & 64 ))
     {
     if (LED_Power>1) LED_Power--;
     
     }
     
     else if (!(PINA & 16 ))
     {
     if (LED_Power<100) LED_Power++;
     }
     }
     
     if (mode==1)  // Time_Setting
     {
     if (!(PINA & 64 ))
     {
     if (On_Time>0) On_Time--;
     }
     else if (!(PINA & 16 ))
     {
     if (On_Time<300) On_Time++;  // maximale On-time 5min
     
     }
     }
     
     if (!(PINA & 32))
     {
     switch (mode)
     {
      case 0: mode=1;
      break;
      case 1: mode=2;
      break;
      default:mode=0;
      break;
     }
     
     
     _delay_ms(200);
     }
     
     
     if (mode==0)
     {  SetPos_LCD(0,0);
     sprintf(lcd_text,"*Power One %d  ",LED_Power);
     WriteString_LCD();
      SetPos_LCD(0,1);
     if (On_Time) sprintf(lcd_text," Real Time %ds  ",Duration); else sprintf(lcd_text," On_Time Period  ");
     WriteString_LCD();
     _delay_ms(10);
     }
     
     if (mode==1)
     {  SetPos_LCD(0,0);
     sprintf(lcd_text," Power One %d  ",LED_Power);
     WriteString_LCD();
     SetPos_LCD(0,1);
     if (On_Time) sprintf(lcd_text,"*Time One %ds  ",Duration); else sprintf(lcd_text,"*On_Time Period  ");
     WriteString_LCD();
     _delay_ms(10);
     }
     
     if (!(PINA & 128))
      {
      _delay_ms(200);
      if (LED_on==0) {LED_on=1; Reset_RTC(); RTC_Seconds=0;} else LED_on=0;
      if (LED_on) {OCR1D=50;  _delay_ms(1);}  
      }
     
     if (LED_on) OCR1D=LED_Power; else OCR1D=0;
     
     if (LED_on==0)
     {
     Duration=On_Time;
     SetPos_LCD(15,0);
     sprintf(lcd_text," ");
     WriteString_LCD();
     }
     else
     {
     SetPos_LCD(15,0);
     sprintf(lcd_text,"*");
     WriteString_LCD();
     }  
     if ((LED_on) && (On_Time))
     {
     if (RTC_Seconds>=On_Time)
      LED_on=0;
     else
     Duration=On_Time-RTC_Seconds;  
     }  
     
     
      // Set RTC Register
      messageBuf[0]=(TWI_RTCSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
      messageBuf[1] = RTC_REG_POINTER;
      USI_TWI_Start_Transceiver_With_Data(messageBuf,2);
     
      // Read RTC Register
      messageBuf[0]=(TWI_RTCSlaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT);
      USI_TWI_Start_Transceiver_With_Data(messageBuf,2);
      sec=messageBuf[1];
     
     
      // Set RTC Register
      messageBuf[0]=(TWI_RTCSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
      messageBuf[1] = 0x01;
      USI_TWI_Start_Transceiver_With_Data(messageBuf,2);
     
      // Read RTC Register
      messageBuf[0]=(TWI_RTCSlaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT);
      USI_TWI_Start_Transceiver_With_Data(messageBuf,2);
      min=messageBuf[1];
     
     
      // Set RTC Register
      messageBuf[0]=(TWI_RTCSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
      messageBuf[1] = 0x02;
      USI_TWI_Start_Transceiver_With_Data(messageBuf,2);
     
      // Read RTC Register
      messageBuf[0]=(TWI_RTCSlaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT);
      USI_TWI_Start_Transceiver_With_Data(messageBuf,2);
      hr=messageBuf[1];
     
      // convert time to seconds
     RTC_Seconds=  (sec & 0x0f) + 10* ((sec >> 4) & 0x0f)  // seconds
      + 60*(min & 0x0f) + 600*((min >> 4) & 0x0f); // minutes to secs
      // convert BCD coded decimal to ASCII code, display on LCD
     
      time_array[0] = (hr >> 4) & 0x0f;
      time_array[1] = hr & 0x0f;
      time_array[3] = (min >> 4) & 0x0f;
      time_array[4] = min & 0x0f;
      time_array[6] = (sec >> 4) & 0x0f;
      time_array[7] = sec & 0x0f;
     
     
      for(i=0; i< 8; i++)
      {
      if ((i==2) || (i==5))
      ;  //do nothing
      else
      {
      time_array[i] += 48;
      }
      }
     
      time_array[8]=0;
     
     
      //SetPos_LCD(0,1);
      //sprintf(lcd_text,"Second %s  ",time_array);
     //sprintf(lcd_text,"seconds %d  ",RTC_Seconds);
      //WriteString_LCD();
     
     
     
       
      //  OCR1B=64;  
     
      }
     
    }
     

     
     

Share This Page