Attiny861 Duty Cycle Variation

Thread Starter

nudmat

Joined May 27, 2014
4
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.

Rich (BB code):
 # 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='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 -= 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 += 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;    
        
   }
   
}
  
 
 
Top