/*
* ADC_lcd.c
*
* Created: 2017-11-13 오후 6:13:47
* Author : GLORY
*/
#include <avr/io.h>
#include <util/delay.h> //_delay_us(), _delay_ms() 함수를 사용하기 위해
//DDRAM 설정 : 0x80+DDRAM address 값
#define LINE1 0x80 //첫번째 라인의 DDRAM address : 0x00 -> 0x80+0x00
#define LINE2 0xC0 //두번째 라인의 DDRAM address : 0x40 -> 0x80+0x40
//PG2=LCD_EN, PG1=RW, PG0=RS 에 연결
#define CMD_WRITE 0xFC //명령어쓰기 E=1, RW=0, RS=0
#define CMD_READ 0xFE //명령어읽기 E=1, RW=1, RS=0
#define DATA_WRITE 0xFD //데이터쓰기 E=1, RW=0, RS=1
#define DATA_READ 0xFF //데이터읽기 E=1, RW=1, RS=1
#define LCD_EN 0x04 //PG2에 연결되어 있기 때문에 bit2를 1로 했다.
//LCD에 명령을 쓰기 위한 함수
void LCD_cmd_write(char cmd)
{
PORTG = CMD_WRITE; //PORTG에 RS, RW, E 가 연결되어 있다.
PORTB = cmd; //PORTB에 데이터버스가 연결되어 있다.
PORTG = PORTG^LCD_EN; //E 신호를 H->L로 하기 위해
_delay_ms(2); //LCD 내부 동작시간
}
void LCD_pos(unsigned char col, unsigned char row) //LCD 포지션 설정
{
LCD_cmd_write(0x80 | (row+col*0x40)); // row=행 / col=열 ,DDRAM주소설정
}
// LCD 초기화, 초기화 강좌의 순서도 참조
void init_LCD(void)
{
_delay_ms(15); //15msec 이상 시간지연
LCD_cmd_write(0x38); //기능셋(데이터버스 8비트, 라인수:2줄)
_delay_ms(5); //4.1msec 이상 시간지연, 생략가능
LCD_cmd_write(0x38); //기능셋, 생략 가능
_delay_us(100); //100usec 이상 시간지연, 생략가능
LCD_cmd_write(0x38); //기능셋, 생략 가능
LCD_cmd_write(0x08); //표시 Off , 생략 가능
LCD_cmd_write(0x01); //화면 지우기
LCD_cmd_write(0x06); //엔트리모드셋
LCD_cmd_write(0x0C); //표시 on
}
//LCD에 데이터를 쓰기 위한 함수
void LCD_data_write(char data)
{
PORTG = DATA_WRITE; //PORTG에 RS, RW, E 가 연결되어 있다.
PORTB = data; //PORTB에 데이터버스가 연결되어 있다.
PORTG = PORTG^LCD_EN; //E 신호를 H->L로 하기 위해
_delay_ms(2); //LCD 내부 동작시간
}
// LCD에 문자열을 표시하기 위한 함수
void LCD_wr_string(char d_line, char *lcd_str)
{
LCD_cmd_write(d_line); //문자열을 표시하기 위한 라인 설정
while(*lcd_str != '\0')
{
LCD_data_write(*lcd_str); //한개의 문자씩 LCD에 표시한다.
lcd_str++;
}
}
void lcdPrintData(char *str) //↑문자열을 한문자씩 출력함수로 전달
{ while(*str !=0)
{
LCD_data_write(*str);
str++;
}
}
void LCD_numerals (uint16_t _temp) {
uint8_t s100,s10;
LCD_pos(1,0); // 커서위치를 첫번째 줄, 첫번째 칸으로 이동
lcdPrintData(" Vres: "); // " Vres: " 출력
s100 = _temp/100; // 100의 자리 추출
if(s100> 0) LCD_data_write(s100+'0'); // 100의 자리 값이 있으면 출력
else lcdPrintData(" "); // 100의 자리 값이 없으면 빈칸 출력
s10 = _temp%100; // 100의 자리를 제외한 나머지 추출
LCD_data_write((s10/10)+'0'); // 10의 자리 추출하여 출력
LCD_data_write('.'); // 소숫점 출력
LCD_data_write((s10%10)+'0'); // 1의 자리 추출하여 출력
LCD_data_write('V'); // 전압 단위 출력
}
// ATmega128의 포트 초기화
void init_PORT(void){
DDRB = 0xFF; //LCD 데이터 버스
PORTB = 0xFF;
DDRG = 0xFF; //LCD 컨트롤 신호(PG2=LCD_EN, PG1=RW, PG0=RS)
PORTG = 0xFF;
}
int main(void)
{
unsigned int AdData = 0; // 10bit ADC값 저장 변수
float v_temp; // 전압값을 계산할 변수
ADMUX = 0x01; // 00000
ADCSRA = 0x87;
init_PORT(); //초기화
init_LCD();
while(1){
ADCSRA |= 0x40; // ADSC AD 개시(Start)
while((ADCSRA & 0x10) == 0x00); // ADIF AD 다 될 때까지 기다림
AdData = ADC; // 전압이 디지털로 변환된 값 읽어오기
v_temp = (float)AdData*33/1023;
LCD_numerals(v_temp);
}
return 1;
}