Zurück (C) Christof Ermer, Regensburg
Gästebuch 
(public. sonst besser Email)  ChristofErmer@gmail.com



02.03.2023

ATMega3280 µProzessor  C-Module..


HighResPWM_OCR1AB_T1


// Chr. Ermer 01.03.23
#include <stdint.h>
#include <ctype.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "HighResPWM_OCR1AB_T1.h"
//256 = 4MS Servo = 1MS +0..1MS = 64+ 0..64
/*
16^6 / 256 / 256 = 1/244 = 4mS
|-------|         |-- PWM
|       |         |   
|       |---------| 
*/
//*************
void Start_OCR1AB_PWM_T1(void) // SERVO 62500 Int/sec
//*************
/*
Nutze ICR Register zum zurücksetzen des TCNT1
CLEAR mit OCR1AB Das PWM BIT
Kein Interrupt benötigt
*/
{
SERVO_ENABLE_INIT();
SERVO_ENABLE_CLR();
DDRB |= (1<<PB1) | ( 1<<PB2);  //DDRB Output nicht vergessen, PORTB=unnötig
// CTC MODE 14 50 = 20MS Range = 1..2 mSec ;
//T1 /8 /50Hz = 20000=ICP1 Set ON Range 1000..2000
TCNT1= 0;
OCR1B = OCR1A = SERVO_MITTE;  // 3000;  //T1_50HZPWM_CENTERR
//OCRx = OCR1ab 2000 = 1mS = 2000…4000. Mitte=3000
ICR1 = 40000U;// 20000 = 1MHz/50 Hz
//Phase correct MODE 14 --> WGM 13, 12, 11 14 1 1 1 0 Fast PWM ICR1 BOTTOM TOP
TCCR1A = (1<< WGM11) | (1<< COM1A1) | (1<< COM1B1); //Clear by Match
TCCR1B = (1<< WGM13) | (1<< WGM12) | (1<< CS11); // ICR Compare FCPU/8

SERVO_ENABLE_SET();
};

/*
// MAIN
uint8_t u8Sin=0;
    u8Sin++;
     gu8aServoPWM[0] = 128 + 125 * sin( 2* M_PI * (u8Sin/256.0) );
      u8Sin++;
*/

//HEADER

#ifndef HIGHRES_PWM_T1_H
  #define HIGHRES_PWM_T1_H

#define SERVO_LINKS   2000  // 1ms
#define SERVO_MITTE   3000 //1,5ms
#define SERVO_RECHTS  4000 //2ms

#define SERVO1_PORT PORTB
#define SERVO1_DDRX DDRB
#define SERVO1_PIN  1 // OC1A
#define SERVO1_INIT() (SERVO1_DDRX |= (1<<SERVO1_PIN) )
#define SERVO1_SET()  (SERVO1_PORT |= (1<<SERVO1_PIN) )
#define SERVO1_CLR()  (SERVO1_PORT &= ~(1<<SERVO1_PIN) )

#define SERVO2_PORT PORTB
#define SERVO2_DDRX DDRB
#define SERVO2_PIN  2  // OC1B
#define SERVO2_INIT() (SERVO2_DDRX |= (1<<SERVO2_PIN) )
#define SERVO2_SET()  (SERVO2_PORT |= (1<<SERVO2_PIN) )
#define SERVO2_CLR()  (SERVO2_PORT &= ~(1<<SERVO2_PIN) )

#define SERVO_ENABLE_PORT PORTC
#define SERVO_ENABLE_DDRX DDRC
#define SERVO_ENABLE_PIN  0
#define SERVO_ENABLE_INIT() (SERVO_ENABLE_DDRX |= (1<<SERVO_ENABLE_PIN) )
#define SERVO_ENABLE_SET()  (SERVO_ENABLE_PORT |= (1<<SERVO_ENABLE_PIN) )
#define SERVO_ENABLE_CLR()  (SERVO_ENABLE_PORT &= ~(1<<SERVO_ENABLE_PIN) )
//Proto
void Start_OCR1AB_PWM_T1(void); // SERVO 62500 Int/sec

#endif //MULTIPWMT2_H



SHIFT 74595

/*
Christof Ermer
10.02.2015
LED8 02.2023
*/
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#include "8LED_74-595_Out.h"

//ANPASSEN AN CHIP-ZAHL  --> Header USED_74595_ICS
//POINTERdes Datentyps der Funktion ebfalls anpassen

// ******************************
void LED8_74595_InitDDRegs(void)
// ******************************
{
LED8_SH_CP_PORT |= DS_LED8_74595;
LED8_SH_CP_DDRX |= SH_CP_LED8_74595;
LED8_ST_CP_DDRX |= ST_CP_LED8_74595;
};

// **************************************
void LED8_74595( uint8_t u8Val )  //uint16_t uint32_t
// **************************************
{
uint8_t u8NN;
LED8_74595_InitDDRegs();  // AUSLAGERN IN INIT
OUT_LED8_74595_SCK_LOW();
//TWO_CYCLES();
u8NN =  7;
u8Val = ~u8Val;  // 1-->0
do
    {  // Clock out bits
    if( u8Val &  (1UL << u8NN) )     // Ist es undiert eine EINS ?
        {     
        OUT_LED8_74595_SERDATA_HIGH();    
        }         
     else
        {   
        OUT_LED8_74595_SERDATA_LOW();   
        };    //Shift clock
    TWO_CYCLES(); //_delay_us(1);
    OUT_LED8_74595_SCK_HIGH();
    TWO_CYCLES(); //_delay_us(1);
    OUT_LED8_74595_SCK_LOW();
    TWO_CYCLES(); //_delay_us(1);       
  }while( u8NN-- );
 
OUT_LED8_74595_RCK_HIGH(); // Latch Data to Output
TWO_CYCLES(); //_delay_us(1);
OUT_LED8_74595_RCK_LOW();
};
//HEADER
/*
Christof Ermer
20.03.2018
Neue Version mit getrennten BIT DEfines
02.2015 f�r Kurs

NICHT VERGESSEN :
SCL/MR PIN 10  = 1
/OE Pin 13 = 0
*/

//HEADER
#ifndef LED8_OUTSHIFT_74_595_HEADER
#define LED8_OUTSHIFT_74_595_HEADER

#define TWO_CYCLES() __asm__ __volatile__( "rjmp 1f\n 1:" ) // 2 cycles

#define LED8_DS_PORT    PORTD     //DATA
#define LED8_DS_DDRX    DDRD
#define LED8_DS_PIN_NR        7

#define LED8_SH_CP_PORT  PORTB //SCK
#define LED8_SH_CP_DDRX  DDRB
#define LED8_SH_CP_PIN_NR    0

#define LED8_ST_CP_PORT    PORTB    //RCK
#define LED8_ST_CP_DDRX    DDRB
#define LED8_ST_CP_PIN_NR    4

//PINS
#define DS_LED8_74595     (1<< LED8_DS_PIN_NR  )      // DATA
#define SH_CP_LED8_74595  (1<< LED8_SH_CP_PIN_NR ) //SCK
#define ST_CP_LED8_74595  (1<<  LED8_ST_CP_PIN_NR )  // Store / RCK

#define OUT_LED8_74595_SERDATA_LOW()    (LED8_DS_PORT &= ~DS_LED8_74595 ) //Daten rausshiften
#define OUT_LED8_74595_SERDATA_HIGH()    (LED8_DS_PORT |= DS_LED8_74595 ) //Daten rausshiften

#define OUT_LED8_74595_SCK_LOW()    (LED8_SH_CP_PORT &= ~SH_CP_LED8_74595 ) //Shift clock
#define OUT_LED8_74595_SCK_HIGH()    (LED8_SH_CP_PORT |= SH_CP_LED8_74595 ) //Shift clock

#define OUT_LED8_74595_RCK_LOW()    (LED8_ST_CP_PORT &= ~ST_CP_LED8_74595 ) //Latch Data to Output
#define OUT_LED8_74595_RCK_HIGH()    (LED8_ST_CP_PORT |= ST_CP_LED8_74595 ) // Latch Data to Output

void LED8_74595_InitDDRegs(void);
void LED8_74595( uint8_t u8Val );

#endif //OUTSHIFT_74_595_HEADER



PWM mit 8 Bit Timer2 
/*
16^6 / 256 / 256 = 1/244 = 4mS
|-------|         |-- PWM
|       |         |   
|       |---------| 
*/
///*************
void Start_FastPWM_T2(void)
//*************
{
DDRB |= ( 1<< 3 ); // OC2A
OCR2A = 20;  // ~1,5mS
TCNT2=0;
TIMSK2 = 0;// (1<< TOIE2);   //OVL
TCCR2A =  (1<<COM2A1) | (1<<WGM21) |  (1<<WGM20);  //  FAST PWM CTC Fehler in DOCU
TCCR2B = 7; //1024 // 16^6 / 1=  62500 / 256 = 244,140625
};




/ *******************
ISR(TIMER0_COMPA_vect)  // 250*/sec
// *******************
{
  gu32Ticks++;                      // ~250/Sekunde
  if (!(gu32Ticks % TICKS_1000MS))  //Modulo ==0 ?
  {
    gstFlags.TickEvent_Flag = 1;  //Set FLAG
  };

  if (!(gu32Ticks % TICKS_100MS))  //Modulo ==0 ?
  {
    gstFlags.TICK_100MS_Flag = 1;
    //UART_RX_Check();
  };

};

// *****************************
void StartTickTimer(void)
// *****************************
{ // Timer0 TickCounter starten im Compare Mode
  // M_CPU=16^6 / 256 / 250 = {ebenso} 250!Z�hle 0 bis 250-->exakt 1 SeKunde
  TCNT0 = 0;
  OCR0A = 250;             //Compare Value
  TCCR0A = (1 << WGM01);   //CTC Mode = Compare Timer Counter mit OCR0A
  TIMSK0 = (1 << OCIE0A);  //Compare Interrupt aktivieren
  TCCR0B = (1 << CS02);    //Vorteiler /256
};



// *******************
ISR(INT0_vect)
// *******************
{
  //EIMSK &= ~(1<< INT0);  //Int deaktivieren
  //EIFR = (1 << INT0);
  //Toggle_Bit(1)
  gstFlags.Switch_Toogle ^= 1; //XOR
  INTERN_LED_TOOGLE();
};


/ ******************************
void Start_FRQ_T1(void)
// ******************************
{//Start T1
  DDRB |= _BV(1);  // OC1A TOGGLE OUT
  TCNT1 = 0;
  OCR1A = 16; //~1KHz
  TCCR1A = _BV(COM1A0);  //OC1A=PB1 Toogle
  TCCR1B = _BV(WGM12) | _BV(CS12) | _BV(CS10); //VT=1024
};

const uint8_t MCA_SINUS[] PROGMEM = {        // "256 Byte SINUS von 0..255
128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,\
185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,\
230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,\
253,254,254,254,255,255,255,255,255,255,255,254,254,254,253,253,252,251,250,\
250,249,248,246,245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,\
220,218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,176,173,\
170,167,165,162,158,155,152,149,146,143,140,137,134,131,128,124,121,118,115,\
112,109,106,103,100,97,93,90,88,85,82,79,76,73,70,67,65,62,59,57,54,52,49,47,\
44,42,40,37,35,33,31,29,27,25,23,21,20,18,17,15,14,12,11,10,9,7,6,5,5,4,3,2,\
2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,\
25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,\
90,93,97,100,103,106,109,112,115,118,121,124};


uint8_t u8SinT2A;
u8SinT2A++;
OCR2A = 128 + 50 * sin( 2* M_PI * (u8SinT2A/256.0) );
OCR2A = pgm_read_byte_near(MCA_SINUS + u8SinT2A++) / 16 + 16; // Etwas kleiner