|
| |||||||
|
Опубликовано 2013-05-02 16:24:12 автором MRS Цифровий амперметр на мікроконтролеріУ попередній статті цифровий вольтметр на мікроконтролері ми навчилися вимірювати напругу за допомогою АЦП, і у вас , напевно, ще тоді виникло питання : а як же виміряти струм ? Про це ми і поговоримо в цьому пості . З напругою все просто: пропустив через дільник напруги (якщо потрібно ) і подав на АЦП , а як же на рахунок струму? Для вимірювання струму можна піти двома шляхами:
Сигнал від датчика посилюється підсилювачем DA1.1 , буферизується повторювачем DA1.2 ( може бути відсутнім) . Резистором R2 можна регулювати коефіцієнт посилення ОУ (чутливість датчика) розраховується за формулою U out = U inp * ( 1 + R 1 / R 2 ) .
# 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); // робимо затримку
} ;
}
У наступній статті опишу , як зробити простий ватметр на мк Комментарии - (5)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||