How to calculate Pulse width using xmega256 TIMER in Capture Mode

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

Hello friends

Maybe it is repeated question, but really i could not solve the problem, so ...

I have to interface HCSR04 with ATXMega256. I am using the TCC0 Timer in Capture mode with setting it to capture pulse width, using Event System Channel 0 source: Port A Pin0.

Anyway, my code is shown below in one file using USARTE1 to send the measurement to another terminal:

#define F_CPU 16000000UL
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/io.h>

#define USART_Format_Set(_usart, _charSize, _parityMode, _twoStopBits)         \
(_usart)->CTRLC = (uint8_t) _charSize | _parityMode |                      \
(_twoStopBits ? USART_SBMODE_bm : 0)

#define USART_RxdInterruptLevel_Set(_usart, _rxdIntLevel)                      \
((_usart)->CTRLA = ((_usart)->CTRLA & ~USART_RXCINTLVL_gm) | _rxdIntLevel)

#define USART_Baudrate_Set(_usart, _bselValue, _bScaleFactor)                  \
(_usart)->BAUDCTRLA =(uint8_t)_bselValue;                                           \
(_usart)->BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8)

#define USART_Rx_Enable(_usart) ((_usart)->CTRLB |= USART_RXEN_bm)
#define USART_Tx_Enable(_usart)	((_usart)->CTRLB |= USART_TXEN_bm)

#define USART_IsTXDataRegisterEmpty(_usart) (((_usart)->STATUS & USART_DREIF_bm) != 0)
#define USART_PutChar(_usart, _data) ((_usart)->DATA = _data)
void usart_putchar (uint8_t data)
{

	while(!USART_IsTXDataRegisterEmpty(&USARTE1));
	USART_PutChar(&USARTE1, data);
}
volatile uint16_t pulseWidth = 0;
int main(void)
{
	cli();
	int16_t count_a = 0;
	//System clock External oscillator 16 MHz
	OSC.XOSCCTRL=OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;
	OSC.CTRL|=OSC_XOSCEN_bm;
	CCP=CCP_IOREG_gc;
	while ((OSC.STATUS & OSC_XOSCRDY_bm)==0);
	OSC.CTRL&= ~(OSC_RC2MEN_bm | OSC_RC32MEN_bm | OSC_RC32KEN_bm | OSC_PLLEN_bm);
	PORTCFG.CLKEVOUT=(PORTCFG.CLKEVOUT & (~PORTCFG_CLKOUT_gm)) | PORTCFG_CLKOUT_OFF_gc;
    //Port initialize
	PORTB.DIR =0x01;//Trig Port at PB0
	PORTA.DIR = 0x00;//Echo Port at PA0
	PORTA.PIN0CTRL = PORT_ISC_BOTHEDGES_gc;
	PORTE.DIR=0x80;//USART at USARTE1
	//Timer TCCO in capture pulse width mode
	EVSYS.CH0MUX = EVSYS_CHMUX_PORTA_PIN0_gc;
	TCC0.CTRLB = TC0_CCAEN_bm | TC_WGMODE_NORMAL_gc;
	TCC0.CTRLA = TC_CLKSEL_DIV1_gc;
	TCC0.CTRLD = TC_EVACT_PW_gc | TC_EVSEL_CH0_gc;
	TCC0.INTCTRLB = TC_CCAINTLVL_LO_gc;
	TCC0.INTFLAGS=TCC0.INTFLAGS;
	//USARTE1
	USART_Format_Set(&USARTE1, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);
	USART_RxdInterruptLevel_Set(&USARTE1, USART_RXCINTLVL_LO_gc);
	USART_Baudrate_Set(&USARTE1, 0xCE5 , -5);//9600
	USART_Rx_Enable(&USARTE1);
	USART_Tx_Enable(&USARTE1);
	//PMIL
	PMIC.INTPRI=0x00;
	PMIC.CTRL |= PMIC_LOLVLEX_bm;
	sei();
    while (1)
    {
		 PORTB.OUT = 0x01;//trig the sensor
		 _delay_us((20));
		 PORTB.OUT = 0x00;
		count_a = pulseWidth/58;
		//pulseWidth = 0;
		uint8_t hByte = count_a >> 8;
		uint8_t lByte = count_a &0xff ;
		count_a = 0;
		usart_putchar(hByte);
		usart_putchar(lByte);
		_delay_ms(250);
    }
}
ISR(TCC0_CCA_vect)
{
	pulseWidth = TCC0.CCA;
}

In Atmel Studio 7 I have written a .stim file to generate pulses with 10 ms, and in simulation I was able to capture this pulse which is equal to 10000/58=172cm

, but with the real xmega, the terminal received random bytes. Also I checked the USARTE1 sending process and it works fine.

Have you any suggestion please to determine where the problem is?

Do i need to disable TCCA interrupt when i calculate the distance in cm?

Do i need to clear CCAIF manually inside CCA ISR?

thank you

Last Edited: Mon. Nov 18, 2019 - 11:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AdamMe wrote:

 PORTB.OUT = 0x01;//trig the sensor
		 _delay_us((20));
		 PORTB.OUT = 0x00;
		count_a = pulseWidth/58;
		//pulseWidth = 0;

 

How is this going to work? You don't wait for the pulse to happen!

 

Also read up on the use printf() - this will make things easier for you in printing human readable rather than hex values.

 

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

This is the same thing you are asking here:

 

https://www.avrfreaks.net/forum/...

 

Keep it in the other thread

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Topic locked