728x90
제목 :
날짜 : 21.04.07
주제 : I2C 연습
목표 : I2C를 통해 LCD 글자 출력
<활동>
- main.c -
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "uart0.h"
#include "I2C.h"
#include "i2c_lcd.h"
FILE OUTPUT = FDEV_SETUP_STREAM(UART0_Transmit, NULL, _FDEV_SETUP_WRITE);
int main(void)
{
LCDInit();
UART0_Init();
stdout =&OUTPUT;
LCDWriteStringXY(0,0,"hello world");
int c=0;
char stbuf[30];
while (1)
{
sprintf(stbuf,"count :%d",c++);
LCDWriteStringXY(1,0,stbuf);
_delay_ms(50);
}
}
- i2c_lcd.c -
#include "i2c_lcd.h"
#define LCD_DEV_ADDR_W (0x27<<1)
uint8_t I2C_LCD_Data;
void LCDCommandMode(void)
{
//1. cmd rs값을 0으로 출력
I2C_LCD_Data &= ~(1<<LCD_RS);
}
void LCDDataMode(void)
{
//cmd rs값을 1으로 출력
I2C_LCD_Data |= (1<<LCD_RS);
}
void LCDWriteMode(void)
{
//2. r/w pin값을 0(write)로 출력
I2C_LCD_Data &= ~(1<<LCD_RW);
}
void LCDSendData(uint8_t data) //8bit mode data
{
//3. 입력된 data 출력
LCD_DATA_PORT = data;
}
void LCD_SendData4bit(uint8_t data)
{
I2C_LCD_Data = (I2C_LCD_Data & 0x0f) | (data & 0xf0);
LCDEnable();
I2C_LCD_Data = (I2C_LCD_Data & 0x0f) | ((data & 0x0f)<<4);
LCDEnable();
}
void LCD_BackLightOn(void)
{
I2C_LCD_Data |= (1<<LCD_BACKLIGT);
I2C_TxByte(LCD_DEV_ADDR_W, I2C_LCD_Data);
}
void LCD_BackLightOff(void)
{
I2C_LCD_Data &= ~(1<<LCD_BACKLIGT);
I2C_TxByte(LCD_DEV_ADDR_W, I2C_LCD_Data);
}
void LCDEnable(void)
{
//4. enable pin을 0>1>0 으로 실행
//LCD_ENABLE_PORT &= ~(1<<LCD_ENABLE);
//LCD_ENABLE_PORT |= (1<<LCD_ENABLE);
//LCD_ENABLE_PORT &= ~(1<<LCD_ENABLE);
I2C_LCD_Data &= ~(1<<LCD_ENABLE);
I2C_TxByte(LCD_DEV_ADDR_W, I2C_LCD_Data);
I2C_LCD_Data |= (1<<LCD_ENABLE);
I2C_TxByte(LCD_DEV_ADDR_W, I2C_LCD_Data);
I2C_LCD_Data &= ~(1<<LCD_ENABLE);
I2C_TxByte(LCD_DEV_ADDR_W, I2C_LCD_Data);
//딜레이를 줘야 깨지지 않고 나옴
_delay_us(1800);
}
void LCDWriteCommand(uint8_t cmdData)
{
LCDCommandMode();
LCDWriteMode();
LCD_SendData4bit(cmdData);
//LCDEnable();
}
void LCDWriteData(uint8_t charData)
{
LCDDataMode();
LCDWriteMode();
LCD_SendData4bit(charData);
//LCDEnable();
}
void LCDInit(void)
{
//LCD_DATA_DDR =0xff;
//LCD_RS_DDR |= (1<<LCD_RS);
//LCD_RW_DDR |= (1<<LCD_RW);
//LCD_ENABLE_DDR |= (1<<LCD_ENABLE);
I2C_Init();
_delay_ms(20);
LCDWriteCommand(0x03);
_delay_ms(5);
LCDWriteCommand(0x03);
_delay_ms(1);
LCDWriteCommand(0x03);
LCDWriteCommand(0x02);
LCDWriteCommand(COMMAND_FUCTION_SET_4BIT); //4bit function set
LCDWriteCommand(COMMAND_DISPLAY_OFF); //display off
LCDWriteCommand(COMMAND_DISPLAY_CLEAR); //display clear
LCDWriteCommand(COMMAND_ENTRY_MODE_SET); //entry mode set 0b00000110
LCDWriteCommand(COMMAND_DISPLAY_ON);
LCD_BackLightOn();
}
void LCDWriteString(char *string)
{
for(uint8_t i=0;string[i];i++)
{
LCDWriteData(string[i]);
}
}
void LCDGoToXY(uint8_t row, uint8_t col)
{
col %= 16;
row %= 2;
uint8_t address = (0x40 * row) + col;
uint8_t command =0x80 + address;
LCDWriteCommand(command);
}
void LCDWriteStringXY(uint8_t row, uint8_t col, char *string)
{
LCDGoToXY(row, col);
LCDWriteString(string);
}
- I2C.c -
#include "I2C.h"
void I2C_Init(void)
{
I2C_DDR |= (1<<I2C_SCL) | (1<<I2C_SDA); //포트 출력으로 설정
TWBR = 72; //100khz 의미 (다른 곳에서 계산되있는 통신 속도를 사용)
//TWBR = 32; //200khz 의미
//TWBR = 12; //400khz 의미
}
void I2C_Start(void)
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //Send START condition
while (!(TWCR & (1<<TWINT))) ; //Wait for TWINT flag set.
//This indicates that the START condition has been transmitted
}
void I2C_TxData(uint8_t data)
{
TWDR = data; //write bit = 0, SLA_W; SLA_W = slave dev 주소 +write, 1byte:dev주소+r/w //lcd 주소
TWCR = (1<<TWINT) | (1<<TWEN); //Load SLA_W into TWDR Register.
//Clear TWINT bit in TWCR to start transmission of address
while (!(TWCR & (1<<TWINT))) ; //Wait for TWINT flag set. This indicates that the
//SLA+W has been transmitted, and ACK/NACK has been received.
}
void I2C_Stop(void)
{
TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO); //Transmit STOP condition
}
void I2C_TxByte(uint8_t devAddr_RW, uint8_t data)
{
/* I2C inteface를 이용한 1byte 전송 코드 */
//1. start bit 전송
I2C_Start();
//2. data 전송 (dev address + r/w)
I2C_TxData(devAddr_RW); //함수 사용, 반복되는 코드가 발생할시 함수 이용
//3. 실제 데이터 전송
I2C_TxData(data);
//4. stop bit 전송, 통신 종료
I2C_Stop();
}
<파일>
'AVR' 카테고리의 다른 글
[AVR] UART 실험 (0) | 2021.04.08 |
---|