So far my code works to set a DC voltage on the ADC input, obtain a 8 bit value from the ADC result and produce a PWM output on pin 6 of the MCU by plugging the ADC value into the TOP register.
The ADC 8 bit value is used to set the TOP or slowest frequency of the PWM output.
The BOTTOM value is fixed at 1, that is the fastest frequency of the PWM output.
My next task is to have the PWM output start with the ADC 8 bit value put into OCR0A then subtract 1 from the OCR0A register and do another PWM cycle.
Continuing to do this until the TOP equals the BOTTOM then increment the OCR0A register by one until TOP is reached again.
Finally read the ADC again for another 8 bit value and repeat the cycle.
In addition I need to be able to set the amount of times the PWM output repeats the very same frequency per OCR0A subtraction or addition.
This would adjust the "laziness" of the up down sweep.
Here is my logic, please let me know if I am thinking about this correctly.
1. Read ADC and get 8 bit value.
2. Put value into OCR0A and do one timer cycle.
3. Repeat this cycle "x" amount of times (laziness).
4. Decrement OCR0A by one.
5. Repeat until TOP equals BOTTOM.
6. Then sweep back up to TOP.
7. Back to step 1.
Below is the code for the first part of the project.
Is there a way to CJNE in AVR assembly to allow me to sweep the OCR0A value down then up?
; ; ;======================================================== ; SETUP THE TIMER COUNTER FOR PHASE CORRECT PWM MODE ;======================================================== ; ; ;CT0 in Phase Correct PWM Mode. ;Generating a Waveform: ;OCR0A as TOP, OCR0B as compare, OC0B as output. ;Vary OCR0A to change cycle time. ; ; loop_bak: rcall READ_ADC ;read input voltage and store as a 8 bit value at ADCH ; ;Set OCR0A (TOP) and OCR0B (bottom) ldi TEMP, ADCH out OCR0A, TEMP ;Set the TOP limit as the ADCH value ldi TEMP, 1 out OCR0B, TEMP ;set the BOTTOM limit to ground ; ; ;Configure Timer/Counter 0 ;Select Phase Correct PWM Mode, and OCR0A as TOP. Use WGM Bits. ;WGM Bits are in TCCR0A and TCCR0B. Any previous settings are cleared. ; ; ;OC0B LO when COUNT = OCR0B upcounting, HI when COUNT = OCR0B downcounting. ldi TEMP,0b00100001 out TCCR0A,TEMP ; TCCR0A = 0b10000001 clear OC0A/OC0B on compare match, WGM00 = 1, WGM01 = 0 ; select COM0B1 output mode ldi TEMP,0b00001101 out TCCR0B,TEMP ; TCCR0B = 0b00001001 set clock divide by 1024, WGM02 = 1 = mode 5 ; ; rjmp loop_bak ; ; ; ; ; ; ;=================================== ;READ THE ADC INPUT AND CONVERT TO ;A 8 BIT VALUE. 00000000 = 0V ;11111111 = 5v ;RESULTS ARE AUTOMATICALLY STORED ;IN ADCH REGISTER ;=================================== ; ; READ_ADC: sbi portb, NU2 ;turn on "ADC running" pulse on pin 3 of MCU, WATCH WITH SCOPE sbi ADCSRA, ADSC ;start conversion ADSC to 1 (zeros when done) loopX: sbic ADCSRA, ADSC ;ADSC bit goes low when conversion complete rjmp loopX ;not complete, keep checking cbi portb, NU2 ;turn off "ADC running" pulse on pin 3 of MCU ret ; ;