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.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…