2024.9.12 수업날
< dht11_lcd(myip) >
이번에는 온습도센서(dht11)에서 측정한 값을 LCD에 출력하는 IP를 만들어본다.
vivado 진행 순서
새로운 Block Diagram 생성 후,
기본적인 Diagram까지 만들고 create and package new ip로 edit_myip를 진행한다.
Add Sources
slave 모듈 수정해야하는 부분
top 모듈 수정해야하는 부분
체크표시 확인 후 Re-Package IP 클릭
Block Diagram에 myip_dht11 추가
Generate Block Design에서 Global 선택 후 Generate 하기
Block Design에서 Sources의 .xdc에서 아래와 같이 수정
Mblaze_iic -> helloworld.c 소스코드(dht11_lcd 기능)
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xiic.h"
#define IIC_ID XPAR_IIC_0_DEVICE_ID
#define DHT11_BASEADDR XPAR_MYIP_DHT11_0_S00_AXI_BASEADDR
#define LCD_RS 0
#define LCD_RW 1
#define LCD_E 2
#define LCD_BACKLIGHT 3
#define LCD_DEV_ADDR (0x27<<1) // address 0x27 beginning from bit 1, bit 0 is R/W_bar
#define COMMAND_DISPLAY_CLEAR 0x01
#define COMMAND_DISPLAY_ON 0x0C
#define COMMAND_DISPLAY_OFF 0x08
#define COMMAND_ENTRY_MODE 0x06
#define COMMAND_4BIT_MODE 0x28
static u8 I2C_LCD_Data;
XIic iic_instance;
void LCD_Data_4bit (u8 data);
void LCD_EnablePin();
void LCD_WriteCommand(uint8_t commandData);
void LCD_WriteData(uint8_t charData);
void LCD_Init();
void LCD_BackLightOn();
void LCD_GotoXY(uint8_t row, uint8_t col);
void LCD_WriteString(char *string);
int main()
{
init_platform();
u8 data_t[4] = {0,}; //0 -> backlight off
u8 tx_data = 0xff;
u8 cnt = 0;
print("Start!\n\r");
volatile unsigned int *dht11_instance = (volatile unsigned int) DHT11_BASEADDR;
XIic_Initialize(&iic_instance, IIC_ID);
// XIic_Send(iic_instance.BaseAddress, 0x27, data_t, 1, XIIC_STOP);
LCD_Init();
LCD_WriteString("Humidity : ??");
LCD_GotoXY(1, 0);
LCD_WriteString("Temperture : ??");
while(1){
// dht11-lcd
MB_Sleep(3000);
LCD_GotoXY(0, 11); // Humidity
LCD_WriteData(dht11_instance[0]/10%10 + '0');
LCD_WriteData(dht11_instance[0]%10 + '0');
LCD_GotoXY(1, 13); // Temperture
LCD_WriteData(dht11_instance[1]/10%10 + '0');
LCD_WriteData(dht11_instance[1]%10 + '0');
xil_printf("humidity : %d temperature : %d\n\r", dht11_instance[0], dht11_instance[1]);
print("Hello World!\n\r");
}
cleanup_platform();
return 0;
}
void LCD_Data_4bit (u8 data)
{
I2C_LCD_Data = (I2C_LCD_Data & 0x0f) | (data & 0xf0); // put upper four bits
LCD_EnablePin();
I2C_LCD_Data = (I2C_LCD_Data & 0x0f) | ((data & 0x0f)<<4); // put lower four bits
LCD_EnablePin();
}
void LCD_EnablePin()
{
I2C_LCD_Data &= ~(1<<LCD_E);
XIic_Send(iic_instance.BaseAddress, 0x27, &I2C_LCD_Data, 1, XIIC_STOP);
I2C_LCD_Data |= (1<<LCD_E);
XIic_Send(iic_instance.BaseAddress, 0x27, &I2C_LCD_Data, 1, XIIC_STOP);
I2C_LCD_Data &= ~(1<<LCD_E);
XIic_Send(iic_instance.BaseAddress, 0x27, &I2C_LCD_Data, 1, XIIC_STOP);
MB_Sleep(2);
}
void LCD_WriteCommand(uint8_t commandData)
{
I2C_LCD_Data &= ~(1<<LCD_RS); // enter instruction code mode
I2C_LCD_Data &= ~(1<<LCD_RW); // enter write mode
LCD_Data_4bit(commandData); // output data
}
void LCD_WriteData(uint8_t charData)
{
I2C_LCD_Data |= (1<<LCD_RS); // enter data mode
I2C_LCD_Data &= ~(1<<LCD_RW); // enter write mode
LCD_Data_4bit(charData); // output data
}
void LCD_Init()
{
// see HD44780 datasheet page 45 for following init commands
MB_Sleep(20);
LCD_WriteCommand(0x03);
MB_Sleep(5);
LCD_WriteCommand(0x03);
MB_Sleep(1);
LCD_WriteCommand(0x03);
LCD_WriteCommand(0x02);
LCD_WriteCommand(COMMAND_4BIT_MODE);
LCD_WriteCommand(COMMAND_DISPLAY_OFF);
LCD_WriteCommand(COMMAND_DISPLAY_CLEAR);
LCD_WriteCommand(COMMAND_ENTRY_MODE);
LCD_WriteCommand(COMMAND_DISPLAY_ON);
LCD_BackLightOn();
}
void LCD_BackLightOn()
{
I2C_LCD_Data |= (1<<LCD_BACKLIGHT);
}
void LCD_GotoXY(uint8_t row, uint8_t col)
{
col %= 16; // column width is within 16
row %= 2; // row length is within 2
uint8_t address = (0x40 * row) + col; // see HD44780 datasheet page 12
uint8_t command = 0x80 + address;
LCD_WriteCommand(command);
}
void LCD_WriteString(char *string)
{
for (uint8_t i=0; string[i]; i++)
{
LCD_WriteData(string[i]);
}
}
dht11_lcd(myip)