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.

How displays adc results on 7-segment display

Status
Not open for further replies.
7-segment,display pic16f676

Can any one explain me how to do 7 segment multiplexing using C. Just give some sample.
 

7 segment display lcd

Man...you have to read previous post....only that...and youll get a idea....
C compilers makes a HEX like asm, using PIC instrucction....

So....turn ON a display, then turn OFF, and so on with others....the on time depends of human eye....1/20 s of retention....5 ms to retend the image...is the time ncesarry to stay ON the display...then....turn off it and turn on the following display..in this case...3 displays....

To turn ON a display, use a PNP transistor if case is AC, and NPN if ist CC.....

Firts, you must study how 7 segments displays works...


Bye
 

interface adc to 7 segment display

I know all this timing thing. I want to know how you will implement this in C.
 

display temperature, multiplexer, adc

WELL...the above code is a multiplexing rutine...

read it...

Bye
 

pic16 clock 7seg

Thanks I will try that. And you have ebook on PIC micro?
 

code example 7-segment

can i get the same code in assembly
 

Re: pic adc seven segment display

metal said:
Code:
// use PIC16F676
#include <16F676.h>
// ADC resolution is 10 bits
#device adc=10
// Define fuses !!
#fuses INTRC_IO,NOWDT,PUT,NOPROTECT,BROWNOUT,NOMCLR
// Define clock used for this MCU
#use delay (clock=4000000) // 4MHz clock
// No need for that any way !!
#rom  0x3ff={0x3444}
// Define PIC Ports
#byte PORTA = 0x05
#byte PORTC = 0x07
#byte TRISA = 0x85
#byte TRISC = 0x87
// I don't see it necessary to redifne ports in another  name
#define SPORTA PORTA
#define SPORTC PORTC
// Define some constants for interuupts
#define  TICKS_BETWEEN_INTERRUPTS      5000 //5000
#define  INTERRUPT_OVERHEAD            35
#define  TMR1RESET (0xFFFF-(TICKS_BETWEEN_INTERRUPTS-INTERRUPT_OVERHEAD))
// Here the 7 segment decoder values reside
const char SegCode[11] = {0x40,0x57,0x22,0x06,0x15,0x0C,0x08,0x56,0x00,0x04,0xFF};
	//                       0    1    2    3    4    5    6    7    8    9
// Used to output manipulate digits, one at a time (MUX)
const char Column[3]   = {0x02,0x01,0x04};
static char Segment[3] = {0x7f,0x7f,0x7f};	
static unsigned char ColCount=0x00;
// PIC CPU intialization function protoype
void CPU_SETUP(void);
// Display function protoype
void Display(void);
// ADC result manipulation function protoype
void HTO7S(unsigned int32 Num);

byte i;
unsigned int32 result;
// Interrupt handler routine, use timer 1 interrupt
#INT_TIMER1
void Timer1(void)
{
// Set timer 1 to use its interrupt for display 	muxing
set_timer1(TMR1RESET);    
// Display the result on 7 seg digits
Display();	
}	

void main()
{		
	unsigned char i;
Initialize PIC configuration, nice way to do that in deed	
CPU_SETUP();
	
while(true)
{			
result=0;
// Read adc result 20 times using this for loop
for (i=0;i<20;i++)
{
set_adc_channel(3); 
delay_ms(1); 
// finally, the reslt will contain 20 ADC readings
result=result+read_adc();
}
//result = 0x3fe;
// Take the average of the 20 ADC results readings, and 
// use it to manipulate this to be able to display it on 7 digits	
HTO7S(result/20);	
delay_ms(200);		    
}
	
}

void CPU_SETUP()
{
// not use comparator module 	
setup_comparator(NC_NC_NC_NC);
// A3 as analog input, refrences are Vss, and Vdd	
setup_adc_ports( sAN3 | VSS_VDD); 
//Divide the internal clock for use ADC on 64 = 1000000/64
setup_adc(ADC_CLOCK_DIV_64);
TRISA=0b00011000;
PORTA=0x27;
TRISC=0b00000000;
PORTC=0x37;
   
// Use internal clock, prescalar ratio is 1   
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
// Reset timer 1 now
set_timer1(TMR1RESET);
// Set the global interrupt bit in options register
enable_interrupts(GLOBAL);
// enable timer 1 interrupt now
enable_interrupts(INT_TIMER1);   
}

//-------------------------------------
// Display routine
//-------------------------------------
void Display()
{
// off all digits column and Segment G
PORTA = 0b00100111;
// off segment a-f		  
PORTC = 0b00111111;   
delay_cycles(2);
	
// for loop could be used here, but it will cause a stack overflow !!
if (ColCount>=3) 
ColCount=0;
// Display corresponding digit    	
SPORTC = Segment[ColCount];
// maniplate digit value in order to put the bits on portc and porta.5
// XOR it with 7, solve this your self, its easy
SPORTA = ((Segment[ColCount] & 0b01000000)>>1) | (Column[ColCount]^0x07);
ColCount++;				
}	

//--------------------------------------
// Convet HEX 2 byte to 7-Segment code
//--------------------------------------
void HTO7S(unsigned int32 Num)
{

unsigned int32 res;

	
Segment[0]=SegCode[30*Num/10230];
// If first digit is 0, turn it off
if (Segment[0]==0x40) 
Segment[0]=0xFF;
// manipulate the result in order to display it on digits, maths trick, but smart one.
// needs another post in deed for me to explain	
res = 30*Num%10230;
Segment[1]=SegCode[10*res/10230];
res=10*res%10230;
Segment[2]=SegCode[10*res/10230];
}

I have modified this code to use it with common cathod display, instead of common anode one, because this is what I found in my components box. Its wasn't easy at the start, but when I figured out what each line of code does, it becamse easy to make those changes.


can u proveid hex code
 

can someone help me find a schematic and code for digital thermometer using LM35 and that can display into 7 segment (0 - 150.5 degree celcius)..plz..tnx
 

hi all '
can anyone guide me how to change port of pic16f676 for above volt meter projects provided by mr metal.plese help me.thanks
munna
 

Re: seg disp code for asm language

Hi
I want to ask you what's the purpose of this initialization.
const char SegCode[11] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xFF};
// 0 1 2 3 4 5 6 7 8 9 OFF
const char Column [3] = {0x06,0x05,0x03}; //0x06 MS digit

I mean why you select these paricular values in initialization?

thanks
 

Each value represents the segments that should turn on in order to show the number so when you assign SegCode[0] to the port that is connected to the segments then the port value will be 0x01000000 (which is 0x40) and this will turn on all the segments except from the middle line and will show "0".

when you assign SegCode[1] to the port that is connected to the segments then the port value will be 0x01111001 (which is 0x79) and this will turn on only two segments and will show "1".

This value depends on how is your display wired (which pin goes to which led segment) and which value turns the segnemt on (0 or 1).

Alex

---------- Post added at 16:57 ---------- Previous post was at 16:55 ----------

Column [3] = {0x06,0x05,0x03}; does the same thing when you assign it to the port that controls if a digit is on or off, it turns on the first display (Column [0]) , the second (Column [1]) or the third (Column [2])
 
  • Like
Reactions: sumiii

    sumiii

    Points: 2
    Helpful Answer Positive Rating
Ohhh got it !!!!!!
Thank you so much alexan_e :)
 

hi sir Mr.alexan_e
when you assign SegCode[0] to the port that is connected to the segments then the port value will be 0x01000000 (which is 0x40) and this will turn on all the segments except from the middle line and will show "0".
0x01000000 it show port (7, 6, 5, 4, 3, 2, 1 & 0) OK ||
but PIC16F676 have only portc (5, 4, 3, 2, 1 & 0) & porta (5, 4, 3, 2, 1 & 0) .mens each port have only SIX I\P & O\P .
so request pl explan hear port a & c , management . how both port use o\p as "3 digits Digital volt meter" for 7 segment .
 

I haven't used a device like the mcu you describe but the only solution I see is to use a second port

for example you can use
portc = (SegCode[0] &(0x3f)); // assign only the six bits from the left
porta = porta | ((Column[0]<<2) & 0x7) | ((SegCode[0]>>6) & 0x3); assign the three bits of Column[0] and the two bits of SegCode[0]

Alex
 

I haven't used a device like the mcu you describe but the only solution I see is to use a second port

for example you can use
portc = (SegCode[0] &(0x3f)); // assign only the six bits from the left
porta = porta | ((Column[0]<<2) & 0x7) | ((SegCode[0]>>6) & 0x3); assign the three bits of Column[0] and the two bits of SegCode[0]

Alex
but
SPORTC = Segment[ColCount];
SPORTA = ((Segment[ColCount] & 0b01000000)>>1) | (Column[ColCount]^0x07);
how ?
 

whats wrong with me ...
Code:
/*        voltmeter For 0 volt to 300 volt link are as 

http://coolcircuit.com/project/meter/index.html
          Shivendra Sahu        
        16F676 Configuration   
          O = Output, I = Input
                             _________
                       vdd   | 1  14 |  Vss
for 1 (0)1ST_DISPLY--> RA5   | 2  13 |  AN0 <-- Sense_Value (I)
      (O)  SEG_(G) <-- RA4   | 3  12 |  AN1 --> 3RD_DISPLY (0) for 100
               N\C    MCLR   | 4  11 |  RA2 --> 2ND_DISPLY (0) for 10
      (O)  SEG_(F) <-- RC5   | 5  10 |  RC0 --> SEG_(A) (O)
      (O)  SEG_(E) <-- RC4   | 6   9 |  RC1 --> SEG_(B) (O)
      (O)  SEG_(D) <-- RC3   | 7   8 |  RC2 --> SEG_(C) (O)
                             ---------
*/
#include <16F676.h>
#device adc=10 
#fuses INTRC_IO,NOWDT,PUT,NOPROTECT,BROWNOUT,NOMCLR
#use delay (clock=4000000) // 4MHz clock

#rom  0x3ff={0x3444}

#byte PORTA = 0x05
#byte PORTC = 0x07
#byte TRISA = 0x85
#byte TRISC = 0x87

#define SPORTA PORTA
#define SPORTC PORTC

#define  TICKS_BETWEEN_INTERRUPTS      5000 //5000
#define  INTERRUPT_OVERHEAD            35
#define  TMR1RESET (0xFFFF-(TICKS_BETWEEN_INTERRUPTS-INTERRUPT_OVERHEAD))


//// segment activates on LOW state of pins.
//const char SegCode[11] = {0x40,0x57,0x22,0x06,0x15,0x0C,0x08,0x56,0x00,0x04,0xFF};//for 

coolcircuit vm 
   //                       0    1    2    3    4    5    6    7    8    9

const char SegCode[11] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xFF};//for my vm
   //                       0    1    2    3    4    5    6    7    8    9



/* CA display (common anode) for cool circuit vm
        A
        --
      F|G |B                0=ON
        --
      E|  |C                1=OFF
        --
        D                 
  A  B  C  D  E  F  G             = in order
  c0 c3 c5 c4 c2 c1 A5            =  A5 c5 c4 c3 c2 c1 c0       =  HEX CODE  = DECIMAL
  0  0  0   0  0 0  1             =  1  0  0  0  0  0  0        =  0X40      = 0
  1  0  0   1  1 1  1             =  1  0  1  0  1  1  1        =  0x57      = 1
  0  0  1   0  0 1  0             =  0  1  0  0  0  1  0        =  0x22      = 2
  0  0  0   0  1 1  0             =  0  0  0  0  1  1  0        =  0x06      = 3
  1  0  0   1  1 0  0             =  0  0  1  0  1  0  1        =  0x15      = 4
  0  1  0   0  1 0  0             =  0  0  0  1  1  0  0        =  0x0C      = 5 
  0  1  0   0  0 0  0             =  0  0  0  1  0  0  0        =  0x08      = 6
  0  0  0   1  1 1  1             =  1  0  1  0  1  1  0        =  0x56      = 7   
  0  0  0   0  0 0  0             =  0  0  0  0  0  0  0        =  0x00      = 8
  0  0  0   0  1 0  0             =  0  0  0  0  1  0  0        =  0x04      = 9  
  1  1  1   1  1 1  1             =  1  1  1  1  1  1  1        =  0xFF      = ALL OFF*/



/* CA display (common anode) for  my vm
        A
        --
      F|G |B                0=ON
        --
      E|  |C                1=OFF
        --
        D                 
  A  B  C  D  E  F  G             = in order
  c0 c1 c2 c3 c4 c5 A4           =   A4 c5 c4 c3 c2 c1 c0       =  HEX CODE  = DECIMAL
  0  0  0   0  0 0  1             =  1  0  0  0  0  0  0        =  0X40      = 0

  1  0  0   1  1 1  1             =  1  1  1  1  0  0  1        =  0x79      = 1

  0  0  1   0  0 1  0             =  0  1  0  0  1  0  0        =  0x24      = 2

  0  0  0   0  1 1  0             =  0  1  1  0  0  0  0        =  0x30      = 3

  1  0  0   1  1 0  0             =  0  0  1  1  0  0  1        =  0x19      = 4

  0  1  0   0  1 0  0             =  0  0  1  0  0  1  0        =  0x12      = 5 

  0  1  0   0  0 0  0             =  0  0  0  0  0  1  0        =  0x02      = 6

  0  0  0   1  1 1  1             =  1  1  1  1  0  0  0        =  0x78      = 7 

  0  0  0   0  0 0  0             =  0  0  0  0  0  0  0        =  0x00      = 8

  0  0  0   0  1 0  0             =  0  0  1  0  0  0  0        =  0x10      = 9 
  1  1  1   1  1 1  0             =  1  1  1  1  1  1  1        =  0xFF      = - */

//const char Column[3]   = {0x02,0x01,0x04};  // may be as use \\(RA1= 0x02),(RA0= 0x01),(RA2= 

0x04) cool circuit
const char Column[3]   = {0x06,0x03,0x02};  // may be as use \\(RA1= 0x02),(RA2= 0x04),(RA5= 

0x32) my vm
//static char Segment[3] = {0x7f,0x7f,0x7f};   //Start value for all segmenta, OFF cool circuit
static char Segment[3] = {0x7f,0x7f,0x7f};   //Start value for all segmenta, OFF my vm
static unsigned char ColCount=0x00;

void CPU_SETUP(void);
void Display(void);
void HTO7S(unsigned int32 Num);

byte i;
unsigned int32 result;

#INT_TIMER1
void Timer1(void)
{   
   set_timer1(TMR1RESET);
   Display();   
}   

void main()
{      
   unsigned char i;
   
   CPU_SETUP();
   
   while(true)
   {         
      result=0;
// Read adc result 20 times using this for loop
      for (i=0;i<20;i++)
      {
         set_adc_channel(0); 
         delay_ms(1); // finally, the reslt will contain 20 ADC readings
         result=result+read_adc();
      }
         //result = 0x3fe;
// Take the average of the 20 ADC results readings, and 
// use it to manipulate this to be able to display it on 7 digits                             

        HTO7S(result/20);   
      delay_ms(200);          
   }
   
}

void CPU_SETUP()
{
    
   setup_comparator(NC_NC_NC_NC);   // not use comparator module
// A0 as analog input, refrences are Vss, and Vdd   
   setup_adc_ports( sAN0 | VSS_VDD);
//Divide the internal clock for use ADC on 64 = 1000000/64 
   setup_adc(ADC_CLOCK_DIV_64);
   //TRISA=0b00011000;//All BC557in OFF. LOW is active cool ckt
  // PORTA=0x27; //cool ckt
  // PORTC=0x37;//cool ckt

   TRISA=0b00001001;//All BC557in OFF. LOW is active my vm
   PORTA=0x36; //my vm
   TRISC=0b11111111;//PortC as OUTPUT
    PORTC=0x3F;

   // Use internal clock, prescalar ratio is 1  
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  // Reset timer 1 now
   set_timer1(TMR1RESET);
   enable_interrupts(GLOBAL);
// enable timer 1 interrupt now
   enable_interrupts(INT_TIMER1);   
}

//-------------------------------------
// Display routine
//-------------------------------------
void Display()
{
  // PORTA = 0b00100111;     // off all digits column and Segment G cool ckt
   PORTA = 0b00110110;     // off all digits column and Segment F my vm
   PORTC = 0b00111111;   // off segment a-f   
   delay_cycles(2);
   
    // for loop could be used here, but it will cause a stack overflow !!
   if (ColCount>=3) 
   ColCount=0;

       // Display corresponding digit   
   SPORTC = Segment[ColCount];
   // maniplate digit value in order to put the bits on portc and porta.5
   // XOR it with 7, solve this your self, its easy
   //SPORTA = ((Segment[ColCount] & 0b01000000)>>1) | (Column[ColCount]^0x07); // cool ckt
     SPORTA = ((Segment[ColCount] & 0b01000000)>>1) | (Column[ColCount]^0x07); // my vm
   ColCount++;            
}   

//--------------------------------------
// Convet HEX 2 byte to 7-Segment code
//--------------------------------------
void HTO7S(unsigned int32 Num)
{

unsigned int32 res;

   
Segment[0]=SegCode[30*Num/10230];
// If first digit is 0, turn it off
if (Segment[0]==0x40) 
Segment[0]=0xFF;
// manipulate the result in order to display it on digits, maths trick, but smart one.
// needs another post in deed for me to explain   
res = 30*Num%10230;
Segment[1]=SegCode[10*res/10230];
res=10*res%10230;
Segment[2]=SegCode[10*res/10230];
}
 

This is LED voltmeter with 3 digit and all works fine in format xx,xV up to 30V. Today I need to measure up to 9,99V and how I can change source code to make this? Resolution it need to be better to sense 10mV. PIC is 16f676.

Code is here

Code:
#include <htc.h>
__CONFIG (FOSC_INTRCIO & MCLRE_OFF & BOREN_ON & CP_OFF & CPD_OFF & WDTE_OFF & PWRTE_ON ); 



#define SPORT PORTA
#define DPORT PORTC
const char SegCode[11] = {0x40,0x57,0x22,0x06,0x15,0x0C,0x08,0x56,0x00,0x04,0xFF};
	//                       0    1    2    3    4    5    6    7    8    9
const char Column[3]   = {0x02,0x01,0x04};
static char Segment[3] = {0x7f,0x7f,0x7f};	
static unsigned char ColCount=0x00;
void CPU_SETUP(void);
void Display(void);
void HTO7S(unsigned int Num);
void delayMs(int x);

unsigned int result;
unsigned int readAdc(void);
void interrupt  timer1_isr(void)
{
if(PIR1bits.TMR1IF==1)
{
PIR1bits.TMR1IF = 0;
	TMR1H=0xDF;
Display();
}
}
void main()
{		
	unsigned char i;
	
	CPU_SETUP();
	while(1)
	{			
		result=0;
		for (i=0;i<3;i++)
		{
			
			delayMs(1); 
			result=result+readAdc();
		}
				HTO7S(result/3);								
		
		delayMs(200);		    
	}
	
}

void CPU_SETUP()
{
	CMCON =0x07;		//Turn off comparator module
	ANSEL =0x8;			//AN3 as analog input
	ADCON1 =0x60; 		//clock/64
	ADCON0 = 0x8D;
   	TRISA=0b00011000;
   	PORTA=0x27;
   	TRISC=0b00000000;
   	PORTC=0x37;
   
   T1CON= 0x00;
  	TMR1H=0xDF;
   	INTCONbits.GIE =1;
	INTCONbits.PEIE=1;
	PIE1bits.TMR1IE =1;
 	T1CONbits.TMR1ON=1;
}
unsigned int readAdc()
{
unsigned int res;
ADCON0bits.GO_DONE =1;
while(ADCON0bits.GO_DONE ==1);
res=ADRESL+(ADRESH*0x100);
return(res);
}
//-------------------------------------
// Display routine
//-------------------------------------
void Display()
{
	PORTA = 0b00100111;	  // off all digits column and Segment G
	PORTC = 0b00111111;   // off segment a-f	

	

	if (ColCount>=3) 
	ColCount=0;
    	
	DPORT = Segment[ColCount];
	SPORT = ((Segment[ColCount] & 0b01000000)>>1) | (Column[ColCount]^0x07);
	ColCount++;				
}	

//--------------------------------------
// Convet HEX 2 byte to 7-Segment code
//--------------------------------------
void HTO7S(unsigned int Num)
{
	
	unsigned int res;

	res = ((30*Num)%1023)/100;
	if(res==10)
	{
	Num=Num+1;
	res=0;
	}
	Segment[2]=SegCode[res];

	res = (30*Num)/1023;
	Segment[1]=SegCode[res%10];

	Segment[0]=SegCode[res/10];
	if (Segment[0]==0x40) 
	Segment[0]=0xFF;	
	
}	

void delayMs(int x)
{
int i;
for (x ;x>0;x--)
{
for (i=0;i<=110;i++);
}
}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top