Attiny861 Duty Cycle variation

Status
Not open for further replies.

firstoption

New Member
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:
# 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;  
  
  }
  
}
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…