Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Carputer Xarias v0.1 - need help with code

Status
Not open for further replies.

tiochico27

Newbie level 5
Joined
May 5, 2008
Messages
8
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,320
Hello!

I'm need help with xarias v0.1 code... when i compile the code and burn in uC, the display initialize but stay blank.

Please, check the code

Code:
#include "defines.h"

#include <ctype.h>
#include <stdint.h>
#include <stdio.h>

#include <avr/io.h>
#include <avr/pgmspace.h>

#include <util/delay.h>
#include <util/twi.h>
#include <avr/interrupt.h>

#include "lcd.h"

#define PIN_INJ   PIND&_BV(3)
#define PORT_INJ  PORTD|_BV(3)


/*
 * Injector flow constant in ml/min
 * For Toyota Corolla 1,3 4EFE it's 136 - 176
 * For Toyota Corolla 1,6 4AFE it's 160 - 200
 */
#define INJ_FLOW 156

/*
 * Number of ticks per one kilometer
 */
#define SPEED_TICKS 2548


FILE lcd_str = FDEV_SETUP_STREAM(lcd_putchar, NULL, _FDEV_SETUP_WRITE);

uint32_t passed_seconds=0, tcnt0_overs=0, passed_speed_ticks=0;
uint16_t clock_ticks=0, inj_ticks=0, tcnt0_overs_sec=0;



void error(char *msg)
{
	stderr = &lcd_str;

	lcd_locate(2,1);
	fprintf(stderr,"ERR: %s",msg);
}


/*
 * This function sends one byte through TWI bus.
 * It returns 0 on success and 1 if failed.
 */
uint8_t twi_write_data(uint8_t data)
{
	TWDR = data;
	TWCR = _BV(TWINT) | _BV(TWEN);

	/*
	 * waiting for TWINT flag set
	 */
	while (!(TWCR & _BV(TWINT)));

	if ( TW_STATUS != TW_MT_DATA_ACK) 
	{
		error("MT_DATA_ACK cmd");
		return 1;
	}
	return 0;
}




/*
 * Do all the startup-time peripheral initializations.
 */
static void ioinit(void)
{
	lcd_init();

	/*
	 * SCL = CPU_Freq / ( 16 + 2 * TWBR * 4^TWPS )
	 */

	TWBR = 98; // with prescaller = 1 gives us 100kHz TWI bus
	TWSR = 0;  // prescaller = 1

	/*
	 * enablibg TWI and sending START condition
	 */
	TWCR = _BV(TWINT)|_BV(TWSTA)|_BV(TWEN);

	/*
	 * waiting for TWINT flag set
	 */
	while (!(TWCR & _BV(TWINT)));

	
	if ( TW_STATUS != TW_START) error("TWI START cmd");


	/*
	 * writing SLA_W and device address 1101 000
	 */
	TWDR = TW_WRITE | 0xD0; 
	TWCR = _BV(TWINT) | _BV(TWEN);

	/*
	 * waiting for TWINT flag set
	 */
	while (!(TWCR & _BV(TWINT)));

	if ( TW_STATUS != TW_MT_SLA_ACK) error("MT_SLA_ACK cmd");

	/*
	 * writing address start 0
	 */
	twi_write_data(0);

	twi_write_data(0);
	twi_write_data(0);
	twi_write_data(0);
	twi_write_data(0);
	twi_write_data(0);
	twi_write_data(0);
	twi_write_data(0);

	/*
	 * writing control register
	 * turning on output (bit 7) and setting 32,768 kHz (bits 0 and 1)
	 */
	twi_write_data(_BV(4)|_BV(0)|_BV(1));

	TWCR = _BV(TWINT)|_BV(TWEN)|_BV(TWSTO);




	/*
	 * Enable external interrupt 0
	 */
	GICR = _BV(INT0);

	/*
	 * Falling edge will generate interrupt 0
	 */
	MCUCR |= _BV(1);


	/*
	 * enable pull-up resistors for ports D2 and D3
	 */
	PORTD |= _BV(2) | _BV(3);

	/*
	 * enable all interrupts
	 */
	sei();


	/*
	 * external clock source for Timer0, clock on falling edge
	 */
	TCCR0 |= _BV(2) | _BV(1);
	/*
	 * enable Timer0 overflow interrupt
	 */
	TIMSK |= _BV(0);

}

/*
 * This function return fuel consumption in l/h * 1000
 * We assume that fuel consumption is not greater than 65.536 l/h
 * Although l_inj_ticks is uint64_t, it cannot be greater than
 * xxxxxx and 
 */
uint16_t calc_fuel_h(uint64_t l_inj_ticks, uint32_t l_seconds)
{
	return (uint16_t)((l_inj_ticks*INJ_FLOW*15)/((uint64_t)2048*l_seconds));
}

uint16_t calc_fuel_100(uint16_t l_fuel_h, uint64_t l_speed_ticks, uint32_t l_seconds)
{
	return (uint16_t)(((uint64_t)l_fuel_h*SPEED_TICKS*l_seconds)/(l_speed_ticks*36));
}

uint16_t calc_speed_m(uint64_t l_speed_ticks, uint32_t l_seconds)
{
	return (uint16_t)(l_speed_ticks*1000/(SPEED_TICKS*l_seconds));
}


uint32_t power(uint32_t x, uint8_t y)
{
	uint8_t i;
	uint32_t retval=1;
	for(i=0;i<y;i++,retval*=x);
	return retval;
}

/*
 * Cuts last p digits of the value
 */
#define CUT(val,mult) ((uint16_t)((val)/power(10,(uint8_t)mult)))

/* 
 * The most calculations in this program made on integer values. 
 * Floating point precision is achieved by doing calculations on 
 * values multiplied with 10^x, where i x is precision. For example 
 * if we want to write 2.345 with precision of 3 digits after 
 * floating point, we will use 2345, as it is equal to 2.345*10^3
 * Recalculation is done just before displayng the values.
 * The next three macros are provided to made such calculations.
 *
 * Parameters:
 *    <val>   - value on which calculations are made
 *    <mult>  - multiplier 
 *    <prec>  - precision of the calculations; shoud be less
 *              or equal then multiplier
 *
 * ROUND macro just do the rounding to <prec> digits after
 * imaginable point. Be aware that it does not truncate the rest 
 * digits
 *
 * uint32_t gives us 4294967 km 296 m of maximium pass
 */
#define ROUND(val,mult,prec) ((uint32_t)(val+5*power(10,(uint8_t)mult-prec-1)))

/*
 * This macro just truncates digits after the floating point, so it
 * only left integer part before.
 */
#define ROUND1(val,mult,prec) ((uint16_t)CUT(ROUND(val,mult,prec),mult))

/*
 * And the following macro truncate digits before floating point,
 * so it only left floating part with the specified precision.
 */
#define ROUND2(val,mult,prec) (uint16_t)(CUT(ROUND(val,mult,prec)-CUT(ROUND(val,mult,prec),mult)*power(10,(uint8_t)mult),mult-prec))


int main()
{
	stderr = &lcd_str;

	ioinit();

	return 0;
}


SIGNAL(SIG_INTERRUPT0)
{
	static uint64_t passed_inj_ticks=0;

	uint8_t pin_inj_state=PIN_INJ;
	if(!pin_inj_state) inj_ticks++;

	if(!clock_ticks)
	{
		uint16_t m_speed_m, m_speed_km, avg_speed_m, avg_speed_km;
		uint16_t m_fuel_h, m_fuel_100, avg_fuel_h, avg_fuel_100, speed_ticks;
		uint32_t passed_distance;
		uint8_t  tcnt0;
		
		tcnt0=TCNT0;
		TCNT0=0;
		tcnt0_overs_sec=0;

		speed_ticks=tcnt0_overs_sec*256+tcnt0;
		passed_speed_ticks += speed_ticks;
		passed_inj_ticks += inj_ticks;
		passed_distance=passed_speed_ticks*1000/SPEED_TICKS;

		m_fuel_h     = calc_fuel_h(inj_ticks,1);
		m_fuel_100   = calc_fuel_100(m_fuel_h,speed_ticks,1);
		avg_fuel_h   = calc_fuel_h(passed_inj_ticks,passed_seconds);
		avg_fuel_100 = calc_fuel_100(avg_fuel_h,passed_speed_ticks,passed_seconds);

		m_speed_m    = calc_speed_m(speed_ticks,1);
		m_speed_km   = m_speed_m * 36 / 10;
		avg_speed_m  = calc_speed_m(passed_speed_ticks,passed_seconds);
		avg_speed_km = avg_speed_m * 36 / 10;


		// printing speed in km/h and m/s
		lcd_locate(1,1);
		fprintf(stderr, "%3u km/h  %3u m/s",m_speed_km,m_speed_m);

		// printing fuel consumption
		lcd_locate(2,1);
		fprintf(stderr, " %3u.%u l/100km %2u.%u l/h",ROUND1(m_fuel_100,3,1),ROUND2(m_fuel_100,3,1),ROUND1(m_fuel_h,3,1),ROUND2(m_fuel_h,3,1));

		// temporarily: checking for error
		if(ROUND2(m_fuel_100,3,1)>9) { lcd_locate(1,1); fprintf(stderr,"%u",m_fuel_100); while(1);}
		
		// avarage speed and fuel consumption
		lcd_locate(3,1);
		fprintf(stderr, "%3u km/h %3u.%u l/100",avg_speed_km,ROUND1(avg_fuel_100,3,1),ROUND2(avg_fuel_100,3,1));
		
		// printing journey time
		lcd_locate(4,1);
		fprintf(stderr,"%02u:%02u:%02u", (uint8_t)(passed_seconds/3600),(uint8_t)((passed_seconds%3600)/60),(uint8_t)(passed_seconds%60));

		// printing passed dist
		lcd_locate(4,10);
		fprintf(stderr, "%4u.%03u km",ROUND1(passed_distance,3,3),ROUND2(passed_distance,3,3));
			
	
		passed_seconds++;
		inj_ticks=0;
	}

	clock_ticks++;
	if(clock_ticks==32768)
	{
		clock_ticks=0;
	}
}


SIGNAL(SIG_OVERFLOW0)
{
	tcnt0_overs++;
	tcnt0_overs_sec++;
}

Thanks a lot!
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top