Simple digital voltmeter + ADC0809 + program query method to achieve 8-channel data conversion

Publisher:RadiantSoulLatest update time:2024-07-26 Source: cnblogs Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1 Experimental phenomenon (the analog signal acquisition channel is automatically switched every 1s, and the measured voltage value is displayed through the digital tube)

2 Hardware Design

3 Programming

3.1 Main function


#include

#include "DisplaySmg.h"

#include "ADC0809.h"

#include "Timer0.h"


unsigned char adc_result = 0; //Data collected directly after ADC conversion

int adc_result_show = 0; // linear scale change

unsigned char adc_flag = 1; //1s flag signal, used to automatically switch channels

unsigned char channel = 0; //channel number 0~7


void disp_num(void) //Display four-digit decimal number

{

LedBuf[0]= channel; //channel number

LedBuf[1]= adc_result_show/100; //hundreds place

LedBuf[2]= adc_result_show/10%10; //ten digit

LedBuf[3]= adc_result_show%10; //unit digit

}


void main()

{

Timer0_Init(); //Timer/Counter T0 initialization

EA=1; //Interrupt main switch

DotDig1=1; //light up the decimal point of the second digital tube

while(1)

{

if(adc_flag==1) //1S time flag signal

{

adc_flag = 0; // clear to use Timer0 for timing

adc_result = ADC_Conv(channel); //Collect channel input data through ADC

adc_result_show = adc_result*1.0*100*5/255; //Data conversion processing (linear scale conversion)

disp_num(); //Display data

channel++; //Switch to the next channel

if(channel>7) channel = 0;

}

}

}


//1ms timing, dynamically refresh the digital tube, and refresh adc_flag=1 every 1000ms

void Timer0_ISR(void) interrupt 1

{

static unsigned int timer0cnt;

TR0=0; //Turn off the timer

timer0cnt++;

if(timer0cnt>=1000)

{

timer0cnt = 0;

adc_flag = 1;

}

DisplaySmg(); //Refresh the digital tube display function every 1ms

TL0 = 0x66; //Set the initial timing value, timing 1ms

TH0 = 0xFC; //Set the initial timing value, timing 1ms

TR0=1; //Turn on the timer

}


3.2 ADC0809 analog-to-digital conversion function


#ifndef __ADC0809_H__

#define __ADC0809_H__


#include


#define ADC_DATA P3


sbit ADDR_A = P1^0;

sbit ADDR_B = P1^1;

sbit ADDR_C = P1^2;

sbit START = P1^4;

sbit EOC = P1^5;

sbit OE = P1^6;


unsigned char ADC_Conv(unsigned char channel);


#endif


#include "ADC0809.h"


void ADC_SetChannel(channel)

{

switch(channel)

{

case 0: ADDR_A = 0; ADDR_B = 0; ADDR_C = 0; break;

case 1: ADDR_A = 1; ADDR_B = 0; ADDR_C = 0; break;

case 2: ADDR_A = 0; ADDR_B = 1; ADDR_C = 0; break;

case 3: ADDR_A = 1; ADDR_B = 1; ADDR_C = 0; break;

case 4: ADDR_A = 0; ADDR_B = 0; ADDR_C = 1; break;

case 5: ADDR_A = 1; ADDR_B = 0; ADDR_C = 1; break;

case 6: ADDR_A = 0; ADDR_B = 1; ADDR_C = 1; break;

case 7: ADDR_A = 1; ADDR_B = 1; ADDR_C = 1; break;

default: break;

}

}


unsigned char ADC_Conv(unsigned char channel)

{

unsigned char adc_result;

OE = 0; //Data output enable signal, high level is valid

START = 0; //ADC conversion start signal, high level is valid, connected with ALE (address latch enable signal) in the circuit

ADC_SetChannel(channel); //Select channel

START = 1; //Rising edge, clear the register inside the ADC

START = 0; //Generate a certain pulse, Typ = 100ns, the falling edge starts AD conversion

while(EOC==0); //Query mode, ADC conversion end signal, EOC=1, conversion end

// DelayXms(1); //Delay waiting mode

OE = 1; //Data update to output port

adc_result = ADC_DATA; //MCU reads data

OE = 0; //This process ends

return adc_result;

}


3.3 Digital tube dynamic display function


#ifndef __DisplaySmg_H__

#define __DisplaySmg_H__


#include


#define GPIO_SEG P0 //Segment select port

#define GPIO_SEL P2 //bit select port


extern unsigned char LedBuf[]; //external variable declaration

extern unsigned char DotDig0,DotDig1,DotDig2,DotDig3;


void DisplaySmg(void);


#endif


#include "DisplaySmg.h"


unsigned char code LedData[]={ //segment code table, character, serial number of common cathode digital tube

0x3F, //"0", 0

0x06, //"1", 1

0x5B, //"2", 2

0x4F, //"3", 3

0x66, //"4", 4

0x6D, //"5", 5

0x7D, //"6", 6

0x07, //"7", 7

0x7F, //"8", 8

0x6F, //"9", 9

0x77, //"A", 10

0x7C, //"B", 11

0x39, //"C", 12

0x5E, //"D", 13

0x79, //"E", 14

0x71, //"F", 15

0x76, //"H", 16

0x38, //"L", 17

0x37, //"n", 18

0x3E, //"u", 19

0x73, //"P", 20

0x5C, //"o", 21

0x40, //"-", 22

0x00, //turn off 23

};

unsigned char DotDig0=0,DotDig1=0,DotDig2=0,DotDig3=0; //decimal point control bit

unsigned char code LedAddr[]={0xfe,0xfd,0xfb,0xf7}; //digital tube position selection

unsigned char LedBuf[]={22,22,22,22}; //Display buffer area


void DisplaySmg() //Four-digit digital tube, consider the decimal point

{

unsigned char i; // equivalent to "static unsigned char i = 0;"

unsigned char temp;

switch(i)

{

case 0:

{

GPIO_SEG = 0x00; //Eliminate shadow

if(DotDig0==1) //decimal point

{

temp = LedData[LedBuf[0]] | 0x80; //Light up the decimal point

}

else

{

temp = LedData[LedBuf[0]];

}

GPIO_SEG = temp; //segment code

GPIO_SEL = LedAddr[0]; //bit selection

i++;

break;

}

case 1:

GPIO_SEG = 0x00;

if(DotDig1==1) //decimal point

{

temp = LedData[LedBuf[1]] | 0x80;

}

else

{

temp = LedData[LedBuf[1]];

}

GPIO_SEG = temp;

GPIO_SEL = LedAddr[1];

i++;

break;

case 2:

GPIO_SEG = 0x00;

if(DotDig2==1) //decimal point

{

temp = LedData[LedBuf[2]] | 0x80;

}

else

{

temp = LedData[LedBuf[2]];

}

GPIO_SEG = temp;

GPIO_SEL = LedAddr[2];

i++;

break;

case 3:

GPIO_SEG = 0x00;

if(DotDig3==1) //decimal point

{

temp = LedData[LedBuf[3]] | 0x80;

}

else

{

temp = LedData[LedBuf[3]];

}

GPIO_SEG = temp;

GPIO_SEL = LedAddr[3];

i=0;

break;

default:break;

}

}


3.4 Timer T0


#ifndef __Timer0_H__

#define __Timer0_H__


#include


void Timer0_Init(void);


#endif


#include "Timer0.h"


void Timer0_Init(void) //1 millisecond @ 11.0592MHz

{

TMOD &= 0xF0; //Set timer mode

TMOD |= 0x01; //Set timer mode

TL0 = 0x66; //Set the initial value of the timing

TH0 = 0xFC; //Set the initial value of the timing

TF0 = 0; // Clear TF0 flag

TR0 = 1; //Timer 0 starts timing

ET0 = 1; //Timer 0 interrupt switch

//EA = 1; //Interrupt main switch

}


4 References


(1) Single chip microcomputer application - ADC0809 query method to realize AD conversion of 8 analog signals_bilibili_bilibili;


Reference address:Simple digital voltmeter + ADC0809 + program query method to achieve 8-channel data conversion

Previous article:Simple digital voltmeter + ADC0832 + serial SPI mode to achieve 1-way data conversion
Next article:Simple digital voltmeter + ADC0809 + bus mode to achieve one-way data conversion

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号