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