| Author |
Message |
|
|
Posted: Apr 20, 2012 - 05:09 PM |
|

Joined: Apr 09, 2012
Posts: 27
|
|
I'm trying in vain to use a the CTC timer for the first time. My program will take a value from a pot via the ADC and use it to update the OCR1A register, changing the frequency of the wave. Currently though I am just having trouble with the CTC timer - I have set the OC1 to toggle on a compare match but when I burn it to the AVR OC1 just sits low. When I simulate this, something weird happens - when I write a value to OCR1A, nothing happens, the line just doesn't seem to execute. TCNT1 just counts up to 11111111 and then BACKWARDS to 0. !? Is this supposed to happen or maybe a bug in the way the file compiled? I was pretty sure I set everything right...
can anyone help?
Code:
#include<avr/io.h>
void initialize_ports(void); //initializes ports
unsigned int tempo;
void main(void)
{
initialize_ports();
while(1)
{
ADCSRA|=(0x01<<6);
PORTB ^=0x01;
while(ADCSRA ^ 0b10010000)
{
}
tempo = ADCH;
OCR1AH = tempo;
}
}
}
void initialize_ports(void)
{
DDRB=0xff; // data direction = output
PORTB=0x00;
DDRC=0b11111110; //all pins on portc output except C0
PORTC=0x00;
ADMUX=0b01100000; //set ADC - AVCC reference, left adjust,ADC0 input
ADCSRA=(0x01<<7); // set ADC - enable ADC
DDRD=0xff;
PORTD=0x00;
TCCR1A=0b01000001; // toggle OC1 at compare match, CTC mode
TCCR1B=0b00000001; //
OCR1A=4096; // compare value
}
|
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 05:20 PM |
|

Joined: Feb 12, 2005
Posts: 16324
Location: Wormshill, England
|
|
You don't say which AVR. Let's assume mega32
Using BIT_NAMES really does make a difference.
Code:
TCCR1A = (1<<COM1A0)|(1<<WGM10); //0b01000001; // toggle OC1 at compare match, CTC mode
TCCR1B = (1<<CS10); //0b00000001; //div1
OCR1A = F_CPU/1/2/freq - 1; //4096; // compare value
I can only guess that you want 900Hz with a 7.3728MHz crystal. (and OCR1A = 4095)
Look up WGM10 in your data sheet.
David. |
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 05:43 PM |
|


Joined: Feb 19, 2001
Posts: 25923
Location: Wisconsin USA
|
|
|
Quote:
ADCSRA=(0x01<<7); // set ADC - enable ADC
At max ADC clock rate you are unlikely to get useful results.
Quote:
You don't say which AVR.
An important piece of information.
Quote:
while(ADCSRA ^ 0b10010000)
Very strange. What do you intend to do here?
Quote:
OCR1AH = tempo;
What does the datasheet say about "16.3 Accessing 16-bit Registers"? (I read it that you must write both halves.)
Quote:
When I simulate this, ...
Tell more about that. Many simulators don't do timer modes well. (Oh, I just saw what David saw--CTC mode wasn't selected.) |
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 07:37 PM |
|

Joined: Apr 09, 2012
Posts: 27
|
|
|
david.prentice wrote:
You don't say which AVR. Let's assume mega32
Using BIT_NAMES really does make a difference.
I can only guess that you want 900Hz with a 7.3728MHz crystal. (and OCR1A = 4095)
Look up WGM10 in your data sheet.
David.
OHHHH! I just realised I have the WGM bits the wrong way round. Whoops! OK, thanks for that. Does using the bit names have any effect on the program other than making it clearer?
Quote:
Quote:
ADCSRA=(0x01<<7); // set ADC - enable ADC
At max ADC clock rate you are unlikely to get useful results.
Quote:
An important piece of information.
Quote:
while(ADCSRA ^ 0b10010000)
Very strange. What do you intend to do here?
Quote:
OCR1AH = tempo;
What does the datasheet say about "16.3 Accessing 16-bit Registers"? (I read it that you must write both halves.)
Quote:
When I simulate this, ...
Tell more about that. Many simulators don't do timer modes well. (Oh, I just saw what David saw--CTC mode wasn't selected.)
-I'm just using a one off conversion and doing it in a loop. This is setup ok for this, right? I turn the ADEN bit high, then eery time I want to do a conversion I turn the ADSC bit high and wait for the ADIF flag to turn on before reading the information from ADCH.... Should doing this work? It certainly doesn't seem to be working at the moment....
-chip is atmega328
-that part of the code checks whether the ADC result is ready and if it isn't it just loops. When the ADC is ready ADCSRA changes from 11000000 to 10010000 so XORing the two indicates whether to loop or not
-oh i thought that only applied if you're using assembly..... i'll just write OCR1A to avoid confusion
- I'm just using the debug mode on avrstudio. Seems to work OK now i've got the WGM bit selected to CTC mode.
So now i've got the CTC mode working, the ADC seems to be giving me problems... is the approach i have used to work the ADC OK?
thankyou both, P |
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 07:51 PM |
|


Joined: Feb 19, 2001
Posts: 25923
Location: Wisconsin USA
|
|
|
Quote:
the ADC seems to be giving me problems...
Quote:
At max ADC clock rate you are unlikely to get useful results.
Quote:
while(ADCSRA ^ 0b10010000)
Very strange. What do you intend to do here?
Quote:
then eery time I want to do a conversion I turn the ADSC bit high and wait for the ADIF flag to turn on
But you never turn it off.
I've never seen an exclusive-or on a flag mask.
Anyway, what "doesn't work". How do you expect the simulator to do A/D? |
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 08:05 PM |
|

Joined: Apr 09, 2012
Posts: 27
|
|
- Yes that is true, the datasheet says "ADSC will read as one as long as a conversion is in progress. When the conversion is complete, it returns to zero. Writing zero to this bit has no effect."
- Well, I don't know about programming conventions, I'm just a beginner.. the way I understand it if the result of that XOR is one, the loop will repeat, if it isn't, it will stop - I designed the bit mask accordingly. Seems to work fine
- I am also physically burning the program to an AVR. When I say the ADC is not working I mean in real life, not in the simulator.
What I would expect to see on OC1 (with a scope, on the real life avr) is when I turn the pot the frequency seeps smoothly. What I actually see is that it makes not a lot of difference apart form one region on the pot which makes OC1 jitter about between low and high frequency (the pot works fine)... hmmm |
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 08:30 PM |
|


Joined: Feb 19, 2001
Posts: 25923
Location: Wisconsin USA
|
|
|
Quote:
What I would expect to see on OC1 (with a scope, on the real life avr) is when I turn the pot the frequency seeps smoothly. What I actually see is that it makes not a lot of difference apart form one region on the pot which makes OC1 jitter about between low and high frequency (the pot works fine)... hmmm
Quote:
Quote:
At max ADC clock rate you are unlikely to get useful results.
Quote:
Quote:
At max ADC clock rate you are unlikely to get useful results.
|
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 09:02 PM |
|

Joined: Apr 09, 2012
Posts: 27
|
|
|
|
|
|
|
Posted: Apr 20, 2012 - 09:09 PM |
|

Joined: Apr 09, 2012
Posts: 27
|
|
| If you are trying to point out that "At max ADC clock rate you are unlikely to get useful results." I ned to point out that I am not using a successive approximation, I am using a one time conversion and hence the ADC clock rate is (as far as I'm aware) irrelevant - is this not so? |
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 09:10 PM |
|

Joined: Nov 17, 2004
Posts: 13851
Location: Vancouver, BC
|
|
No, it is very relevant.
Quote:
-oh i thought that only applied if you're using assembly.....
How would the AVR know whether or not you were using assembly? |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 09:21 PM |
|

Joined: Apr 09, 2012
Posts: 27
|
|
well the avr doesn't know. The compiler knows, and compiles the code accordingly. The datasheet states two distinct examples for accessing 16 bit registers, one in assembly, one in C. Either way, I changed my code at theusch's suggestion, it is no longer a problem.
Can you tell me how the ADC clock rate makes a difference to my problem? pretty please? |
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 09:23 PM |
|


Joined: Feb 19, 2001
Posts: 25923
Location: Wisconsin USA
|
|
|
Quote:
I am using a one time conversion and hence the ADC clock rate is (as far as I'm aware) irrelevant - is this not so?
That is not so. It is important for all conversions. I don't see where you stated your AVR clock rate, despite that being important. Anyway, for decent results you want an ADC clock of 200kHz or less. Certainly not many MHz as you are using. |
|
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 09:34 PM |
|

Joined: Nov 17, 2004
Posts: 13851
Location: Vancouver, BC
|
|
|
Quote:
The compiler knows, and compiles the code accordingly.
No, the compiler does what you tell it to do. You told it to write to OCR1AH. The compiler did that. The compiler has no way of knowing that you also want to write to OCR1AL.
Quote:
The datasheet states two distinct examples for accessing 16 bit registers, one in assembly, one in C.
And both those examples wrote to both the high byte and the low byte. |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Apr 20, 2012 - 10:23 PM |
|


Joined: Feb 19, 2001
Posts: 25923
Location: Wisconsin USA
|
|
|
Quote:
And both those examples wrote to both the high byte and the low byte.
And in the section that I referenced
Quote:
When the low byte of a
16-bit register is written by the CPU, the high byte stored in the temporary register, and the low byte written are both copied into the 16-bit register in the same clock cycle.
|
|
|
| |
|
|
|
|
|
Posted: Apr 22, 2012 - 11:57 AM |
|

Joined: Apr 09, 2012
Posts: 27
|
|
| ohhh yes you are totally right, got it working a treat by changing the ADC frequency - thanks so much! |
|
|
| |
|
|
|
|
|