/*
* char_lcd.c
*
* Created: 2019-01-21 오후 4:25:21
* Author : admin
*/
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include <stdio.h>
#define PORT_DATA PORTD
#define PORT_CONTROL PORTC
#define DDR_DATA DDRD
#define DDR_CONTROL DDRC
#define RS_PIN 0
#define RW_PIN 1
#define E_PIN 2
#define COMMAND_CLEAR_DISPLAY 0x01
#define COMMAND_8_BIT_MODE 0x38
#define COMMAND_4_BIT_MODE 0x28
#define COMMAND_DISPLAY_ON_OFF_BIT 2
#define COMMAND_CURSOR_ON_OFF_BIT 1
#define COMMAND_BLINK_ON_OFF_BIT 0
extern uint8_t MODE;
void LCD_Pulse_enable();
void LCD_write_data(uint8_t data);
void LCD_write_command(uint8_t command);
void LCD_clear();
void LCD_init();
void LCD_write_string(char *string);
void LCD_goto_XY(uint8_t row, uint8_t col);
//////////////////////////////////////////////////////////
void LCD_Pulse_enable(){
PORT_CONTROL |= (1<<E_PIN);
_delay_us(1);
PORT_CONTROL &= ~(1<<E_PIN);
_delay_us(1);
}
void LCD_write_data(uint8_t data){
PORT_CONTROL |= (1<<RS_PIN);
if(MODE == 8){
PORT_DATA = data;
LCD_Pulse_enable();
}
else{
PORT_DATA = data& 0xf0;
LCD_Pulse_enable();
PORT_DATA = (data<<4)&0xf0;
LCD_Pulse_enable();
}
_delay_ms(2);
}
void LCD_write_command(uint8_t command){
PORT_CONTROL&= ~(1<<RS_PIN);
if(MODE ==8){
PORT_DATA =command;
LCD_Pulse_enable();
}
else {
PORT_DATA = command & 0xf0;
LCD_Pulse_enable();
PORT_DATA = (command <<4) & 0xf0;
LCD_Pulse_enable();
}
_delay_ms(2);
}
void LCD_clear(){
LCD_write_command(COMMAND_CLEAR_DISPLAY);
_delay_ms(2);
}
void LCD_init(){
_delay_ms(50);
if(MODE == 8){
DDR_DATA =0xff;
}
else DDR_DATA |= 0xf0;
PORT_DATA = 0x00;
DDR_CONTROL |= (1<<RS_PIN)|(1<<RW_PIN)|(1<<E_PIN);
PORT_CONTROL &= ~(1<<RW_PIN);
if(MODE == 8){
LCD_write_command(COMMAND_8_BIT_MODE);
}
else{
LCD_write_command(0x02);
LCD_write_command(COMMAND_4_BIT_MODE);
}
uint8_t command = 0x08|(1<<COMMAND_DISPLAY_ON_OFF_BIT);
LCD_write_command(command);
LCD_clear();
LCD_write_command(0x06);
}
void LCD_write_string(char *string){
uint8_t i;
for(i=0;string[i];i++){
LCD_write_data(string[i]);
}
}
void LCD_goto_XY(uint8_t row, uint8_t col){
col %=16;
row%=2;
uint8_t address = (0x40*row)+col;
uint8_t command =0x80+address;
LCD_write_command(command);
}
uint8_t MODE = 4;
#define I2C_SCL PD0
#define I2C_SDA PD1
unsigned int sec, min, hour, day, month, year, week;
void uartInit(long buadrate)
{
UCSR0A = 0x00; // ready flag clear
UCSR0B = 0x18; // rx, tx enable
UCSR0C = 0x06; // tx data len : 8bit
UBRR0H = 0;
switch(buadrate){
case 115200:
UBRR0L = 8;
break;
case 57600:
UBRR0L = 16;
break;
case 38400:
UBRR0L = 25;
break;
case 19200:
UBRR0L = 51;
break;
case 14400:
UBRR0L = 68;
break;
case 9600:
UBRR0L = 103;
break;
// Default 19200
default:
UBRR0L = 51;
break;
}
}
void send_data(unsigned char data)
{
while(!(UCSR0A&0x20)); // 송신데이터를 받을 준비가 될때까지 대기
UDR0 = data;
}
void SendLine(char *string)
{
while(*string != '\0')
{
send_data(*string);
string++;
}
}
void init_i2c(){
DDRD |= (1<<I2C_SCL);
DDRD |= (1<<I2C_SDA);
TWBR = 32; // 200khz
}
void i2c_start(){
TWCR = (1<< TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))); // 시작완료 대기
}
void i2c_transmit(uint8_t data){
TWDR = data;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while(!(TWCR&(1<<TWINT))); // 전송완료 대기
}
uint8_t i2c_receive_ACK(){
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while(!(TWCR&(1<<TWINT)));
return TWDR;
}
uint8_t i2c_receive_NACK(){
TWCR = (1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))); // 수신완료 대기
return TWDR;
}
void i2c_stop(){
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
_delay_us(100);
}
uint8_t bcd_to_decimal(uint8_t bcd){
return (bcd>>4) *10 +(bcd&0x0f);
}
uint8_t decimal_to_bcd(uint8_t decimal){
return (((decimal/10)<<4)|(decimal%10));
}
int main(void)
{
LCD_init();
char lcd_buff[100];
init_i2c();
sec = min = hour = day = month = year = week= 0;
char str[1000];
uint8_t address = 0x68;
// 초 분 시 요일 일 월 연
uint8_t date[] = {0,10,12,2,10,10,19};
i2c_start();
i2c_transmit(address <<1);
i2c_transmit(0);
for (int i =0; i<7;i++){
i2c_transmit(decimal_to_bcd(date[i]));
}
i2c_stop();
DDRA = 0xff;
PORTA = 0x00;
while (1)
{
i2c_start();
i2c_transmit(address <<1);
i2c_transmit(0);
i2c_stop();
i2c_start();
i2c_transmit((address<<1)+1);
sec = bcd_to_decimal(i2c_receive_ACK());
min = bcd_to_decimal(i2c_receive_ACK());
hour = bcd_to_decimal(i2c_receive_ACK());
week = bcd_to_decimal(i2c_receive_ACK());
day = bcd_to_decimal(i2c_receive_ACK());
month = bcd_to_decimal(i2c_receive_ACK());
year = bcd_to_decimal(i2c_receive_NACK());
i2c_stop();
LCD_goto_XY(0,0);
sprintf(lcd_buff,"%d/%d/%d",year,month,day);
LCD_write_string(lcd_buff);
LCD_goto_XY(1,0);
sprintf(str,"%d:%d:%d",hour,min,sec);
LCD_write_string(str);
/* LCD example
LCD_goto_XY(1,1);
LCD_write_string("hi");
*/
//sprintf(lcd_buff,"%d/%d/%d",year,month,day);
//sprintf (str, "%d sec, %d min, %d hour, %d week, %d day, %d month, %d year\r\n",sec,min,hour,week,day,month,year);
//sprintf(str,"%d sec\r\n",sec);
}
return 0;
}