Вы находитесь на странице: 1из 5

#include <PWM.

h>

int outputPin = 11;

//For testing
int freqInput = 100; //10-10000 Hz (I wanted that range only)
int dutyCycleInput = 70; //1-65535

void setup()
{
InitTimersSafe();
}

void loop()
{
//Get inputs from either serial or through pot
//So we have Frequency and Duty cycle in variables 'freqInput' &
'dutyCycleInput' respectively in int
SetPinFrequencySafe(outputPin, freqInput );
pwmWriteHR(outputPin, dutyCycleInput );
}

/*

Test sketch for arduino PWM library - modified version.

CLI - command line interface:

d - debug, shift phase on regular time base interval, demo mode.


f - set frequency, "f100" - 100 Hz.
l - set duty cycle, "l2000".
p - set phase, "p90".

Direct Registers Manipulation:

1. "a80" - set address


2. "w10111" - write data, leading 0 could be ommited.
3. "r" - read current registers.

NOTE: Use direct registers programming VERY Carefully !!!

created 16 June. 2017


Anatoly Kuzmenko
anatolyk69@gmail.com

This example code is in the public domain.


Works for Timer 1 & 3 so far:
Pin 11 12 timer1
Pin 2 3 5 timer3

Timer-1 is primery clock generator, Timer-3 secondary, phase shifted clock.


*/

#include <PWM.h>

String in_String = "";


boolean end_input = false;
uint8_t adres_reg = 0;
uint8_t debug_osm = 0;

uint8_t prime_pin = 11;


uint8_t secon_pin = 2;

uint16_t level_pwm = 32767; // 1 -/- 65535


uint16_t phase_pwm = 90; // degree 1 -/- 360
uint32_t freqn_pwm = 35; // frequency in Hz

unsigned long previousMillis = 0;


const long interval = 500;

void setup()
{
Serial.begin(115200);
in_String.reserve(200);

InitTimersSafe();
}

void loop()
{
int32_t tempr = 0;
char * pEnd;

if(debug_osm) {
uint32_t currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
phaseShift();
}
}

serialEvent();

if( end_input) {
char cmd = in_String[0];
in_String[0] = '+';

if( cmd == 'd' ) {


debug_osm = 1 - debug_osm;
if(debug_osm) Serial.print(F("\nDebug aktiv."));
else Serial.print(F("\nDebug de-aktiv."));
}

if( cmd == 'f' ) {


tempr = strtol( in_String.c_str(), &pEnd, 10);
Serial.print(F("\n\tFreq: "));
Serial.print(tempr, DEC);
freqn_pwm = tempr;

bool success1 = SetPinFrequencySafe(prime_pin, freqn_pwm);


bool success2 = SetPinFrequencySafe(secon_pin, freqn_pwm);

GTCCR |= ((1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC));
GTCCR &= ~(1<<TSM);

if(success1 && success2) {


pwmWriteHR(prime_pin, level_pwm);
pwmWriteHR(secon_pin, level_pwm);

pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
}
}

if( cmd == 'l' ) {


tempr = strtol( in_String.c_str(), &pEnd, 10);
Serial.print(F("\n\tLevel: "));
Serial.print(tempr, DEC);
level_pwm = tempr;
pwmWriteHR(prime_pin, level_pwm);
pwmWriteHR(secon_pin, level_pwm);
}

if( cmd == 'p' ) {


tempr = strtol( in_String.c_str(), &pEnd, 10);
Serial.print(F("\n\tPhase: "));
Serial.print(tempr, DEC);
phase_pwm = tempr;

//GTCCR |= ((1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC));
GTCCR |= (1<<TSM);

tempr = ICR3 * (phase_pwm /360.0) -1;


if(tempr < 0) tempr = 0;
TCNT1 = 0;
TCNT3 = tempr;

GTCCR &= ~(1<<TSM);


}

if( cmd == 'a' ) {


adres_reg = strtol( in_String.c_str(), &pEnd, 16);
Serial.print(F("\n\tReg: "));
Serial.print(adres_reg, HEX);
Serial.print(F("\tvalue: "));
tempr = (*(uint8_t*)adres_reg);
Serial.print(tempr, BIN);
}
if( cmd == 'r' ) {
Serial.print(F("\n\tReg: "));
Serial.print(adres_reg, HEX);
Serial.print(F("\tvalue: "));
tempr = (*(uint8_t*)adres_reg);
Serial.print(tempr, BIN);
}
if( cmd == 'w' ) {
Serial.print(F("\n\tReg: "));
Serial.print(adres_reg, HEX);
Serial.print(F("\tvalue: "));
tempr = (*(uint8_t*)adres_reg);
Serial.print(tempr, BIN);
tempr = strtol( in_String.c_str(), &pEnd, 2);
(*(uint8_t*)adres_reg) = tempr;
Serial.print(F("\tnew value: "));
tempr = (*(uint8_t*)adres_reg);
Serial.print( tempr, BIN);
}

in_String = "";
end_input= false;
}
}

void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
in_String += inChar;
if (inChar == '\n') {
end_input= true;
}
}
}

void phaseShift() {
static uint16_t phase_loc = 0;
uint16_t tempr = 0;

//GTCCR |= ((1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC));
GTCCR |= (1<<TSM);
// GTCCR |= _BV (TSM);

tempr = ICR3 * (phase_loc /360.0) -1;


if(tempr < 0) tempr = 0;

TCNT1 = 0;
TCNT3 = tempr;

GTCCR &= ~(1<<TSM);


// GTCCR &= ~(_BV (TSM));
phase_loc += 30;
if(phase_loc > 360) phase_loc = 0;
}

Вам также может понравиться