Написание C для ЖК-дисплея STM32F0

#c #gpio #lcd #hd44780 #stm32f0

#c #gpio #жк-дисплей #hd44780 #stm32f0

Вопрос:

Я пытаюсь изучить встроенную разработку на C с помощью CoIDE. У меня есть микросхема STM32F0 на выделенной плате. я сделал несколько руководств по светодиодам и т.д. Я застрял на этом коде, который должен записывать несколько простых текстовых строк на ЖК-дисплей. Руководство, которому я следую, находится в eeherald tutorial, я адаптировал код к своему чипу STM32F0. Я думаю, что я близок, но ЖК-дисплей просто остается в режиме инициализации со всеми подсвеченными ячейками. экран никогда не очищается для ввода текста. вот мой код … буду ПРИЗНАТЕЛЕН за любую помощь, которая укажет мне правильное направление!

Я «думаю», что проблема может быть в initGPIO () для кода направления данных, но я не уверен… я пробовал так много разных вещей, но безуспешно.

 enter code here
#include "stm32f0xx_hal.h"

#define EN  12 // EN Enable on PortB chip pin#53
#define RW  11 // RW Read Write on PortB chip pin#52
#define RS  10 // RS Register Select on PortB chip pin#51

void initGPIO(void);
void s_init(void);
void s_data(void);
void s_latch(void);

//------------------------------------------------------------------------------
// Function Name : Init GPIO
// Description : pins ,port clock amp; mode initialization.
//------------------------------------------------------------------------------
void initGPIO()
{
    // Define GPIO Structures
    GPIO_InitTypeDef GPIO_InitStructure;

    // Reset and clock control - Advanced high-performance bus - Enabling GPIO Port B and Port C
    __GPIOB_CLK_ENABLE();
    __GPIOC_CLK_ENABLE();

    // Set Data Direction for Port C
    GPIO_InitStructure.Pin = RS | RW | EN;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(GPIOC, amp;GPIO_InitStructure);

    //Set Data Direction for Port A
    GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(GPIOB, amp;GPIO_InitStructure);
}
//------------------------------------------------------------------------------
// Function Name : s_init
// Description : Send Instruction Function (RS=0 amp; RW=0)
//------------------------------------------------------------------------------

void s_init()
{
    GPIOC->BRR=RS;
    GPIOC->BRR=RW;
}
//------------------------------------------------------------------------------
// Function Name : s_data
// Description : Send Data Select routine(RS=1 amp; RW=0)
//------------------------------------------------------------------------------

void s_data()
{
    GPIOC->BSRR=RS;
    GPIOC->BRR=RW;
}
//------------------------------------------------------------------------------
// Function Name : s_latch
// Description : Latch Data/Instruction on LCD Databus.
//------------------------------------------------------------------------------

void s_latch()
{
    GPIOC->BSRR=EN;
    HAL_Delay(10);
    GPIOC->BRR=EN;
    HAL_Delay(10);
}

/*******************************************************************************
* Function Name : main
* Description : Main program.
*******************************************************************************/
int main(void) //Main function
{

    initGPIO();

    int k=0;
    char a[]="WWW.EEHERALD.COM";
    char b[]="EMBEDDED SYSTEMS";

    GPIOC->BRR=RS; //Initialize RS=0 for selecting instruction Send
    GPIOC->BRR=RW; // Select RW=0 to write Instruction/data on LCD
    GPIOC->BSRR=EN; // EN=1 for unlatch. (used at initial condition)

    HAL_Delay(10);

    s_init(); //Call Instruction Select routine
    GPIOB->ODR=0x0001; // Clear Display, Cursor to Home
    s_latch(); //Latch the above instruction
    GPIOB->ODR=0x0038; // Display Function (2 rows for 8-bit data; small)
    s_latch(); //Latch this above instruction 4 times
    s_latch();
    s_latch();
    s_latch();
    GPIOB->ODR=0x000E; // Display and Cursor on, Cursor Blink off
    s_latch(); //Latch the above instruction
    GPIOB->ODR=0x0010; // Cursor shift left
    s_latch(); //Latch the above instruction
    GPIOB->ODR=0x0006; // Cursor Increment, Shift off
    s_data(); //Change the input type to Data.(before it was instruction input)
    s_latch(); //Latch the above instruction

    for(k=0;a[k];k  )
    {
        GPIOB->ODR=a[k]; //It will send a[0]='P' as = '0x0050' on Port B.
        s_latch(); //Latch the above instruction only once. Or it will clone each character twice if you latch twice.
    }
    GPIOC->BRR=RS; //Initialize RS=0 for selecting instruction Send
    GPIOC->BRR=RW; // Select RW=0 to write Instruction/data on LCD
    GPIOC->BSRR=EN; // EN=1 for unlatch. (used at initial condition)


    GPIOB->ODR=0x00C0; // Move cursor to beginning of second row
    s_latch(); //Latch the above instruction
    s_data(); //Change the input type to Data.(before it was instruction input)
    for(k=0;b[k];k  )
    {
        GPIOB->ODR=b[k]; //It will send b[0]='E' as = '0x0044' on Port B.
        s_latch();//Latch the above instruction only once. Or it will clone each character twice if you latch twice.
    }
    s_init();
}
  

Комментарии:

1. одна проблема, которую я вижу, в том, что инициализация не так хороша, например, команда 0x0001 для очистки дисплея занимает много времени, и вам не нужно ждать.

2. если вы не будете ждать, то другие команды во время обработки будут проигнорированы, посмотрите таблицу данных: sos.sk/productdata/63/27/5/63275/bc1602Aver01.pdf на странице 25 для правильной инициализации с правильными задержками.