imranahmed
Advanced Member level 3
- Joined
- Dec 4, 2011
- Messages
- 822
- Helped
- 3
- Reputation
- 6
- Reaction score
- 3
- Trophy points
- 1,298
- Location
- Karachi,Pakistan
- Activity points
- 6,533
Digit=number; // Convert float to Integer
Decimal=(number - Digit) * 10; // Get The Decimal Digit
Thank you dear PA3040,
Dear I need to display amperes i.e 0.5 , 1.75 , 1.5 , 7.5 , 11.8 , 23.5 or etc like this.
But he makes fixed decimal point , how to move decimal point according to input value of current?
#include <avr/io.h>
#include <avr/interrupt.h>
#define SEVEN_SEGMENT_PORT PORTB
#define SEVEN_SEGMENT_DDR DDRB
volatile uint8_t digits[2];
volatile uint8_t digits1[2];
unsigned char mcount=0,p=0,swcount=0,flag=0;
unsigned int av=0,RBV=0;
float fc=0.005,dispv=0,dispv1=0,dv=0,dv1=0,dv2=0,tmp1=0,tmp=0;
void SevenSegment(uint8_t n)
{
/*
n must be less than 9
//0x3f,~0x06,~0x5b,~0x4f,~0x66,
//0x6d,~0x7d,~0x07,~0x7f,~0x67;
*/
if(n<10)
{
switch (n)
{
case 0:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b00111111;
break;
case 1:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b00000110;
break;
case 2:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b01011011;
break;
case 3:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b01001111;
break;
case 4:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b01100110;
break;
case 5:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b01101101;
break;
case 6:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b01111101;
break;
case 7:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b00000111;
break;
case 8:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b01111111;
break;
case 9:
//.gfedcba
SEVEN_SEGMENT_PORT=~0b01101111;
break;
}
}
}
void Print(uint16_t num)
{
/*
This function breaks apart a given integer into separate digits
and writes them to the display array i.e. digits[]
*/
uint8_t i=0;
uint8_t j;
if(num>999)
return ;
while(num)
{
digits[i]=num%10;
i++;
num=num/10;
}
for(j=i;j<3;j++)
digits[j]=0;
}
void Print1(uint16_t num1)
{
/*
This function breaks apart a given integer into separate digits
and writes them to the display array i.e. digits[]
*/
uint8_t i=5;
uint8_t j;
if(num1>999)
return ;
while(num1)
{
digits1[i]=num1%10;
i++;
num1=num1/10;
}
for(j=i;j<8;j++)
digits1[j]=0;
}
void InitTimer0(){ //Overflow timer0
TCCR0|=(1<<CS01)|(1<<CS00); // PRESCALAR = 64
TIMSK|=(1<<TOIE0);
TCNT0 = 0;
OCR0 = 20;
}
void InitTimer1(){
TCCR1B |= 0x09;
OCR1AH = 0x9C;
OCR1AL = 0x3F;
TIMSK |= 0x10;
}
void InitADC()
{
ADMUX |=(1<<REFS0); // For Aref=AVcc;
ADCSRA|=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS0);// Prescalar = 32
ADCSRA|=(1<<ADSC);
}
uint16_t read_adc(uint8_t ch)
{
//Select ADC Channel ch must be 0-7
ADMUX = (ADMUX & 0xF8) | ch;
ADCSRA|=(1<<ADSC);
while(!(ADCSRA & (1<<ADIF)));
ADCSRA|=(1<<ADIF);
return(ADCW);
}
ISR(TIMER1_COMPA_vect)
{
if((PIND & (1<<PD6)) == 0)
{
swcount++;
if(swcount==100)
{
p++;
swcount=0;
}
}
mcount++;
}
ISR(TIMER0_OVF_vect)
{
TCNT0=0;
// This interrupt service routine (ISR)
// Updates the displays
static uint8_t i=0;
if(i==5)
{
//If on last display then come
//back to first.
i=0;
}
else
{
//Goto Next display
i++;
}
//Activate a display according to i
PORTD&=(0b11000000);
PORTD|=(1<<i);
SevenSegment(digits[i]);
}
void state_display(){
switch(p){
case 0:
PORTC &= ~(1<<PC0);
PORTC &= ~(1<<PC2);
PORTC |= 1<<PC1;
av=read_adc(1); // yellow volts
dv = dv + ( av - dv) * fc ;
av=read_adc(3); // yellow amps
dv1 = dv1 + (av - dv1) * fc ;
if(mcount==100)
{
mcount=0;
dispv=dv;
dispv1=dv1;
flag=1;
}
break;
case 1:
PORTC &= ~(1<<PC1);
PORTC |= 1<<PC2;
av=read_adc(2); // blue volts
dv = dv + ( av - dv) * fc ;
av=read_adc(3); // yellow amps
dv1 = dv1 + (av - dv1) * fc ;
if(mcount==100)
{
mcount=0;
dispv=dv;
dispv1=dv1;
flag=1;
}
break;
case 2:
PORTC &= ~(1<<PC2);
PORTC |= 1<<PC0;
av=read_adc(0); // red volts
dv = dv + ( av - dv) * fc ;
av=read_adc(3); // yellow amps
dv1 = dv1 + (av - dv1) * fc ;
if(mcount==100)
{
mcount=0;
dispv=dv;
dispv1=dv1;
flag=1;
}
break;
case 3:
PORTC |= 1<<PC0;
PORTC |= 1<<PC2;
av=read_adc(0); // red_blue volts
dv = dv + ( av - dv) * fc ;
av=read_adc(2); // blue_red volts
dv2 = dv2 + ( av - dv2) * fc ;
RBV=((dv+dv2)*0.866);
av=read_adc(3); // yellow amps
dv1 = dv1 + (av - dv1) * fc ;
if(mcount==100)
{
mcount=0;
dispv=RBV;
dispv1=dv1;
flag=1;
}
break;
case 4:
PORTC &= ~(1<<PC0);
PORTC |= 1<<PC1;
PORTC |= 1<<PC2;
av=read_adc(2); // blue_yellow volts
dv = dv + ( av - dv) * fc ;
av=read_adc(1); // yellow_blue volts
dv2 = dv2 + ( av - dv2) * fc ;
RBV=((dv+dv2)*0.866);
av=read_adc(3); // yellow amps
dv1 = dv1 + (av - dv1) * fc ;
if(mcount==100)
{
mcount=0;
dispv=RBV;
dispv1=dv1;
flag=1;
}
break;
case 5:
PORTC &= ~(1<<PC2);
PORTC |= 1<<PC0;
PORTC |= 1<<PC1;
av=read_adc(0); // red_yellow volts
dv = dv + ( av - dv) * fc ;
av=read_adc(1); // yellow_red volts
dv2 = dv2 + ( av - dv2) * fc ;
RBV=((dv+dv2)*0.866);
av=read_adc(3); // yellow amps
dv1 = dv1 + (av - dv1) * fc ;
if(mcount==100)
{
mcount=0;
dispv=RBV;
dispv1=dv1;
flag=1;
}
break;
default:
p=0;
break;
}}
void atomic_display(){
cli();
tmp1=dispv1;
tmp=dispv;
sei();
Print1(tmp1); // Print1 for digit 1-3
Print(tmp); // Print for digit 4-6
}
void initialize(){
DDRD|= 0b00111111;
PORTD|= 0b01111111;
//Port B AS OUTPUT
SEVEN_SEGMENT_DDR=0XFF;
//Turn off all segments
SEVEN_SEGMENT_PORT=0X00;
// _delay_ms(1000);
InitTimer0();
InitTimer1();
InitADC();
DDRA = 0b00000000;
DDRC |= 0x07;
PORTC = 0x00;
//Enable Global Interrupts
sei();
//Infinite loop
}
int main()
{
initialize();
while(1)
{
state_display();
if(flag==1){
atomic_display();
flag=0;
}}
}
Code C - [expand] 1 2 // Define the segment combinations corresponding to each number const char Segments[10] = {0b00111111, 0b00000110, ...};
Code C - [expand] 1 2 3 void SevenSegment(uint8 n) { SEVEN_SEFGMNET_PORT = Segments[n]; }
Code C - [expand] 1 2 for(j=i;j<3;j++) digits[j]=0; for(j=i;j<8;j++) digits1[j]=0;
How can I handle DOT in my code?
In print function this "for(j=i;j<3;j++) digits[j]=0;" use separating digits coming from ADC channel.
Code C - [expand] 1 2 volatile uint8_t digits[2]; volatile uint8_t digits1[2];
Now your last mail is very confusing. You cannot display 102.4 because you have only
3 digits.
Do you mean 1024 correspond 5.00?To 1024 should correspond 500.
Please more clarify above quote.And beside this, just for your info: avoid divisions on a MCU except if you cannot
do anything else. In this case, you can.
Do you mean 1024 correspond 5.00?
...yes, 1024 (or more precisely 1023) will ...
for most applications this is not important, but most ADCs and DACs work with
1024 to be fullscale (for a 10 bit converter)
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?