Timers Registers from uno to atmega 8

Hi
I have a code for Uno atmega 328 which makes setting for timer registers
I want to use Atmega 8 instead of uno atmega 328
Could you help me please make these setup for atmega 8


  // set up Timer1
  OCR1A = 100;                        // initialize the comparator
  TIMSK1 = 0x03;                      // enable comparator A and overflow interrupts
  TCCR1A = 0x00;                      // timer control registers set for
  TCCR1B = 0x00;                      // normal operation, timer disabled

  TCNT1 = 0;                   // reset timer - count from zero
  OCR1A = dimming;             // set the compare register brightness desired.

 TCCR1B = 0x00;               // disable timer stops unintended triggers

Why do you think this is even possible? I see direct programming of the microcontroller registers and the ATmega8 is older and different from the ATmega88 for example - if I remember correctly the ATmega8 only has 3 PWM pins unlike the ATmega88 which has 6.

i tried this but not woking
the code for controlling motor speed
this is the code for uno atmega 328 i need to convert it to atmega 8

#include <avr/io.h>
#include <avr/interrupt.h>
#include <PID_v1.h>

#define TACHO 3            // tacho signals input pin
#define DETECT 2           // zero cross detect pin
#define GATE 17            // TRIAC gate pin
#define BUTTON 4           // rottary encoder button pin
#define RELAY 5            // relay pin
#define PULSE 2            // number of triac trigger pulse width counts. One count is 16 microseconds
#define TACHOPULSES 8      // number of pulses per revolution 

unsigned int RPM;                   // real rpm variable
unsigned int count;                 // tacho pulses count variable
unsigned int lastcount = 0;         // additional tacho pulses count variable
unsigned long lastcounttime = 0;
unsigned long lastflash;
unsigned long lastpiddelay = 0;
unsigned long previousMillis = 0;
unsigned long lastDebounceTime = 0;

const int sampleRate = 1;           // Variable that determines how fast our PID loop
const int rpmcorrection = 86;       // sito kazkodel reikia, kad realus rpm atitiktu matuojamus
const int protection = 2000;        // protection will switch on when real rpm exceeds desired by value
const int debounceDelay = 50;       // the debounce time; increase if the output flickers
const int minoutputlimit = 80;      // limit of PID output
const int maxoutputlimit = 540;     // limit of PID output
const int mindimminglimit = 80;     // the shortest delay before triac fires
const int maxdimminglimit = 625;    // for 60Hz will be 520
const int risetime = 100;           // RPM rise time delay in microseconds (risetime x RPM)
const int desiredRPM = 1000;        // ENTER DESIRED RPM HERE

int dimming = 540;                  // this should be the same as maxoutputlimit
int tempcounter = 100;

byte relayState = LOW;              // the current state of the relay pin
byte buttonState;                   // the current reading from the input pin
byte lastButtonState = HIGH;        // the previous reading from the input pin

bool loopflag = false;              // flag for soft start
bool startflag = false;             // flag for motor start delay
bool runflag = false;               // flag for motor running state

double Setpoint, Input, Output;       // define PID variables
double sKp = 0.1, sKi = 0.2, sKd = 0; // PID tuning parameters for starting motor
double rKp = 0.25, rKi = 1, rKd = 0;  // PID tuning parameters for runnig motor

PID myPID(&Input, &Output, &Setpoint, sKp, sKi, sKd, DIRECT); // define PID variables and parameters

void setup() {
  Serial.begin(115200);
  // set up pins
  pinMode(BUTTON, INPUT);             // set the button pin
  pinMode(RELAY, OUTPUT);             // set the relay  pin
  pinMode(DETECT, INPUT);             // set the zero cross detect pin
  pinMode(GATE, OUTPUT);              // set the TRIAC gate control pin
  pinMode(TACHO, INPUT);              // set the tacho pulses detect pin
  digitalWrite(BUTTON, HIGH);         // turn on pullup resistors
  digitalWrite(RELAY, relayState);    // initialize relay output

  Input = 200;                        // asiign initial value for PID
  Setpoint = 200;                     // asiign initial value for PID

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(minoutputlimit, maxoutputlimit);
  myPID.SetSampleTime(sampleRate);    // Sets the sample rate

  // set up Timer1
  OCR1A = 100;                        // initialize the comparator
  TIMSK1 = 0x03;                      // enable comparator A and overflow interrupts
// i tried TIMSK=00010100; not working with atmega 8
  TCCR1A = 0x00;                      // timer control registers set for
  TCCR1B = 0x00;                      // normal operation, timer disabled

  // set up zero crossing interrupt IRQ0 on pin 2.
  // set up tacho sensor interrupt IRQ1 on pin3
  attachInterrupt(0, zeroCrossingInterrupt, RISING);
  attachInterrupt(1, tacho, FALLING);
}

// Interrupt Service Routines
void zeroCrossingInterrupt() { // zero cross detect
  TCCR1B = 0x04;               // start timer with divide by 256 input
  TCNT1 = 0;                   // reset timer - count from zero
  OCR1A = dimming;             // set the compare register brightness desired.
}

ISR(TIMER1_COMPA_vect) {       // comparator match
  if (startflag == true) {     // flag for start up delay
    digitalWrite(GATE, HIGH);  // set TRIAC gate to high
    TCNT1 = 65536 - PULSE;     // trigger pulse width
  }
}

ISR(TIMER1_OVF_vect) {         // timer1 overflow
  digitalWrite(GATE, LOW);     // turn off TRIAC gate
  TCCR1B = 0x00;               // disable timer stops unintended triggers
}

// RPM counting routine
void tacho() {
  count++;
  unsigned long tachotime = micros() - lastflash;
  float time_in_sec  = ((float)tachotime + rpmcorrection) / 1000000;
  float prerpm = 60 / time_in_sec;
  RPM = prerpm / TACHOPULSES;
  lastflash = micros();
}

void loop() {

  // check the start / stop button state
  int reading = digitalRead(BUTTON);  // read the state of the switch into a local variable:
  if (reading != lastButtonState) {   // If the switch changed, due to noise or pressing
    lastDebounceTime = millis();      // reset the debouncing timer
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {     // if the button state has changed:
      buttonState = reading;
      if (buttonState == LOW) {       // only toggle the relay if the new button state is LOW
        relayState = !relayState;
        if (relayState == HIGH) {
          loopflag = true;
          digitalWrite(RELAY, relayState); // set the Relay:
          delay (300);                     // delay to prevent sparks on relay contacts
          startflag = true;                // flag to start motor
        }
        if (relayState == LOW) {
          Setpoint = 200;
          Input = 200;
          runflag = false;
          startflag = false;
          delay (300);                     // delay to prevent sparks on relay contacts
          digitalWrite(RELAY, relayState); // set the Relay:
        }
      }
    }
  }
  lastButtonState = reading;               // save the reading. Next time through the loop, it'll be the lastButtonState:

  //soft start
  if (loopflag == true) {
    myPID.SetTunings(sKp, sKi, sKd);        // Set the PID gain constants and start
    int i = (desiredRPM - tempcounter);
    for (int j = 1; j <= i; j++) {
      Input = RPM;
      Setpoint = tempcounter;
      myPID.Compute();
      dimming = map(Output, minoutputlimit, maxoutputlimit, maxoutputlimit, minoutputlimit); // inverse the output
      dimming = constrain(dimming, mindimminglimit, maxdimminglimit);     // check that dimming is in 20-625 range
      tempcounter++;
      delayMicroseconds (risetime);
    }
    if (tempcounter >= desiredRPM) {
      lastcounttime = millis();
      lastpiddelay = millis();
      loopflag = false;
      runflag = true;
      tempcounter = 100;
    }
  }

  // normal motor running state
  if (relayState == HIGH && loopflag == false) {
    unsigned long piddelay = millis();

    if ((piddelay - lastpiddelay) > 1000) {     // delay to switch PID values. Prevents hard start
      myPID.SetTunings(rKp, rKi, rKd);          // Set the PID gain constants and start
      lastpiddelay = millis();
    }

    Input = RPM;
    Setpoint = desiredRPM;
    myPID.Compute();
    dimming = map(Output, minoutputlimit, maxoutputlimit, maxoutputlimit, minoutputlimit); // reverse the output
    dimming = constrain(dimming, mindimminglimit, maxdimminglimit);     // check that dimming is in 20-625 range
  }

  // diagnose a fault and turn on protection
  unsigned long counttime = millis();
  if (counttime - lastcounttime >= 1000) {
    if (count == 0 && relayState == HIGH && runflag == true) {
      startflag = false;            // flag to turn off triac before relay turns off
      delay (300);                  // delay to prevent sparks on relay contacts
      digitalWrite(RELAY, LOW);
      relayState = LOW;
    }
    lastcount = count;
    count = 0;
    lastcounttime = millis();
  }

  //reset rpm after motor stops
  if (count == 0 && relayState == LOW) {
    RPM = 0;
  }

  // protection against high rpm. i e triac damage
  if (relayState == HIGH && RPM > desiredRPM + protection) {
    startflag = false;            // flag to turn off triac before relay turns off
    delay (300);                  // delay to prevent sparks on relay contacts
    digitalWrite(RELAY, LOW);
    relayState = LOW;
  }
}

It is certainly possible to control motor speed using an ATmega8 timer, but you will need to program the timer slightly differently than when using the ATmega328.

To learn how, study the timer sections of data sheets for the ATmega8 and ATmega328 very carefully.

This code works to control two motors using the ATmega8:

// ATmega8, clock = 7.3 MHz, Arduino core Minicore 3.3V
// add unified motor speed and direction control
// OC1A and OC1B outputs PB1&2 wired to motor driver /EN pins 

byte led = 14; //PC0

// motor driver direction control pins
byte RDIR = 6;
byte LDIR = 4;

void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);

  pinMode(RDIR, OUTPUT); //R DIRECTION
  pinMode(LDIR, OUTPUT); //L DIRECTION
  pinMode(9, OUTPUT); //OC1A
  pinMode(10, OUTPUT); //OC1B
  
 timer1_init();
  digitalWrite(LDIR, 1); //set direction FWD
  digitalWrite(RDIR, 1); //"
}

// initialize Timer1 for phase and frequency correct PWM, output on OC1A,B
// full range of PWM control 0..255 OCR1A,B

void timer1_init(void) {
  cli(); //no interrupts
  TCNT1 = 0;
  TCCR1A = TCCR1B = 0;
  // WGM : 8 phase and frequency correct PWM, TOP=ICR1
  TCCR1B = (1 << WGM13);
  TCCR1A = (1 << COM1A1)|(1 << COM1B1)|(1 << COM1A0)|(1 << COM1B0); //set on compare match (/EN)
  //prescaling : clock/8
  TCCR1B |= (1 << CS11);
  //TOP
  ICR1 = 255;  //about 1.8 kHz if F_CPU = 7.3 MHz
  //duty cycle
  OCR1A = 0;
  OCR1B = 0; // default 0% PWM (outputs HIGH)

  TIFR = 0b00111100; //clear interrupt flags, if set
  TIMSK &= ~((1 << OCIE1A) | (1 << OCIE1B)); //no compare interrupts
  sei(); //enable interrupts
}

void setPWM(int R, int L) { //-255 to 255

  if (R < 0) {
    digitalWrite(RDIR, 0); //reverse
    R = -R;
  }
  else digitalWrite(RDIR, 1); //fwd

  if (L < 0) {
    L = -L;
    digitalWrite(LDIR, 0); //reverse
  }
  else digitalWrite(LDIR, 1); //fwd

    if (L > 255) L = 255; //cap
    OCR1A = L;  //set PWM compare
 
    if (R > 255) R = 255; //cap
    OCR1B = R; //set PWM compare
}

void loop() {
  digitalWrite(led, HIGH);   // LED on, signal loop start
  delay(800);               // wait
  digitalWrite(led, LOW);    // LED off
  delay(200);               // wait

  for (int i=-255; i<=255; i++) {  //run motors up and down
    setPWM(i,i);
    delay(20);
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.