Not long ago, i ask a similar question about the Attiny 84, and i was able to get it work, but i running into memory issue (sram too low for some serial communication), so since i have a Attiny1614 that has all i need i decide to use this one.
So now my project is to use a Attiny 1614 to 1st read a analog input that change from 0 to 5V, that ok, then i need to create a analog ouput that change based on the input, to do that i use the PWM ouput using analogWrite, the ouput will be a PWM witha a duty cycle from 0 to 100% (0 when input is 0V and 100% when input is 5V), then i use a RC low pass filter and a op amp rail to rail to give me a 0 to 5V analog output.
But to do it right i need to have a higher pwm frequency and if possible resolution, the input is in 10 bit (0 to 1023) but ouput PWM is only in 8 bit, so if i can have it in 10 bit is it better (or 9 bit is ok too).
Here he code i was runing on the Attiny 84 and was just fine about the PWM :
long vin = 0;
long vout = 0;
#include <SoftwareSerial.h>
SoftwareSerial serial_dev(0,1);
void setup() {
pinMode(6, OUTPUT);
serial_dev.begin(9600);
TCCR1A = _BV(COM1A1) | _BV(WGM11); // That give me a 9 bit Fast PWM at 15.625Khz
TCCR1B = _BV(CS10) | _BV(WGM12);
//TCCR1A = _BV(COM1A1) | _BV(WGM10) | _BV(WGM11); // That second option give me 10 bit at 7.8 Khz
//TCCR1B = _BV(CS10) | _BV(WGM12);
}
void loop() {
vin = analogRead(A2);
serial_dev.println("vin=" + String(vin));
OCR1A = vout/2; // Output on PA6 with (it output vout/2 but cause vin is in 10 bit and output in 9bit).
}
Actually input = ouput for the test, of course after that work it will be change to apply different formula.
You can see in this code i put the 2 version (10 bit and 9 bit).
That all work fine on the Attiny 84
Now goal is to apply that on the Attiny 1614 or even better have the 10 bit ouput with the higher frequency (15.625Khz or more).
The input and serial is ok, just stuck with this ouput, i look over the datasheet but i can't understand how to do it.
Actually on this Attiny 1614 i use PA3 as input (for analogRead), PA5 for the ouput, that i was able to get working with analogWrite but give only 8 bit this way, and PB2, PB3 is my TX, RX that work fine.
I start to think that no possible on the Attiny 1614, i really find nothing in the datasheet and on internet, that strange.
Maybe better to use the DAC output with 4.3V reference that is the max for the Attiny1614, and then use the OP amp to get a 0 to 5V ouput, but will still be in 8 bit since the DAC is in 8 bit.
There may be other libraries as well which come closer to your resolution requirements.
You can also configure a timer to do it directly and here is an example of a 78kHz PWM with 16bit duty cycle resolution It uses timer TCA0, however, it is only an example and I have not considered its impact on the rest of the Arduino environment which may be affected by the use of this timer.
/*
ATtiny1614 PWM example
Use timer TCA0 in normal (non-split) mode.
Possible impact on built in Arduino functions (analogWrite() etc.)
based on https://github.com/MicrochipTech/TB3217_Getting_Started_with_TCA/blob/master/Generating_a_dual-slope_PWM_signal/main.c
and http://ww1.microchip.com/downloads/en/AppNotes/TB3217-Getting-Started-with-TCA-90003217A.pdf
see also https://ww1.microchip.com/downloads/en/DeviceDoc/40001949B.pdf
see data sheet ATTINY1614 20.5
6v6gt / 25. Nov 2022
*/
const uint8_t pwm0 = 7 ; // pwm wave out on PB0 / D7
void setup() {
// Serial.begin( 115200 ) ; // RX=PB2=D5 , TX=PB1=D4
pinMode( pwm0 , OUTPUT ) ;
cli() ;
TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc | TCA_SINGLE_CMP0EN_bm ;
TCA0.SINGLE.CTRLC = TCA_SINGLE_CMP0OV_bm ; // CMP 0
TCA0.SINGLE.CTRLD = 0 ; // 0 = single
TCA0.SINGLE.CTRLECLR = 0 ;
TCA0.SINGLE.CTRLESET = 0 ;
TCA0.SINGLE.CTRLFCLR = 0 ;
TCA0.SINGLE.CTRLFSET = 0 ;
TCA0.SINGLE.EVCTRL = 0;
TCA0.SINGLE.INTCTRL = 0 ;
TCA0.SINGLE.CNT = 0 ;
TCA0.SINGLE.PERBUF = 0x0100 ; // set frequency (also depends on system clock and prescaler(s)
TCA0.SINGLE.CMP0BUF = 0x0020 ; // set duty cycle (same units as frequency)
PORTMUX.CTRLC = 0 ;
TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm | TCA_SINGLE_CLKSEL_DIV1_gc ; // clk
sei() ;
}
void loop() { }
**EDIT **
For a true 10bit resolution the TOP (or in this case TCA0.SINGLE.PERBUF), that is where the counter resets, has to be 1023. That limits the frequency with a 20MHz clock to about 19.5kHz but still within your requirements.
Thanks a lot.
10bit 19.5Khz, that just perfect, i will try it.
If not i will try 8bit is real use, maybe it work ok in case i can't get more.
Thanks again, that help me a lot