Practical Application of STM32 (I) - 1602 Bluetooth Clock 1 LCD Display Test

Keywords: C Programming

Preface

After studying for so long from 51 to STM32F4, I finally got a clue. Now I have learned the basic usage of GPIO, interrupt, timer and watchdog, so I want to try to see if I can do something, that is, to review the knowledge I have learned recently. Just last semester, MCU curriculum design has done a clock with Bluetooth, button calibration and temperature display, so I want to see if I can transplant the program to STM32? After three days of modification and debugging, we finally succeeded!

I can refer to my previous blog post about the clock implemented by 51 single chip computer. There are also video links for demonstration.

Course Design of Single Chip Microcomputer --"Electronic Clock Based on AT89S52 and DS1302 Clock Chip (Bluetooth Calibration)"

Because the accuracy of STM32 internal timer is still very high (one hour slower than one second), so there is no use of DS1302 clock chip (the key is not in hand). The display is somewhat different from the curriculum design. There is no additional date and week display, on the time, alarm clock and temperature display.  

Today, let's learn about the display of 1602 LCD. How to use STM32 to control LCD 1602 to display characters, strings or numbers?

Introduction of 1602 Liquid Crystal

Industrial character LCD can display 16x02 or 32 characters at the same time. 1602 liquid crystal is also called 1602 character liquid crystal. It is a dot matrix liquid crystal module used to display letters, numbers, symbols and so on. It consists of several 5X7 or 5X11 dot-matrix character bits. Each dot-matrix character bit can display a character. There is a dot-space interval between each bit, and there is a space between each line. It plays the role of CHARACTER-SPACE and line-space. Because of this, it can not display graphics well (with custom CGRAM, display). The effect is not good either. Most character liquid crystals on the market are based on HD44780 LCD chip. The control principle is the same. Therefore, the control program written on HD44780 can be easily applied to most character liquid crystals on the market. 1602 LCD refers to the content of the display is 16X2, that is, it can display two lines, each line of 16 characters LCD module (display characters and numbers).

Because 1602 LCD is powered by 5V, the pin high level is 5V. Unlike 51 single-chip IO output high level 5v, STM32 high level only 3.3v, low level 0v, found 1602 data manual, which did not explain the high level voltage range, in the end can drive it? I also looked up the data manual of the 1602 driver HD44780, which has a voltage characteristic, as shown below.

Visible with STM32 3.3v level drive display is completely no problem, I am relieved to see that, after many modifications, the code finally succeeded in showing, so we still need to look at the data manual.

Hardware Circuit Connection

 

 

Programming

1. The macro definition of control line can be operated by bit band operation, and then RS=1 like 51 can be operated. Is it very familiar? The eight ports of the data line are also defined as an LCD_DB.

#define LCD_RS PAout(1)
#define LCD_RW PAout(4)
#define LCD_EN PAout(6)
#define LCD_DB GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15

2. The GPIO configuration connected with LCD, which configures the data line port to OD output mode, can be used as bidirectional IO. When checking whether the LCD is busy, it needs to read the state of D7 bits.

void LCD_GPIO_Config(void)
{
    GPIO_InitTypeDef  IO_Init;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE,ENABLE);
    
    /*Control line initialization: */
    IO_Init.GPIO_Mode=GPIO_Mode_OUT;        //output
    IO_Init.GPIO_OType=GPIO_OType_PP;        //push-pull mode
    IO_Init.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_6; 
    IO_Init.GPIO_PuPd=GPIO_PuPd_UP;            //
    IO_Init.GPIO_Speed=GPIO_Speed_2MHz;        //GPIO_Speed_2MHz
    GPIO_Init(GPIOA,&IO_Init);
    
    /*Data line initialization*/
    IO_Init.GPIO_Mode=GPIO_Mode_OUT;
    IO_Init.GPIO_OType=GPIO_OType_OD;        //Leakage output can be bidirectional
    IO_Init.GPIO_Pin=LCD_DB;
    IO_Init.GPIO_PuPd=GPIO_PuPd_UP;            //Pull up
    IO_Init.GPIO_Speed=GPIO_Speed_2MHz;        
    GPIO_Init(GPIOE,&IO_Init);                        
    /*Testing: High level 3.3v
    LCD_RS=1;
    LCD_RW=1;
    LCD_EN=1;
    GPIO_SetBits(GPIOE,LCD_DB); */
}

 

3. Function of P1=0xff with parameters

void GPIO_OutData(u8 Dat)
{
    u16 tmp;
    tmp = 0;
    tmp =Dat;
    tmp <<= 8;            //Move data left to 8 bits high
    GPIO_Write(GPIOE,tmp);        //Data written to GPIOE 8 bits high
}

4. Check if LCD is busy

void LCD_CheckBusy(void)
{
    u8 sta;
    GPIO_OutData(0xff);
    LCD_RS=0;
    LCD_RW=1;
    do{
        LCD_EN=1;
        delay_ms(5);
        sta = GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_15);
        LCD_EN =0;
    }while(sta & 0x80);
}

 

5. Write a byte of data to the LCD

/* LCD_RS = 1, LCD_RW = 0 */
void LCD_WriteData(u8 Dat)
{

    LCD_CheckBusy(); //Busy is waiting
    LCD_RS=1;
    LCD_RW=0;
    GPIO_OutData(Dat);
    LCD_EN=1;
    delay_ms(1);
    LCD_EN = 0;
    
}

6. Write a byte command to the LCD

/*LCD_RS = 0, LCD_RW = 0*/
void LCD_WriteCmd(u8 Cmd)
{
    LCD_CheckBusy(); //Busy is waiting
    LCD_RS = 0;
    LCD_RW = 0;
    GPIO_OutData(Cmd);    
    LCD_EN = 1;
    delay_ms(1);
    LCD_EN = 0;     
}

 

7.LCD initialization

void LCD_Init(void)
{
    LCD_WriteCmd(0x38);
    LCD_WriteCmd(0x0C);
    LCD_WriteCmd(0x06);    /*Display cursor movement settings*/    delay_ms(1);
    LCD_WriteCmd(0x01);    /*Display Clear Screen*/
}

8.LCD Screen Cleaning

void LCD_ClearScrren(void)
{
    LCD_WriteCmd(0x01);
}

 

9. Write the corresponding data location according to xy coordinates

void LCD_SetCursor(u8 x, u8 y)
{
    u8 addr;
    if (y == 0)
        addr = 0x00 + x;
    else
        addr = 0x40 + x;
    LCD_WriteCmd(addr | 0x80);
}

10. Display a character according to xy coordinates

 
void LCD_DisChar(u8 x,u8 y,u8 ch)
{
    LCD_SetCursor(x,y);        //Character Display Position Setting
    LCD_WriteData(ch);
}

11. Display two digits

void LCD_DisNumber(u8 x,u8 y,u8 Num)
{
    LCD_SetCursor(x,y);
    LCD_WriteData(0x30+Num/10);
    LCD_SetCursor(x+1,y);
    LCD_WriteData(0x30+Num%10);
}

 

12. Display string

void LCD_DisString(u8 x,u8 y,u8 *str)
{
    LCD_SetCursor(x, y);
    while(*str != '\0')
    {
        LCD_WriteData(*str++);
    }
}

Principal function

int main(void)
{
    delay_init(168);
    LED_Init();
    
    LCD_GPIO_Config();
    LCD_Init();
    LCD_ClearScrren();
    while(1)
    {
        delay_ms(500);
        LED1_ON;
        LCD_DisString(0,0,"abcdefghijklmnop");
        delay_ms(500);
        LED1_OFF;
        LCD_DisNumber(0,1,56);
        LCD_DisChar(2,1,'a');
        LCD_DisString(3,1," Hello World!");
    }    
}

 

Actual display effect:

Perfect display, no difference from 51 driver

Summary:

Actual runtime, do not use the detection busy function, 1602 display is normal, the next is to increase the timer display clock. When IO port mode is set, the mode can be set to open-leak mode, which can achieve the purpose of bidirectional IO, i.e. output and read external input. Through bit band operation and macro definition, you can directly operate the IO port to output high and low levels as 51.  

Reference material:

1602 character LCD-Baidu Encyclopedia

HD44780 Device Manual
 
 

Welcome to my previous single-chip learning notes:

STM32 Learning Notes (V) - Universal Timer Counting Delay 
STM32 Learning Notes (IV) - Serial Port Control LED (Interrupt Mode) 
STM32 Learning Notes (3) - Use of External Interruption 
STM32 Learning Notes (2) - Serial Port Control LED 
STM32 Learning Notes (1) - Lighting an LED 
Modular Programming of Single Chip Microcomputer 
Learning Notes of PCF8591 Based on IIC Communication of 51 Single Chip Microcomputer 
AT24C02 Learning Notes Based on IIC Communication of 51 Single Chip Microcomputer 
 
 
 
The above is my personal understanding of the learning process, there are some inaccuracies or inaccuracies, you are welcome to rectify the gods.
 
April 23, 2017 14:24:45
 

Posted by domerdel on Sat, 06 Jul 2019 18:56:24 -0700