2013-02-05
A kapcsolás megegyezik az ADC kezeléshez használttal. A tényleges mérő készülék esetében analóg bemeneti áramkört kell az uC bemenete elé tenni, ami adott esetben lehet egy feszültség osztó is.
Az asztalon a megszokott kuszaság.
Két újdonság van a programban. Az egyik a fix pontos kiíró rutin az LCD-re. Ezi tesz lehetővé, hogy 10-es számrendszerben, a számunkra megszokott formában (nem hexa :) írja ki a prgram a mért eredményeket. Végre rájöttem, mire is használható az LCD-n a betük kiírási irányának megváltoztatására szolgáló parancs. A konvertálásnál előszőr a legkisebb helyiértékű digit áll elő. Ha hátulról kezdem balra felé kiíratni a digiteket, akkor nem kell hozzá külön buffer. A függvénybe tettem kezdő nulla elnyomást is. A másik az ADC megszakítás vektorban található számoló képlet. A program elején definiálhatjuk a számításhoz használt értékeket. A FELBONTAS az AD által legnagyobb mérhető érték. Az OSZTAS a legnagyobb megjelenítendő érték (1000, 2000 ....). A TIZEDESPONT pedig nyiván a tizedesjegyek száma. A képletben azért használtam long értékeket, mert így akkor is jó lehet, ha 10, 16 vagy több bit-es AD-t használunk.
/*******************************************************************************
* Author - Kiraly Tibor
* http://www.tkiraaly.hu
* Date - 2013.02.04.
* Chip - Atmel ATmega8 & HD44780
* Compiler - avr-gcc (WinAVR)
*
* ATmega8 feszultseg mero
*
********************************************************************************
* LCD bekotese:
*
* 14 LCD D7 - AVR PD7 - 13
* 13 LCD D6 - AVR PD6 - 12
* 12 LCD D5 - AVR PD5 - 11
* 11 LCD D4 - AVR PD4 - 6
* 10 LCD D3
* 9 LCD D2
* 8 LCD D1
* 7 LCD D0
* 6 LCD E - AVR PC2 - 25
* 5 LCD RW - GND
* 4 LCD RS - AVR PC3 - 26
* 3 LCD KONTR - 10 kOhm trim.
* 2 LCD VDD - +5V
* 1 LCD VSS - GND
*
*
* Analog resz:
*
* AVR AVCC - 20 - 100nF - GND / 51R - VCC
* AVR AREF - 21 - 100nF - GND
* AVR ADC0 - 23 - 100nF - GND / 1K poti VCC/GND
*
*******************************************************************************/
#define F_CPU 4000000 // orajel (MHz)
#define OSZTAS 1000UL
#define TIZEDESPONT 2
#define FELBONTAS 255UL
#include "tkiraaly_atmega8.h"
#include <util/delay.h>
#include <avr/pgmspace.h>
#define LED 0
#define LED_ENABLE BS( DDRB, LED)
#define LED_BE BC( PORTB, LED)
#define LED_KI BS( PORTB, LED)
#define LCD_E 2
#define LCD_E_ENABLE BS( DDRC, LCD_E)
#define LCD_E_0 BC( PORTC, LCD_E)
#define LCD_E_1 BS( PORTC, LCD_E)
#define LCD_RS 3
#define LCD_RS_ENABLE BS( DDRC, LCD_RS)
#define LCD_RS_UTASITAS BC( PORTC, LCD_RS)
#define LCD_RS_ADAT BS( PORTC, LCD_RS)
#define LCD_PORT PORTD // felso 4 bit+ E, RS
#define LCD_PORT_ENABLE DDRD= 0B11110000
void lcd_init4( void); // LCD inicializalasa 4 bitre
void lcd_putc( UC); // betu kiirasa
void lcd_putcmd( UC); // parancskod kiadasa
void lcd_yx( UC, UC); // kurzor pozicioja 0..3/0..15
void lcd_cls( void); // kepernyo torles
void lcd_puts( const char *); // string kiirasa
void lcd_fixdp( int, UC, UC); // fix pontos kiiras LCD-re
ISR( ADC_vect) // IT, ha AD meres lefutott
{
lcd_yx( 1, 10);
lcd_fixdp( (int)( (unsigned long)ADCH * OSZTAS/ FELBONTAS), 4, 1);
}
int main( void)
{
lcd_init4();
lcd_cls();
lcd_yx( 0, 1);
lcd_puts( PSTR( "KT - V meter"));
lcd_yx( 1, 2);
lcd_puts( PSTR( "Ube= V"));
ADMUX= VREF_INT_2_56V+ ADC_8BIT+ IN_ADC0;
ADCSRA= ADC_ENABLE+ ADC_IT_ENABLE+ ADC_CP64;
LED_ENABLE;
LED_BE;
IT_ENABLE;
for(;;)
{
START_ADC; // meres 0,5 sec-enkent
_delay_ms( 200);
}
return 0;
}
void lcd_init4( void) // LCD inicializalasa 4 bitre
{
LCD_PORT_ENABLE;
LCD_E_ENABLE;
LCD_RS_ENABLE;
_delay_ms( 15);
LCD_RS_UTASITAS;
LCD_PORT= 0B00100000; // 4 bit interface
LCD_E_1;
LCD_E_0;
_delay_ms( 5);
LCD_E_1;
LCD_E_0;
_delay_us( 120);
lcd_putc( 0B00101000); // 4 bit interface, 2 sor, 5x8 pontos betu
lcd_putc( 0B00101000); // 2x kell kiadni, vagy LCD D3-t VDD-re kell kotni
lcd_putc( 0B00001100); // kijelzes be, cursor ki
lcd_putc( 0B00000110); // kiiras jobbra
LCD_RS_ADAT;
}
void lcd_putcmd( UC cmd) // parancskod kiadasa
{
LCD_RS_UTASITAS;
lcd_putc( cmd);
LCD_RS_ADAT;
}
void lcd_putc( UC c) // egy betu kiiras
{
LCD_E_1; // felso 4 bit
LCD_PORT= ( LCD_PORT & 0x0F) | ( 0xF0 & c);
LCD_E_0;
LCD_E_1; // also 4 bit
LCD_PORT= ( LCD_PORT & 0x0F) | ( 0xF0 & c << 4);
LCD_E_0;
_delay_us( 37); // var 37 usec
}
void lcd_yx( UC sor, UC betu) // kurzor pozicionalasa 0..3/0..15
{
UC cim= 0x80; // parancs kodja
if (sor & 0B00000001) cim+= 64; // 1. es 3. sor
if (sor & 0B00000010) cim+= 20; // 2. es 3. sor
cim+= betu & 0x0F;
lcd_putcmd( cim);
}
void lcd_cls( void) // kepernyo torles
{
lcd_putcmd( 0x01);
_delay_ms( 2);
}
void lcd_puts( const char *s) // string kiiras
{
register unsigned char c;
while ( ( c= pgm_read_byte( s++))) lcd_putc( c);
}
void lcd_fixdp( // fix pontos kiiras LCD-re
int n, // ertek
UC digit, // szamjegyek szama
UC dp) // tizedespont helye
{
UC i; // szamlalo
UC c; // kiirando karakter
i= digit;
if( dp) // ha van tizedes pont
{
i++; // +1 karakter
dp= i- dp; // tizedespont helye
}
lcd_putcmd( 0B00000100); // LCD balra ir
for( ; i; i--)
{
if( i == dp)
{
c= '.';
}
else
{
c= '0'+ n% 10;
if( ( n == 0) && ( ( i+ 1) < dp)) c= ' '; // elejen 0 elnyomas
n/= 10;
}
lcd_putc( c);
}
lcd_putcmd( 0B00000110); // LCD jobbra ir
}
Itt a vége, fuss el véle, legytek az én vendégeim, innen letölthetitek a hozzávalókat összecsomagolva.