Continue to Site

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.

  • 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.

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.

Latest threads

New Articles From Microcontroller Tips

Back
Top