Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

AVR, LM35 temperature and 7seg display

Status
Not open for further replies.

konradIC13

Member
Hello,

Im modifying program
https://extremeelectronics.co.in/avr-tutorials/interfacing-temperature-sensor-lm35/
about interfacing LM35 temperature sensor with 7 segment display to match my project.

Here is my code so far:
Code:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define SEVEN_SEGMENT_PORT PORTD
#define SEVEN_SEGMENT_DDR DDRD

volatile uint8_t digits[2];

void SevenSegment(uint8_t n,uint8_t dp)
{
	/* 
	Function writes numbers to 7 segment
	display by given n and dp
	*/
   if(n<10)
   {
      switch (n)
      {
         case 0:
         SEVEN_SEGMENT_PORT=0b11000000;
         break;
         case 1:
         SEVEN_SEGMENT_PORT=0b11111001;
         break;
         case 2:
         SEVEN_SEGMENT_PORT=0b10100100;
         break;
         case 3:
         SEVEN_SEGMENT_PORT=0b10110000;
         break;
         case 4:
         SEVEN_SEGMENT_PORT=0b10011001;
         break;
         case 5:
         SEVEN_SEGMENT_PORT=0b10010010;
         break;
         case 6:
         SEVEN_SEGMENT_PORT=0b10000010;
         break;
         case 7:
         SEVEN_SEGMENT_PORT=0b11111000;
         break;
         case 8:
         SEVEN_SEGMENT_PORT=0b10000000;
         break;
         case 9:
         SEVEN_SEGMENT_PORT=0b10010000;
         break;
      }
      if(dp)
      {
         SEVEN_SEGMENT_PORT&=0b01111111;
      }
   }
   else
   {
      SEVEN_SEGMENT_PORT=0b10111111;
   }
}

void Wait()
{
	//Function that waits ~1/4 second
	_delay_ms(250);
}

void Print(uint16_t num)
{
   /*
   This function breaks apart a given 
   integer into separete digits
   and writes them to the display 
   array i.e. digits[]
   */
   uint8_t i=0;
   uint8_t j;
   if(num>99) return;
   while(num)
   {
      digits[i]=num%10;
      i++;
      num=num/10;
   }
   for(j=i;j<2;j++) digits[j]=0;
}

void InitADC()
{
	/*
	Set ADC, Vref from internal 2.56V
	Enable ADV conversion, divider by 2
	*/
	ADMUX=(1<<REFS1)|(1<<REFS0);
	ADCSRA=(1<<ADEN)|(7<<ADPS0);
}

uint16_t ReadADC(uint8_t ch)
{
	//Select ADC Channel ch must be 0-7
	ch=ch&0b00000001;
	ADMUX|=ch;

	//Start Single conversion
	ADCSRA|=(1<<ADSC);

	//Wait for conversion to complete
	while(!(ADCSRA & (1<<ADIF)));

	//Clear ADIF by writing one to it
	ADCSRA|=(1<<ADIF);

	return(ADC);
}

int main(void)
{
	uint16_t adc_value;
	uint8_t t;
	/*
	Prescaler 64
	Enable Overflow Interrupt
	Initialize counter
	*/
	TCCR0=0b00000010;
	TIMSK=0b00000001;
	TCNT0=0;
	
	/*
	Port B[3,2,1] R,G,B LED output initial LOW
	Port B[5,4] 7 Segment output initial [HIGH,LOW]
	Port B[0,7,6] FAN [3,2,1] output initial LOW
	Port C[5,4,3,2] Switch input[Control,SW1,SW2,SW3] Pulled-Up
	Unused C[7,6,1] set input Pulled-Up
	Port C[0] is connected to LM35 and is read by ADC
	*/
	DDRB =0b11111111;
	PORTB=0b00100000;
	DDRC =0b00000000;
	PORTC=0b11111110;

	//Port D
	SEVEN_SEGMENT_DDR=0XFF;

	//Turn off all segments
	SEVEN_SEGMENT_PORT=0XFF;

	//Enable Global Interrupts
	sei();

	//Enable ADC
	InitADC();

	//Infinite loop
	while(1)
	{
		//Read ADC
		adc_value=ReadADC(0);

		//Convert to degree Centrigrade
		t=(2.56*adc_value*100)/1024;

		//Print to display
		Print(t);

		//Wait some time
		Wait();

		//<here my future program>

	}
}

ISR(TIMER0_OVF_vect)
{
	static uint8_t i=4;
	static uint8_t j=0;
	if(i==5)
	{
		i=4;
		j=0;
	}
	else
	{
		i++;
		j++;
	}
	PORTB=~(1<<i);
	SevenSegment(digits[j],0);
}

Problem:

transistors that are multiplexing 7segment display are connected to pin 5 and 4 of PORTB, the rest of its pins (7,6,3,2,1,0) i want to set as outputs and use for controling leds and mosfet transistors. Unfortunatly even if i set them on beginning o my program to 0, it seems that this part of program
Code:
ISR(TIMER0_OVF_vect)
{
	static uint8_t i=4;
	static uint8_t j=0;
	if(i==5)
	{
		i=4;
		j=0;
	}
	else
	{
		i++;
		j++;
	}
	PORTB=~(1<<i);
	SevenSegment(digits[j],0);
}

Always sets them back to 1

Unfortunately i cant find solution to prevent this interference between pin 5,4 of PORTB, multiplexing of 7 segment display and using rest of PORTB pins as other outputs.

Any help appreciated.
 
Oh yeah, didnt noticed that, mistook it with PORTB&=~ (1<<i)

Already fixed it
Code:
ISR(TIMER0_OVF_vect)
{
	static uint8_t i=0;
	if(i==1)
	{
		i=0;
	}
	else
	{
		i++;
	} 
	PORTB ^=(1<<PB4);
	PORTB ^=(1<<PB5);
	SevenSegment(digits[i],0);
}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top