Chào các bạn,
Mình đang gặp 1 vấn đề mà không hiểu lỗi ở đâu mà hiển thị LCD không có gì cả.
Mình sử dụng kit Stm32f103RB và kết nối các chân với LCD như sau:
PA2-RS, PA4-RW,PA 6-EN: chân điều khiển
PA8-D4, PA9-D5,PA10-d6,PA11-D7,
Chân 1 LCD-GND
Chân 2 LCD-5V
Chân 15-5V
Chân 16-GND
Các chân còn lại LCD không nối gì cả.
Chuơng trình dựa trên code sẵn có của stm32f103RC. Mình chỉ add thêm file ...mdvl.s
và define lại chân nối LCD như trên.
Nhưng không hiểu sao mình nạp file hex ra thì LCD chỉ sáng đèn mà không hiển thị gì cả.
Đây là các file chuơng trình của mình
Khai báo LCD
hàm định nghĩa các chân
file main.c
Các bạn giúp mình với không hiểu tại sao LCD chỉ sáng đèn nền mà không hiển thị kí tự nào
Mình đang gặp 1 vấn đề mà không hiểu lỗi ở đâu mà hiển thị LCD không có gì cả.
Mình sử dụng kit Stm32f103RB và kết nối các chân với LCD như sau:
PA2-RS, PA4-RW,PA 6-EN: chân điều khiển
PA8-D4, PA9-D5,PA10-d6,PA11-D7,
Chân 1 LCD-GND
Chân 2 LCD-5V
Chân 15-5V
Chân 16-GND
Các chân còn lại LCD không nối gì cả.
Chuơng trình dựa trên code sẵn có của stm32f103RC. Mình chỉ add thêm file ...mdvl.s
và define lại chân nối LCD như trên.
Nhưng không hiểu sao mình nạp file hex ra thì LCD chỉ sáng đèn mà không hiển thị gì cả.
Đây là các file chuơng trình của mình
Khai báo LCD
Code:
/** ****************************************************************************** * @file lcd.c * @author ARMVN Application Team * @version V1.0.0 * @date 28/02/2010 * @brief This file provides firmware functions to manage LCD on STM32 GEM3M Boards from ARMVietNam. ****************************************************************************** * @copy * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2010 ARMVietNam</center></h2> */ /* ************************************************************************************************************************************* * INCLUDED FILES * ************************************************************************************************************************************* */ #include "lcd.h" #include "main.h" /* define macro for debug-------------------------------------------------------------------*/ #define DEBUG_LCD /* ************************************************************************************************************************************* * PRIVATE DEFINE * ************************************************************************************************************************************* */ /* ************************************************************************************************************************************* * DATA TYPE DEFINE * ************************************************************************************************************************************* */ /* ************************************************************************************************************************************* * PRIVATE VARIABLES * ************************************************************************************************************************************* */ /* ************************************************************************************************************************************* * LOCAL FUNCTIONS * ************************************************************************************************************************************* */ static void delay(u32 nCount); /** * @brief Inserts a delay time with resolution is 1 milisecond. * @param nCount: specifies the delay time length. * @retval None */ static void delay(u32 nCount) { u32 index = 0; /* default system clock is 72MHz */ for(index = (24000 * nCount); index != 0; index--) { } } // ****** Low-level functions ****** // the following functions are the only ones which deal with the CPU // memory or port pins directly. If you decide to use a fundamentally // different hardware interface to your LCD, only these functions need // to be changed, after which all the high-level functions will // work again. void lcd_data_line_write(u8 data) { // Write only the highest 4 bits! SET_LCD_EN_Line() ; // Disable LCD GPIO_Write(LCD_DATA_GPIO_PORT, ( GPIO_ReadOutputData(LCD_DATA_GPIO_PORT) & 0xFFF0 ) |(u16) ((data >> 4)&0x000F)); CLR_LCD_EN_Line() ; // Enable LCD, Create a falling edge Delay(5); SET_LCD_EN_Line() ; // Disable LCD GPIO_Write(LCD_DATA_GPIO_PORT, (GPIO_ReadInputData(LCD_DATA_GPIO_PORT)&0xFFF0) |(u16)(data&0x000F)); CLR_LCD_EN_Line() ; // Enable LCD, create a falling edge Delay(1); } u8 lcd_data_line_read(void) { u8 HNib, LNib; /* set data I/O lines to input */ lcd_data_line_conf(Input); /* set RS to "control" */ CLR_LCD_RS_Line(); /* set R/W to "read" */ SET_LCD_RW_Line(); Delay(1); /* Read only the lowest 8 bits!*/ SET_LCD_EN_Line(); HNib = (u8)(GPIO_ReadInputData(LCD_DATA_GPIO_PORT) & LCD_DATA_GPIO_PINS); CLR_LCD_EN_Line() ; // create a falling edge Delay(1); SET_LCD_EN_Line(); LNib = (u8)(GPIO_ReadInputData(LCD_DATA_GPIO_PORT) & LCD_DATA_GPIO_PINS); CLR_LCD_EN_Line() ; // create a falling edge return (HNib |(LNib >> 4)); } void lcd_data_line_conf(GPIOConfig_Mode_TypeDef IO_mode) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable the LCD Data line Clock */ RCC_APB2PeriphClockCmd(LCD_DATA_GPIO_CLK, ENABLE); /* Configure the LCD Data lines */ GPIO_InitStructure.GPIO_Pin = LCD_DATA_GPIO_PINS; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; if( IO_mode == Input ){ /* Configure LCD D0~D7 lines as Input */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; } else if ( IO_mode == Output) { /* Configure LCD D0~D7 lines in Output Push-Pull mode */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; } GPIO_Init(LCD_DATA_GPIO_PORT, &GPIO_InitStructure); } /** * @brief initializes I/O pins connected to LCD. * @param None * @retval None */ void lcd_Init_HW(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIO clocks for LCD control pins */ RCC_APB2PeriphClockCmd(LCD_RS_GPIO_CLK | LCD_RW_GPIO_CLK | LCD_EN_GPIO_CLK, ENABLE); /* initialize LCD control lines to output */ GPIO_InitStructure.GPIO_Pin = LCD_RS_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LCD_RS_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_RW_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LCD_RW_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LCD_EN_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LCD_EN_GPIO_PORT, &GPIO_InitStructure); /* Enable GPIO clocks for LCD data pins */ RCC_APB2PeriphClockCmd(LCD_DATA_GPIO_CLK, ENABLE); /* initialize LCD data port to output */ GPIO_InitStructure.GPIO_Pin = LCD_DATA_GPIO_PINS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LCD_DATA_GPIO_PORT, &GPIO_InitStructure); } /** * @brief waits until LCD is not busy. * @param None * @retval None */ void lcd_Busy_Wait(void) { u8 status; do { status = lcd_data_line_read(); } while (status & 0x80); /* Wait for busy flag */ } /** * @brief writes a control command to the LCD. * @param data: Specifies the control command to the LCD. * This parameter can be one of following parameters: * @arg LCD_DD_RAM_PTR : Address Display Data RAM pointer * @arg LCD_CLEAR_DISPLAY : Clear entire display and set Display Data Address to 0 * @arg LCD_RETRN_HOME : sets DDRAM address 0 and returns display from being shifted to original position. * @arg LCD_DISP_INIT : 8 bit data length and 2 lines * @arg LCD_INC_MODE : Entry mode is display Data RAM pointer incremented after write * @arg LCD_DISP_ON : Sets entire display on, cursor on and blinking of cursor position character * @arg LCD_DISP_OFF : Sets entire display off, cursor off * @arg LCD_CURSOR_ON : turn on cursor * @arg LCD_CURSOR_OFF : turn off cursor * @arg LCD_CUR_MOV_LEFT : Cursor move and shift to left * @arg LCD_CUR_MOV_RIGHT : Cursor move and shift to right * @retval None */ void lcd_Control_Write(u8 data) { /* write the control byte to the display controller */ /* wait until LCD not busy */ lcd_Busy_Wait(); /* set RS to "control" */ CLR_LCD_RS_Line(); /* set R/W to "write" */ CLR_LCD_RW_Line(); /* set data I/O lines to output (8bit) */ lcd_data_line_conf(Output); /* output data, 8bits */ lcd_data_line_write(data); /* leave data lines in input mode to save power consumption */ /* set data I/O lines to input (8bit) */ lcd_data_line_conf(Input); } /** * @brief read the control status from the LCD. * @param None * @retval 8 bits value from LCD */ u8 lcd_Control_Read(void) { /* read the control byte from the display controller */ register u8 data; /* wait until LCD not busy */ lcd_Busy_Wait(); /* set data I/O lines to input (8bit) */ lcd_data_line_conf(Input); /* set RS to "control" */ CLR_LCD_RS_Line(); /* set R/W to "read" */ SET_LCD_RW_Line(); /* input data, 8bits */ data = lcd_data_line_read(); /* leave data lines in input mode to save power consumption */ /* set data I/O lines to input (8bit) */ lcd_data_line_conf(Input); return data; } /** * @brief writes a data byte to the LCD screen at the current position. * @param data: data is writed to the LCD. * This parameter is ASCII code or user data: * @retval None */ void lcd_Data_Write(u8 data) { /* write a data byte to the display */ /* wait until LCD not busy */ lcd_Busy_Wait(); /* set RS to "data" */ SET_LCD_RS_Line(); /* set R/W to "write" */ CLR_LCD_RW_Line(); /* set data I/O lines to output (8bit) */ lcd_data_line_conf(Output); /* output data, 8bits */ lcd_data_line_write(data); /* leave data lines in input mode to save power consumption */ /* set data I/O lines to input (8bit) */ lcd_data_line_conf(Input); } /** * @brief reads the data byte on the LCD screen at the current position. * @param None * @retval 8 bits value from LCD */ u8 lcd_Data_Read(void) { /* read a data byte from the display */ register u8 data; /* wait until LCD not busy */ lcd_Busy_Wait(); /* set data I/O lines to input (8bit) */ lcd_data_line_conf(Input); /* set RS to "data" */ SET_LCD_RS_Line(); /* set R/W to "read" */ SET_LCD_RW_Line(); /* input data, 8bits */ data = lcd_data_line_read(); /* leave data lines in input mode to save power consumption */ /* set data I/O lines to input (8bit) */ lcd_data_line_conf(Input); return data; } /* ************************************************************************************************************************************* * GLOBAL FUNCTIONS * ************************************************************************************************************************************* */ /** * @brief Initializes the LCD. * @param None * @retval None */ void lcd_Init(void) { /* initialize hardware */ lcd_Init_HW(); /* Set 4-bits interface */ lcd_Control_Write(0x38); Delay(10); lcd_Control_Write(0x32); Delay(10); /* Start to set LCD function */ lcd_Control_Write(LCD_DISP_INIT); /* clear LCD */ lcd_Control_Write(LCD_CLEAR_DISPLAY); /* wait 60ms */ /* set entry mode */ lcd_Control_Write(LCD_INC_MODE); /* set display to on */ lcd_Control_Write(LCD_DISP_ON); /* move cursor to home and set data address to 0 */ lcd_Control_Write(LCD_RETRN_HOME); } /** * @brief moves the cursor/position to Home (upper left corner). * @param None * @retval None */ void lcd_Home(void) { // move cursor to home lcd_Control_Write(LCD_RETRN_HOME); delay(5); } /** * @brief clears the LCD display. * @param None * @retval None */ void lcd_Clear(void) { lcd_Control_Write(LCD_CLEAR_DISPLAY); delay(5); } /** * @brief moves the cursor/position to the row,col requested, * this may not be accurate for all displays. * @param x: the position of row of the LCD. * This parameter can be one of following parameters: * @arg 0-1 : the LCD has 2 row * @param y: the position of column of the LCD. * This parameter can be one of following parameters: * @arg 0-15 : the LCD has 16 column * @retval None */ void lcd_GotoXY(u8 x, u8 y) { register u8 DDRAMAddr; // remap lines into proper order switch(x) { case 0: DDRAMAddr = LCD_LINE0_ADDR+y; break; case 1: DDRAMAddr = LCD_LINE1_ADDR+y; break; //case 2: DDRAMAddr = LCD_LINE2_ADDR+y; break; // for LCD 16x4 or 20x4 only //case 3: DDRAMAddr = LCD_LINE3_ADDR+y; break; default: DDRAMAddr = LCD_LINE0_ADDR+y; } // set data address lcd_Control_Write(LCD_DD_RAM_PTR | DDRAMAddr); delay(5); } /** * @brief prints a series of bytes/characters to the display. * @param data: data or characters is writed to LCD. * This parameter can be one of following parameters: * @arg 8bits data value * @param nBytes: number of data or character that's writed to LCD. * This parameter can be one of following parameters: * @arg 0-255 * @retval None */ void lcd_Print_Data(char* data, u8 nBytes) { register u8 i; /* check to make sure we have a good pointer */ if (!data) return; /* print data */ for(i=0; i<nBytes; i++) { lcd_Data_Write(data[i]); delay(5); } } /******************* (C) COPYRIGHT 2010 ARMVietNam *****END OF FILE****/
Code:
/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __LCD_H #define __LCD_H #ifdef __cplusplus extern "C" { #endif /* ************************************************************************************************************************************* * INCLUDED FILES * ************************************************************************************************************************************* */ #include "stm32f10x.h" /** @addtogroup STM32F10x_GEM3M_Examples * @{ */ /** @addtogroup LCD_16X2 * @{ */ /* ************************************************************************************************************************************* * PRIVATE DEFINE * ************************************************************************************************************************************* */ /*--------------------------------------------------------- Low level define ----------------------------------------------------------*/ /** * @brief Hardware define for LCD */ /* LCD Control pins----------------------------------------------------- */ #define LCD_RS_GPIO_PORT GPIOA #define LCD_RS_GPIO_CLK RCC_APB2Periph_GPIOA #define LCD_RS_GPIO_PIN GPIO_Pin_2 #define LCD_RW_GPIO_PORT GPIOA #define LCD_RW_GPIO_CLK RCC_APB2Periph_GPIOA #define LCD_RW_GPIO_PIN GPIO_Pin_4 #define LCD_EN_GPIO_PORT GPIOA #define LCD_EN_GPIO_CLK RCC_APB2Periph_GPIOA #define LCD_EN_GPIO_PIN GPIO_Pin_6 /* LCD Data pins----------------------------------------------------- */ /* No need because of 4 bits mode b*/ #define LCD_D4 GPIO_Pin_8 #define LCD_D5 GPIO_Pin_9 #define LCD_D6 GPIO_Pin_10 #define LCD_D7 GPIO_Pin_11 #define LCD_DATA_GPIO_PINS (LCD_D4|LCD_D5|LCD_D6|LCD_D7) #define LCD_DATA_GPIO_PORT GPIOA #define LCD_DATA_GPIO_CLK RCC_APB2Periph_GPIOA /** * @brief LCD command for HD44780U */ /* LCD memory map */ #define LCD_LINE0_ADDR 0x00 // Start of line 0 in the DD-Ram #define LCD_LINE1_ADDR 0x40 // Start of line 1 in the DD-Ram //#define LCD_LINE2_ADDR 0x14 // Only for LCD 20x4: start of line 2 in the DD-Ram //#define LCD_LINE3_ADDR 0x54 // Only for LCD 20x4: start of line 3 in the DD-Ram /* LCD Commands */ #define LCD_DD_RAM_PTR 0x80 // Address Display Data RAM pointer #define LCD_CG_RAM_PTR 0x40 // Address Character Generator RAM pointer #define LCD_CLEAR_DISPLAY 0x01 // Clear entire display and set Display Data Address to 0 #define LCD_RETRN_HOME 0x02 // sets DDRAM address 0 and returns display from being shifted to original position. #define LCD_DISP_INIT 0x28 // function set is 4 bit data length and 2 lines #define LCD_INC_MODE 0x06 // Entry mode is display Data RAM pointer incremented after write #define LCD_DISP_ON 0x0C // Sets entire display on, cursor on and blinking of cursor position character #define LCD_DISP_OFF 0x08 // Sets entire display off, cursor off #define LCD_CURSOR_ON 0x04 // turn on cursor #define LCD_CURSOR_OFF 0x00 // turn off cursor #define LCD_CUR_MOV_LEFT 0x10 // Cursor move and shift to left #define LCD_CUR_MOV_RIGHT 0x14 // Cursor move and shift to right #define LCD_BUSY 0x80 // LCD is busy /* ************************************************************************************************************************************* * PRIVATE TYPE DEFINE * ************************************************************************************************************************************* */ /* GPIO configuration mode */ typedef enum { Input = 0, Output } GPIOConfig_Mode_TypeDef; /* ************************************************************************************************************************************* * PRIVATE MACRO * ************************************************************************************************************************************* */ #define SET_LCD_RS_Line() GPIO_SetBits(LCD_RS_GPIO_PORT, LCD_RS_GPIO_PIN) #define CLR_LCD_RS_Line() GPIO_ResetBits(LCD_RS_GPIO_PORT, LCD_RS_GPIO_PIN) #define SET_LCD_RW_Line() GPIO_SetBits(LCD_RW_GPIO_PORT, LCD_RW_GPIO_PIN) #define CLR_LCD_RW_Line() GPIO_ResetBits(LCD_RW_GPIO_PORT, LCD_RW_GPIO_PIN) #define SET_LCD_EN_Line() GPIO_SetBits(LCD_EN_GPIO_PORT, LCD_EN_GPIO_PIN) #define CLR_LCD_EN_Line() GPIO_ResetBits(LCD_EN_GPIO_PORT, LCD_EN_GPIO_PIN) /* ************************************************************************************************************************************* * PRIVATE VARIABLES * ************************************************************************************************************************************* */ /* ************************************************************************************************************************************* * PRIVATE FUNCTION PROTOTYPES * ************************************************************************************************************************************* */ // ****** Low-level functions ****** // the following functions are the only ones which deal with the CPU // memory or port pins directly. If you decide to use a fundamentally // different hardware interface to your LCD, only these functions need // to be changed, after which all the high-level functions will // work again. void lcd_data_line_write(u8 data); u8 lcd_data_line_read(void); void lcd_data_line_conf(GPIOConfig_Mode_TypeDef IO_mode); // initializes I/O pins connected to LCD void lcd_Init_HW(void); // waits until LCD is not busy void lcd_Busy_Wait(void); // writes a control command to the LCD void lcd_Control_Write(u8 data); // read the control status from the LCD u8 lcd_Control_Read(void); // writes a data byte to the LCD screen at the current position void lcd_Data_Write(u8 data); // reads the data byte on the LCD screen at the current position u8 lcd_Data_Read(void); /* ************************************************************************************************************************************* * GLOBAL FUNCTION PROTOTYPES * ************************************************************************************************************************************* */ // ****** High-levlel functions ****** // these functions provide the high-level control of the LCD // such as clearing the display, setting cursor positions, // displaying text and special characters // initializes the LCD display (gets it ready for use) void lcd_Init(void); // moves the cursor/position to Home (upper left corner) void lcd_Home(void); // clears the LCD display void lcd_Clear(void); // moves the cursor/position to the row,col requested // ** this may not be accurate for all displays void lcd_GotoXY(u8 row, u8 col); // prints a series of bytes/characters to the display void lcd_Print_Data(char* data, u8 nBytes); #ifdef __cplusplus } #endif #endif /* __LCD_H */ /******************* (C) COPYRIGHT 2009 ARMVietNam *****END OF FILE****/
Code:
*/ #include <stdio.h> #include "main.h" #include "lcd.h" /** @addtogroup STM32F10x_GEM3M_Examples * @{ */ /** @addtogroup LCD_16X2 * @{ */ /* ************************************************************************************************************************************* * PRIVATE DEFINE * ************************************************************************************************************************************* */ /* ************************************************************************************************************************************* * DATA TYPE DEFINE * ************************************************************************************************************************************* */ /* ************************************************************************************************************************************* * PRIVATE VARIABLES * ************************************************************************************************************************************* */ /* ************************************************************************************************************************************* * LOCAL FUNCTIONS * ************************************************************************************************************************************* */ /** * @brief Configures the different system clocks. * @param None * @retval None */ void RCC_Configuration(void) { /* Setup the microcontroller system. Initialize the Embedded Flash Interface, initialize the PLL and update the SystemFrequency variable. */ //SystemInit(); } /** * @brief Inserts a delay time with resolution is 10 milisecond.. * @param nCount: specifies the delay time length. * @retval None */ void Delay(__IO uint32_t num) { __IO uint32_t index = 0; /* default system clock is 72MHz */ for(index = (24000 * num); index != 0; index--) { } } /* ************************************************************************************************************************************* * GLOBAL FUNCTIONS * ************************************************************************************************************************************* */ /** * @brief Main program. * @param None * @retval None */ int main(void) { /* Configure the system clocks */ RCC_Configuration(); /* initialize LCD */ lcd_Init(); lcd_Clear(); /* print message on LCD */ lcd_GotoXY(0,0); printf("Sharing Tech in"); lcd_GotoXY(1,0); printf("=> ARM Viet Nam"); lcd_Print_Data("Vietnam",7); while (1) { /* Insert delay */ Delay(100); lcd_Data_Write('a'); lcd_Print_Data("Vietnam",7); } } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */ /** * @} */ /******************* (C) COPYRIGHT 2009 ARMVietNam *****END OF FILE****/
Comment