feluma
Newbie level 1
Hello,
I'm new to PWM techniques and I can't find a simple code to compare mine to get a PW mesure using my ATMega328.
The problem is that right now I get measures, but they are not consistent, they present a very wide range of values for the same input signal; I don't know if this is because some asyncronous problem wrong set of registers or other thing.
If somebady could help me would be nice.
I'm new to PWM techniques and I can't find a simple code to compare mine to get a PW mesure using my ATMega328.
The problem is that right now I get measures, but they are not consistent, they present a very wide range of values for the same input signal; I don't know if this is because some asyncronous problem wrong set of registers or other thing.
If somebady could help me would be nice.
Code:
#include <avr\io.h>
#include <avr\interrupt.h>
#include <stdio.h>
#include <string.h>
#define F_CPU 8000000
#include <util/delay.h>
//Asynchronous serial communication
#define BAUD 9600
#define MYUBRR ((F_CPU/BAUD/16)-1)
//ICP measuring
#define ICP PINB0
//define ovrflow counter
uint16_t ov_counter;
//define times for start and end of signal
uint16_t rising, falling;
//define overall counts
uint32_t counts;
//overflow counter interrupts service routine
ISR(TIMER1_OVF_vect){
ov_counter++;
}
//Timer1 capture interrupt service subroutine
ISR(TIMER1_CAPT_vect){
// This subroutine checks was it start of pulse (rising edge)
// or was it end (fallingedge) and performs required operations
if (ICP){ //if high level
//save start time
rising=ICR1;
//set to trigger on falling edge
TCCR1B=TCCR1B&0xBF;
//reset overflow counter
ov_counter=0;
}
else{
//save falling time
falling=ICR1;
//rising edge triggers next
TCCR1B=TCCR1B|0x40;
counts=(uint32_t)falling-(uint32_t)rising+(uint32_t)ov_counter;
//you can convert coutns to seconds and send to LCD
printf("%lu\n", (unsigned long)counts); //Values variates from 800 to 62000 for the same input signal.
}
_delay_ms(100);
}
//Define functions
//======================
void ioinit(void); // Initializes IO
static int uart_putchar(char c, FILE *stream);
uint8_t uart_getchar(void);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
int main(void) {
ioinit(); //Setup IO pins and defaults
//PWM
TIMSK1=0x24; //Enable overflow and input capture interrupts
TCCR1B=0xC1; //Noise canceller, without prescaler, rising edge
sei(); //Enable interrupts
while(1) { // Loop forever timer does the job
}
return(0);
}
void ioinit (void)
{
//1 = output, 0 = input
DDRB = 0b11111110; //PORTB (yP on PB0 / Accelerometer)
DDRC = 0b11111111; //
DDRD = 0b11111110; //PORTD (RX on PD0)
UBRR0H = 0b00000000;
UBRR0L = 0b00110011;
UCSR0A = 0b00100000;
UCSR0B = 0b00011000;
UCSR0C = 0b00110110;
stdout = &mystdout; //Required for printf init
}
static int uart_putchar(char c, FILE *stream)
{
if (c == '\n') uart_putchar('\r', stream);
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
return 0;
}
uint8_t uart_getchar(void)
{
while( !(UCSR0A & (1<<RXC0)) );
return(UDR0);
}