Sie sind auf Seite 1von 11

Universitatea Tehnica a Moldovei

Facultatea Calculatoare,Informatica si Microelectronica


Catedra Microelectronica si Inginerie Biomedicala

Raport
Lucrare de laborator nr.2
La disciplina: Proiectarea microsistemelor

Tema:Interfete intre microsisteme. Interfete cu utilizatorul

A efectuat:

st.gr.MN-121 Vrabii Daniel

A verificat:

lector asistent : Eugeniu Lazari

Chisinau 2015

Scopul lucrarii : Studiul metodelor de conexiune prin interfetele microcontrolerului.


Problema : Sa se proiecteze un system care ar permite masurarea nivelului de
tensiune prin interfata analogical ( ADC ). Valoarea obtinuta va fi transmisa catre un
afisro alphanumeric ( LCD 16x2) pe baza microcontrolerului HD44780.
Schema bloc:

fig.1. Schema bloc a programei

Fluxul de date:

Fig.2. Ierarhia si fluxul de date in program

Codul sursa:

------------------------------------ ADC Library --------------------------------------------#ifndef ADC_H_


#define ADC_H_
#include <stdint.h>
#include <avr/io.h>
void
ADCInit();
uint16_t ADCGetData(uint8_t ch);
#endif /* ADC_H_ */

#include "adc.h"
void
{

ADCInit()

DDRA = 0x00;
/* ADC init */
ADCSRA = (1 << ADEN) |(1 << ADPS1) | (1 << ADPS0); /* enable ADC cu prescalerul 8 */
ADMUX = (1 << REFS0) | (0 << ADLAR);
/* tensiunea de referinta este AVCC */
}
uint16_t ADCGetData(uint8_t ch)
{
ADMUX = (ADMUX & 0xF8) | (ch & 0b111); /* alegem canalul ADC */
ADCSRA |= (1 << ADSC);
/* incepem conversia */
while (ADCSRA & (1 << ADSC)); /* asteptam finalizarea conversiei */
return ADC;
}

--------------------------------------- Voltage Library ---------------------------------------

#ifndef VOLTAGE_H_
#define VOLTAGE_H_
#include "adc.h"
#include <stdint.h>
#define VMAX 1023 /* 10 bits */
#define VREF 5.0 /* 5 volts */
void VoltageInit(void);
float VoltageGetValue(uint8_t ch);
#endif /* VOLTAGE_H_ */

#include "voltage.h"
void VoltageInit(void) {
}

ADCInit();

float VoltageGetValue(uint8_t ch)


{
uint16_t data = ADCGetData(ch);
return data/((float)VMAX) * VREF;
}

--------------------------------------- LCD Library ------------------------------------------

#ifndef LCD_H_
#define LCD_H_
#include
#include
#include
#include

<stdint.h>
<stdarg.h>
<avr/io.h>
<util/delay.h>

#define LCD_RS 0x1


#define LCD_RW 0x2
#define LCD_EN 0x4
#define LCD_SIZE 16
void
void
void
void
void
void

LCDInit(void);
LCDCursorOn(void);
LCDCursorOff(void);
LCDSetCursor(uint8_t pos);
LCDClear(void);
LCDPrintf(uint8_t pos, const char* msg, ...);

int LCDPutChar(char c);


#endif /* LCD_H_ */

#include "lcd.h"
static uint8_t lcd_cursor;
static void LCDDelay(void)
{
_delay_ms(1);
}
/*
* Write a standart 8 bit value to the LCD
*/
static void LCDWrite8bit(uint8_t value, uint8_t ctrl)
{
PORTC = (value & 0xF0) | ctrl;
PORTC |= LCD_EN;
PORTC &= ~LCD_EN;
LCDDelay();
}
/*
* Write a 8 bit value to the LCD using to write commands
* each transfering 4 bits (High nibble then low nibble)
*
*/
static void LCDWrite4bit(uint8_t value, uint8_t ctrl) // CTRL -> RW/RS
{

LCDWrite8bit(value & 0xF0, ctrl);


LCDWrite8bit((value & 0x0F) << 4, ctrl);
}

void LCDInit(void)
{
DDRC = 0xFF;
LCDWrite8bit(0b00110000, 0x00);
/* Special case "Function Set" */
LCDWrite8bit(0b00110000, 0x00);
/* Special case "Function Set" */
LCDWrite8bit(0b00110000, 0x00);
/* Initial "Function Set to change interface */
LCDWrite8bit(0b00100000, 0x00);
/* At this point display works as 4-bit mode
* and we use two writes (2 nibbles)
*/
/* N = 1 - 2 line mode,
* F = 1 - display on */
LCDWrite4bit(0b00101100, 0x00);
/* Display ON/OFF Control
* D = 0, C = 0, B = 0
* display off, cursor off, blink off
*/
LCDWrite4bit(0b00001000, 0x00);
/* Clear display */
LCDWrite4bit(0b00000001, 0x00);
/* Entry mode set */
LCDWrite4bit(0b00000110, 0x00);
/* Display on/off control */
/* Display on, cursor off, blink off */
LCDWrite4bit(0b00001100, 0x00);
}

/*
* Turn On Cursor

*/
void LCDCursorOn(void)
{
LCDWrite4bit(0b00001110, 0x00);
}
/*
* Turn Off Cursor
*/
void LCDCursorOff(void)
{
LCDWrite4bit(0b00001100, 0x00);
}
void LCDSetCursor(uint8_t pos)
{
LCDWrite4bit(0b10000000 | (pos % LCD_SIZE) | (0x40 * (pos / LCD_SIZE)), 0x00);
}
void LCDClear(void)
{
LCDWrite4bit(0b00000001, 0x00);
lcd_cursor = 0x00;
gotoXY(0, 0);
}
void LCDPrintf(uint8_t pos, const char* msg, ...)
{
char buffer[100];
va_list args;
va_start (args, msg);
vsprintf(buffer, msg, args);
/* Set address */
uint8_t i;
uint8_t line;
i = line = 0;
line = pos / LCD_SIZE;
pos = pos % LCD_SIZE;
while (buffer[i] != '\0')
{
if (buffer[i] == '\n')
{
line++;
pos = 0;
i = i + 1;

continue;

if ((pos % LCD_SIZE == 0) && (pos !=0 ))


{
line++;
pos = 0;
}
/* Select addres in DDRAM */
LCDWrite4bit(0b10000000 | pos | (0x40 * line), 0x00);
/* put char and go to the next char */
pos = pos + 1;
LCDWrite4bit(buffer[i++], LCD_RS);
}
va_end (args);
}

void gotoXY(uint8_t x, uint8_t y)


{
if (x < 0 || y < 0)
return;
if (x > LCD_SIZE || y > 1)
return;
LCDWrite4bit(0b10000000 | x | (0x40 * y), 0x00);
}
int LCDPutChar(char c)
{
/* Set address */
uint8_t i;
if (lcd_cursor > 0x67)
return;
if ((c == '\n' && lcd_cursor <= 0x27) || ((lcd_cursor > 0x27) && (lcd_cursor < 0x40)))
{
lcd_cursor = 0x40;
gotoXY(0, 1);
}

lcd_cursor = lcd_cursor + 1;
LCDWrite4bit(c, LCD_RS);

------------------------------------- Main.c ---------------------------------------------------#include <avr/io.h>


#include "src/voltage.h"
#include "src/lcd.h"
#include <stdio.h>
static FILE mystdout = FDEV_SETUP_STREAM(LCDPutChar, NULL, _FDEV_SETUP_WRITE);
int main(void)
{
VoltageInit();
LCDInit();
stdout = &mystdout;
while(1)
{
float voltage = VoltageGetValue(0);
LCDClear();
printf("Voltage = %3.2f", voltage); // afisam la LCD valoarea curenta a tensiunii
_delay_ms(100);
}

Fig.3,4. Afisarea tensiunii maxime si minime pe LCD


Concluzie :
Acest laborator a oferit posibilitatea capatarii de experienta in lucrul cu afisarea la
un LCD a unei valori colectate la ADC, care pe viitor poate sa fie orice tip de
sensor analog. In aces laborator avem un resistor variabil si valoarea tensiunii de
pe el este afisat la LCD. LCD-ul in cazul dat lucreaza pe 4 biti.

Das könnte Ihnen auch gefallen