[Help] The PWM output on OC2A is controlled by the data value written to the OCR2A register.

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

*question removed by owner*

Last Edited: Sun. Apr 12, 2020 - 04:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Should not take any polling.

 

Just enable the connection from the OCR2A register to the port pin, and it will go without any program intervention (other than initialization).

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you mean by make the connection sorry!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look at TCCR2A, particularly the COM2A1:0 Compare match output A mode bits. Be carful to look at the correct table. From your code comment, I  don't think that you recognize the capability that these provide.

 

With this, you do not need to use any interrupts to control the PWM output. It all happens automagically in hardware. 

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Fri. Apr 10, 2020 - 11:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes okay I have looked over the table again but am unsure as to what is happening.

COM2A1 = 1, COM2A0 = 0, clear OC2A on compare match and set OC2A at bottom!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, if you have it set that way, and do not get a PWM, then the "only" things that should prevent a PWM signal are:

 

1) No Timer2 clock

2) Incorrect Mode

3) OCR2A set either at 0 or full count

 

Have not looked closely enough to how you have mode set, but, to get started, I would choose a mode something like FastPWM that causes it to count from 0 to 255. Once you have that running, then try one of the other modes. I would then set OCR2A to 127 and I would choose TCCR2B CS22:0 to 111 for a relaxed period that you can see with almost anything.

 

Jim

 

 

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

input_ADC has the values 0, 1 or 2, therefore ;
1) if ((input_ADC ^ ADMUX) == 0) will be false because bit-7 (REFS0) in ADMUX has been initialised to 1
2) ADMUX = input_ADC; will change the voltage reference from AVCC to AREF


The checking inside the while(!(ADCSRA & (1<<ADIF))) //Wait until ADIF flag goes high ( Conversion complete) loop is wrong.
for instance, else if (ADMUX & (1<<MUX2)) will never be true because bit-3 (MUX2) can never be set if input_ADC has values of 0, 1 or 2.
Actually., there is ho need to check ADMUX to determine what to print, because input_ADC already has the desired ADC channel number.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah yes thanking you!
So if i replaced the first part with:

	if ((input_ADC ^ MUX0) == 0)
	
	{
		//adc input hasnt changed
	}
	else
	{
		ADMUX |= (input_ADC << MUX0);
			
	}

would this work as intended? Can I enter MUX0 and it will read the MUX1 bit above it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Remove all the references to a LM35 or a Light_dependent resistor.  The "code spec" just says "control an LED's brightness using PWM".  It doesn't say anything about using LM35 or LDR or '0'-'9' to control the LED brightness.

 

Set the timer with the LED to do fast PWM (0-255).

Start the ADC, wait until it finishes (@ 20-50 microSeconds).

Divide the result by four.

Set the timer (that controls the LED brightness PWM) to the adjusted ADC result.

 

The TX UART IRQ is different from all the others.  Only have the TX IRQ active when there are characters in the TX buffer.  When qcntr equals sndcntr, turn off the TX IRQ.   The TX IRQ will happen whenever it is enabled and qcntr=sndcntr.  If there are no chars in the TX buffer, then the TX IRQ will be constantly re-triggered.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MUX0 (0), MUX1 (1), MUX2 (2) are bit identifiers and must be used together to select one ADC channel.
To check for channel 1 use if ( input_ADC == 1 )


Because you only print values for one channel at a time, it would be more readable to replace the nested if() s with ;

switch( input_ADC )<br />
  {<br />
  case 0 :<br />
// print values for ADC channel 0<br />
     break;</p>
<p>  case 1 :<br />
// print values for ADC channel 1<br />
     break;</p>
<p>  case 2 :<br />
// print values for ADC channel 2<br />
     break;</p>
<p>  default :<br />
// print error message<br />
  }
my browser is displaying HTML formatting codes inside code blocks, so if you see crud like < br />[/i] or < p> or < /p> please ignore them,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code spec is just a segment from the whole project! Hence the extra parts

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes okay, instead I have used if ( input_ADC == 0 )

else if if ( input_ADC == 1 )

else if ( input_ADC == 2 ).

Regarding the other part you mentioned before.

How can i test if there is a new input_ADC compared to what was last?
if ((input_ADC ^ MUX0) == 0)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want a 'one-shot' change-of-state event you should ;
1: define a 'change-of-state' flag,
2: after changing the ADC channel set that flag to 'true',
3: somewhere else in your code you check that flag and if it is 'true' you do { whatever needs to be done and clear the flag }