|
| |||||||
|
Опубликовано 2013-05-02 16:24:12 автором MRS Цифровой амперметр на микроконтроллереВ предыдущей статье цифровой вольтметр на микроконтроллере мы научились измерять напряжение с помощью АЦП, и у вас, наверное, ещё тогда возник вопрос: а как же измерить ток? Об этом мы и поговорим в этом посте. С напряжением все просто: пропустил через делитель напряжения (если нужно) и подал на АЦП, а как же на счет тока? Для измерения тока можно пойти двумя путями:
Сигнал от датчика усиливается усилителем DA1.1, буферизируется повторителем DA1.2 (может отсутствовать). Резистором R2 можно регулировать коэффициент усиления ОУ (чувствительность датчика) рассчитывается по формуле Uout=Uinp*(1+R1/R2).Общая схема цифрового амперметра
#include <mega8.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <stdio.h> //библиотека, в которой лежит функция sprintf
#define ADC_VREF_TYPE 0x00
// 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)
{
char buffer[32]; //переменная, в которой будет формироваться строка для вывода на lcd
int adc; //переменная для хранения значений АЦП
int u; //переменная для хранения напряжения
float a; //переменная для хранения тока
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: AREF pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x81;
// LCD module initialization
lcd_init(16);
while (1)
{
adc=read_adc(0); // читаем ацп с порта 0
/*Ток, протекающий через шунт, вычисляется по закону Ома: I=U/R
R=0,1 ом, a U (падение напряжения на шунте) мы будем измерять.
Так как АЦП у нас 10-битный, то максимальное число, которое вернет функция read_adc(),
будет равно 1024, это число будет эквивалентом напряжения на входе adc0.
Например, если read_adc() вернул 512, то это значит, что на вход adc0 мы подали половину опорного напряжения
Чтобы вычислить реальное напряжение, нам нужно составить пропорцию:
опорное напряжение - 1024
искомое напряжение - adc
У нас опорное напряжение=5.12
Искомое напряжение = 5.12*adc/1024 или Искомое напряжение = 0,005*adc
для простоты переведём вольты в миливольты, домножив на 1000
Искомое напряжение = 0,005*adc*1000
Здесь всё хорошо, но мы не учли коэффициент усиления ОУ
рассчитывается по формуле: Кус=1+R1/R2. Подставив, получим
Кус=(1+4)=5
Реальное напряжение = 0,005*adc*1000/5 получаем просто adc
*/
u=adc;
sprintf(buffer,"I = %d,%02d A",
(int)(u/100),/*получаем ток по закону ома I=U/R*/
(int)(u%100) //Дробная часть тока
); //формируем строку для вывода
lcd_clear(); //чистим дисплей перед выводом
lcd_puts(buffer); //выводим сформированую строку на дисплей
delay_ms(100); //делаем задержку
};
}
Проект в протеус и исходный код в архиве Ampermeter_P В следующей статье опишу, как сделать простой ватметр на мк Комментарии - (5)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||