#include "stm32c0xx.h"
#define LCD_ADDR 0x27
// LCD control bits
#define RS 0x01
#define EN 0x04
#define BL 0x08
void delay(volatile uint32_t t)
{
while(t--);
}
//////////////////////////////////////////////////////
// I2C INIT
//////////////////////////////////////////////////////
void I2C1_Init(void)
{
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
RCC->APBENR1 |= RCC_APBENR1_I2C1EN;
// PA9=SCL PA10=SDA
GPIOA->MODER &= ~((3<<(9*2)) | (3<<(10*2)));
GPIOA->MODER |= ((2<<(9*2)) | (2<<(10*2)));
GPIOA->OTYPER |= (1<<9) | (1<<10);
GPIOA->AFR[1] &= ~((0xF<<4) | (0xF<<8));
GPIOA->AFR[1] |= ((6<<4) | (6<<8));
// 100kHz تقریبی
I2C1->TIMINGR = 0x00303D5B;
I2C1->CR1 |= I2C_CR1_PE;
}
//////////////////////////////////////////////////////
// I2C WRITE
//////////////////////////////////////////////////////
void I2C_Write(uint8_t data)
{
while(I2C1->ISR & I2C_ISR_BUSY);
I2C1->CR2 = 0;
I2C1->CR2 |= (LCD_ADDR << 1);
I2C1->CR2 |= (1 << 16); // NBYTES =1
I2C1->CR2 |= I2C_CR2_AUTOEND;
I2C1->CR2 |= I2C_CR2_START;
while(!(I2C1->ISR & I2C_ISR_TXIS));
I2C1->TXDR = data;
while(!(I2C1->ISR & I2C_ISR_STOPF));
I2C1->ICR |= I2C_ICR_STOPCF;
}
//////////////////////////////////////////////////////
// LCD LOW LEVEL
//////////////////////////////////////////////////////
void LCD_Pulse(uint8_t data)
{
I2C_Write(data | EN | BL);
delay(3000);
I2C_Write((data & ~EN) | BL);
delay(3000);
}
void LCD_Send4(uint8_t nibble)
{
LCD_Pulse(nibble);
}
//////////////////////////////////////////////////////
// LCD COMMAND
//////////////////////////////////////////////////////
void LCD_Command(uint8_t cmd)
{
LCD_Send4(cmd & 0xF0);
LCD_Send4((cmd << 4) & 0xF0);
}
//////////////////////////////////////////////////////
// LCD DATA
//////////////////////////////////////////////////////
void LCD_Data(uint8_t data)
{
LCD_Send4((data & 0xF0) | RS);
LCD_Send4(((data << 4) & 0xF0) | RS);
}
//////////////////////////////////////////////////////
// LCD INIT
//////////////////////////////////////////////////////
void LCD_Init(void)
{
delay(50000);
LCD_Send4(0x30);
delay(30000);
LCD_Send4(0x30);
delay(10000);
LCD_Send4(0x30);
delay(10000);
LCD_Send4(0x20); // 4-bit mode
delay(10000);
LCD_Command(0x28); // 2 line
LCD_Command(0x0C); // display on
LCD_Command(0x06); // entry mode
LCD_Command(0x01); // clear
delay(20000);
}
//////////////////////////////////////////////////////
// CURSOR
//////////////////////////////////////////////////////
void LCD_SetCursor(uint8_t row, uint8_t col)
{
uint8_t addr;
if(row == 0)
addr = 0x80 + col;
else
addr = 0xC0 + col;
LCD_Command(addr);
}
//////////////////////////////////////////////////////
// PRINT STRING
//////////////////////////////////////////////////////
void LCD_Print(char *str)
{
while(*str)
{
LCD_Data(*str++);
}
}
//////////////////////////////////////////////////////
// MAIN
//////////////////////////////////////////////////////
int main(void)
{
I2C1_Init();
LCD_Init();
LCD_SetCursor(0,0);
LCD_Print("Hello YASIN/AMIN!!");
LCD_SetCursor(1,0);
LCD_Print("HOW ARE YOU");
while(1)
{
}
}