2020-06-23 01:54 PM
#include "stm32f10x.h" // Device header
#include "LCD.h"
#include "stdint.h"
#include <stdio.h>
void GPIO_Init(void)
{
// Port B is used for I2C1 communication : SCL1-->PB6 / SDA1-->PB7
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
}
void DelayTimerUs1(int n){
// 1 Mhz ---> 1Us
//ARR = n (n=1 --> 1us) (n=2 --> 2us) ....
// n = 30000 for 30ms delay
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->PSC = 36;
TIM2->ARR = n;
TIM2->CNT = 0;
TIM2->CR1 = TIM_CR1_CEN;
for( int i =0; i<n; i++){
while (!(TIM2->SR & (1<<0))) {}
}
TIM2->SR &=~ (1<<0);
TIM2->CR1 &=~ TIM_CR1_CEN;
}
void I2C1_Init(void)
{
RCC->APB1ENR &=~RCC_APB1ENR_I2C1EN; // Clear I2C1
I2C1->CR1 |= 0x00; // clear CR1 register
I2C1->CR2 |= 0x00; // Clear CR2 register
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
// Set PB6 and PB7 as AF push-pull 10MHz (p161)
GPIOB->CRL &=~ GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_1;
GPIOB->CRL |= GPIO_CRL_MODE6_0 | GPIO_CRL_MODE7_0;
GPIOB->CRL &=~ GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0;
GPIOB->CRL |= GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_1;
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // Enable I2C1
I2C1->CR2 |= 36;
I2C1->CCR |= 180;
I2C1->TRISE |= 37;
I2C1->CR1 |= I2C_CR1_ACK;
// Enable Interrupt (not mandatory)
//I2C1->CR2 |= I2C_CR2_ITBUFEN;
//I2C1->CR2 |= I2C_CR2_ITEVTEN;
// Enbale I2C1 Peripheral
I2C1->CR1 |= I2C_CR1_PE;
}
void I2C_send (uint8_t slave_addr, uint8_t data) // data can be either a command or Data
{
uint8_t temp;
// Send START condition
I2C1->CR1 |= I2C_CR1_START;
// check START condtion send
while (!(I2C1->SR1 & I2C_SR1_SB))
{} // if the SB flag is not 1, do nothing,this means that the START condtion was not sent yet
//Transmit the slave addresse
I2C1->DR = slave_addr; // 0x7E
while (!(I2C1->SR1 & I2C_SR1_ADDR)) {} // wait for ADDR flag in status register, if there was a match for this slave address, clear flag
temp = I2C1->SR2; // clear ADDR flag by reading SR2
I2C1->DR = data;
while(!(I2C1->SR1 & I2C_SR1_TXE)) {}
I2C1->CR1 = I2C_CR1_STOP; // send another start condition if we have another byte
}
void LCD_cmd(char cmd){
uint8_t CMD_H = (cmd & 0xF0); // Isoler Bit poids Fort de la cmd avec le masque 0x0F
uint8_t CMD_Een = (CMD_H |0x0C); // Parametrer bit de config(poid faible), RE=1; E=1 ; RW=0; RS=0
uint8_t CMD_Edis = (CMD_H |0x08); // RE=1; E=0 ; RW=0; RS=0
uint8_t CMD_Shift = ((cmd<<4) & 0xF0);
I2C_send (0x7E, CMD_Een); // envoi de la cmd avec E=1
I2C_send (0x7E, CMD_Edis); // envoi de la cmd avec E=0;
I2C_send (0x7E, CMD_Shift | 0x0C); // envoi cmd decalée (4bits de poids faible) avec E=1
I2C_send (0x7E, CMD_Shift | 0x08); // envoi cmd decalée (4bits de poids faible) avec E=0
}
void LCD_Data( char Data){
uint8_t data_H = (Data & 0xF0); // Isoler Bit poids Fort de la donnée avec le masque 0x0F
uint8_t data_Een = (data_H |0x0D); // Parametrer bit de config(poid faible), RE=1; E=1 ; RW=0; RS=1
uint8_t data_Edis = (data_H |0x09); // RE=1; E=0 ; RW=0; RS=1
uint8_t data_Shift = ((Data<<4) & 0xF0);
I2C_send (0x70, data_Een); // envoi de la cmd avec E=1
I2C_send (0x70, data_Edis); // envoi de la cmd avec E=0;
I2C_send (0x70, data_Shift | 0x0D); // envoi data decalée avec E=1
I2C_send (0x70, data_Shift | 0x09); // envoi data decalée avec E=0
}
void LCD_Init (void)
{
GPIO_Init();
DelayTimerUs1(10000); // 10 ms delay
LCD_cmd(0x30);
DelayTimerUs1(10000);
LCD_cmd(0x30);
DelayTimerUs1(10000);
LCD_cmd(0x30);
DelayTimerUs1(10000);
LCD_cmd (0x28); // 0x20 tells the lcd controller that we want to communicate in 4-bit mode with 2 lines Row
LCD_cmd (0x02); // Home (move cursor to top/left character position)
//LCD_cmd (0x14); // Move cursor one character right
}
Hi there, please if anyone can give me a suggestion about my driver : i want to interface a 4-bit LCD HD44780 with I2C interface PCFpcf8574at, i have checked my code many times but it doesn't work : i'm frustrated, please if you have any suggestion