Опубликовано 2013-04-30 12:35:19 автором Electrod

Digital voltmeter on the microcontroller


Today we will make a digital voltmeter on the microcontroller . Repeating and realizing material in this article , you will learn how to use the microcontroller can measure the voltage and bring it to lcd display . To repeat , we need microcontroller atmega8, lcd 16x2 znakosinteziruyuschy , a pair of resistors , linear voltage regulator lm317, for powering the microcontroller , well, like, everything .

Schematic diagram of the device is shown below skhema voltmeter microcontroller atmega8 To measure the voltage used in embedded microcontroller ADC - analog to digital converter (ADC-Analog-to-Digital Converter). It converts the analog signal into digital. For the ADC voltage reference is needed and stress that we want to digitize ( it should be smaller than the reference ) . In our case we will take the reference voltage to the ADC output power AVCC. For more details about the use of the ADC in avr in the article " Using ADC AVR" . Voltage at the ADC output is fed through a resistive divider R1 R2, because we have a low-voltage input , 0 to 5 volts, and we need to measure the voltage from 0 to 20 volts. To do this, use the divider with a division factor 4 , ie, when the input resistor divider will be supplied 20 volts at the ADC input is 5 volts

Getting the software part of the project. In CodeVision AVR tab, click on Tools-> CodeWizardAVR oscillator to run the code. Then in the tab Chip select Atmega8 microcontroller and set frequency 1 Mhz. Go to the tab ADC ( ADC ) here and put a check next to ADC Enable, select the reference voltage Volt. Ref: here are three options

  • AREF pin - the reference voltage will be taken from the legs aref
  • AVCC pin - the reference voltage will be taken from leg power ADC avcc
  • Int., cap on aref - connect the capacitors on foot aref
We choose the AVCC pin, then select the frequency of the ADC 500 Khz skhema settings atsp All settings are made by ADC . Now we need to connect the lcd. Go to the tab LCD, and select the port that will be connected lcd, I have this PORTD. Now all settings are , you need to generate the code . To do this, click File-> Generate, Save and exit and give the names of the source files

Source project

# include <mega8.h>
# include <stdio.h> // library which contains the function sprintf  
# include <delay.h>  
 
// Alphanumeric LCD Module functions  
# asm  
   . equ __ lcd_port = 0x12; PORTD  
# endasm  
# include <lcd.h>   
 
# define ADC_VREF_TYPE 0x40  
 
// Read the AD conversion result  
unsigned int read_adc (unsigned char adc_input)  
{ 
ADMUX = adc_input | (ADC_VREF_TYPE & 0xff);  
// Delay needed for the stabilization of the ADC input voltage  
delay_us ( 10 );  
// Start the AD conversion  
ADCSRA | = 0x40;  
// Wait for the AD conversion to complete  
while ((ADCSRA & 0x10) == 0 );  
ADCSRA | = 0x10;  
return ADCW;  
}  
 
void main (void)  
{ 
// Declare your local variables here  
   char buffer [ 32] ; // variable that will form the string for output to lcd  
   int adc; // variable to record the values of ADC  
   int v; // variable to store the value of the real tension in millivolts  
// Input / Output Ports initialization  
// Port B initialization  
PORTB = 0x00;  
DDRB = 0x00;  
 
// Port C initialization  
PORTC = 0x00;  
DDRC = 0x00;  
 
// Port D initialization  
PORTD = 0x00;  
DDRD = 0x00;  
 
// Timer / Counter 0 initialization  
// Clock source: System Clock  
// Clock value: Timer 0 Stopped  
TCCR0 = 0x00;  
TCNT0 = 0x00;  
 
// Timer / Counter 1 initialization  
// Clock source: System Clock  
// Clock value: Timer1 Stopped  
// Mode: Normal top = FFFFh  
// OC1A output: Discon.  
// OC1B output: Discon.  
// Noise Canceler: Off  
// Input Capture on Falling Edge  
// Timer1 Overflow Interrupt: Off  
// Input Capture Interrupt: Off  
// Compare A Match Interrupt: Off  
// Compare B Match Interrupt: Off  
TCCR1A = 0x00;  
TCCR1B = 0x00;  
TCNT1H = 0x00;  
TCNT1L = 0x00;  
ICR1H = 0x00;  
ICR1L = 0x00;  
OCR1AH = 0x00;  
OCR1AL = 0x00;  
OCR1BH = 0x00;  
OCR1BL = 0x00;  
 
// Timer / Counter 2 initialization  
// Clock source: System Clock  
// Clock value: Timer2 Stopped  
// Mode: Normal top = FFh  
// OC2 output: Disconnected  
ASSR = 0x00;  
TCCR2 = 0x00;  
TCNT2 = 0x00;  
OCR2 = 0x00;  
 
// External Interrupt (s) initialization  
// INT0: Off  
// INT1: Off  
MCUCR = 0x00;  
 
// Timer (s) / Counter (s) Interrupt (s) initialization  
TIMSK = 0x00;  
 
// Analog Comparator initialization  
// Analog Comparator: Off  
// Analog Comparator Input Capture by Timer / Counter 1 : Off  
ACSR = 0x80;  
SFIOR = 0x00;  
 
// ADC initialization  
// ADC Clock frequency: 500,000 kHz  
// ADC Voltage Reference: AVCC pin  
ADMUX = ADC_VREF_TYPE & 0xff;  
ADCSRA = 0x81;  
 
// LCD module initialization  
lcd_init ( 16 );  
 
while ( 1 )  
      { 
               
           adc = read_adc ( 0); // Read the ADC port 0  
           /* since we ADC 10-bit , the maximum number that the function returns , read_adc ()  
           will be equal to 1024, this number will ekvivalentom input voltage adc0.  
           For example, if read_adc () returned 512 , it means that the input adc0 we gave half the reference voltage  
           To calculate the real power, we need to make a proportion  
            reference voltage - 1024  
            desired voltage - adc  
            We reference voltage = 5.12  
            Seeking voltage = 5.12 * adc/1024, or Seeking voltage = 0,005 * adc  
            For simplicity translate Volts in millivolts by multiplying by 1000  
            Seeking voltage = 0,005 * adc * 1000  
            Everything is good here , but we have not considered koefitsient resistor voltage divider  
            We he is Kdel = (R1 + R2) / R2. Substituting , we obtain  
            Kdel = ( 15, 5 ) / 5 = 4  
            The actual voltage = 0,005 * adc * 1000 * 4  
            */  
            v = 20 * adc;  
           sprintf (buffer, "V =% i mv", v); // string to form the output  
           lcd_clear (); // clear display before displaying  
           lcd_puts (buffer); // display the formation of a string to the display  
           delay_us ( 700) ; // do delay  
      };  
} 

Everything needed for the implementation of the voltmeter is in the archive Voltmeter.rar

Комментарии - (1)

  • rvk говорит:
    Добрый день! С простым вольтметром все понятно. Спасибо большое! Есть двухканальный вольметр или больше, 3, 4 канала. Они все паралленые. Вход один резистивные делители разные. Как в таком случае работать програмно? например: 1 канал - 0.00 9.99 В, 2 - 10.0 - 99.9 В подаем напряжение больше 10 В и что? лапа микроконтроллера, корорая делителем расчитана до 10 В сгорает? А если подать 100 В? Поможет ли в этом случае стабилитрон? Вот таким вопросом я задаюсь! Поможете с этим разобраться? Я задаюсь вопросом:

Добавить комментарий

Для отправки комментария вы должны авторизоваться.