Thông báo

Collapse
No announcement yet.

LCD+STM32F4xx HELP?

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • LCD+STM32F4xx HELP?

    Sao mình sử dụng đoạn code này nạp vào modun STM32F407VG-DISCOVERY để text cái LCD 16x2 mà toàn ra màn hinh sáng hết. Không biết mình sai chổ nào nữa.
    Code "lcd.h"
    Code:
    #include "stm32f4xx.h"
    
    #define LCD_RS_GPIO_PORT GPIOB
    #define LCD_RS_GPIO_CLK RCC_AHB1Periph_GPIOB
    #define LCD_RS_GPIO_PIN GPIO_Pin_0
    
    #define LCD_RW_GPIO_PORT GPIOB
    #define LCD_RW_GPIO_CLK RCC_HB1Periph_GPIOB
    #define LCD_RW_GPIO_PIN GPIO_Pin_1
    
    #define LCD_EN_GPIO_PORT GPIOB
    #define LCD_EN_GPIO_CLK RCC_AHB1Periph_GPIOB
    #define LCD_EN_GPIO_PIN GPIO_Pin_2
    
    #define LCD_D4 GPIO_Pin_4
    #define LCD_D5 GPIO_Pin_5
    #define LCD_D6 GPIO_Pin_6
    #define LCD_D7 GPIO_Pin_7
    #define LCD_DATA_GPIO_PINS (LCD_D4|LCD_D5|LCD_D6|LCD_D7)
    #define LCD_DATA_GPIO_PORT GPIOB
    #define LCD_DATA_GPIO_CLK RCC_AHB1Periph_GPIOB
    
    void lcd_init(void);
    void LCD_STROBE(void);
    void LCD_DATA(u8 cX );
    void lcd_write(u8 c);
    void lcd_clear(void);
    void lcd_putchar(u8 c);
    void lcd_putsf(u8 *c);
    void lcd_gotoxy(u8 row,u8 col);
    
    void LCD_Delay_US(__IO uint32_t num)
    {
    __IO uint32_t index = 0;
    for(index = (72 * num); index != 0; index--)
    {
    }
    }
    
    void LCD_STROBE(void)
    {
    GPIO_SetBits(LCD_DATA_GPIO_PORT, LCD_EN_GPIO_PIN);
    LCD_Delay_US(30);
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_EN_GPIO_PIN) ;
    LCD_Delay_US(30);
    }
    
    void LCD_DATA(u8 cX )
    {
    GPIO_WriteBit(LCD_DATA_GPIO_PORT, LCD_D4, (BitAction)(cX & 0x01) );
    GPIO_WriteBit(LCD_DATA_GPIO_PORT, LCD_D5, (BitAction)((cX & 0x02) >> 1) );
    GPIO_WriteBit(LCD_DATA_GPIO_PORT, LCD_D6, (BitAction)((cX & 0x04) >> 2) );
    GPIO_WriteBit(LCD_DATA_GPIO_PORT, LCD_D7, (BitAction)((cX & 0x08) >> 3) );
    }
    
    void lcd_write(u8 c)
    {
    LCD_DATA( c >> 4 );
    LCD_STROBE();
    LCD_DATA( c );
    LCD_STROBE();
    }
    
    void lcd_clear(void)
    {
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_RS_GPIO_PIN) ;
    lcd_write(0x01);
    LCD_Delay_US(2000);
    }
    
    void lcd_putchar(u8 c)
    {
    GPIO_SetBits(LCD_DATA_GPIO_PORT,LCD_RS_GPIO_PIN);
    lcd_write( c );
    }
    
    void lcd_putsf(u8 *c)
    {
    GPIO_SetBits(LCD_DATA_GPIO_PORT,LCD_RS_GPIO_PIN);
    while(*c)
    lcd_write(*c++);
    }
    
    void lcd_gotoxy(u8 row,u8 col)
    {
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_RS_GPIO_PIN) ;
    switch(row)
    {
    case 0 : lcd_write( 0x80 + col ) ; //dia chi bat dau + col (cua LCD)
    break ;
    case 1 : lcd_write( 0xC0 + col ) ;
    break ;
    case 2 : lcd_write( 0x94 + col ) ;
    break ;
    case 3 : lcd_write( 0xD4 + col ) ;
    break ;
    }
    }
    
    void lcd_init(void)
    {
    GPIO_InitTypeDef GPIO_InitStruct;
    
    RCC_APB2PeriphClockCmd(LCD_DATA_GPIO_CLK, ENABLE);
    
    GPIO_InitStruct.GPIO_Pin = LCD_RS_GPIO_PIN | LCD_RW_GPIO_PIN | LCD_EN_GPIO_PIN | LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7 ;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init(LCD_DATA_GPIO_PORT, &GPIO_InitStruct);
    
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_RS_GPIO_PIN) ;
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_EN_GPIO_PIN) ;
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_RW_GPIO_PIN) ;
    
    LCD_Delay_US(15000);
    LCD_DATA(0x03);
    LCD_STROBE();
    LCD_Delay_US(5000);
    LCD_STROBE();
    LCD_Delay_US(200);
    LCD_STROBE();
    LCD_Delay_US(200);
    LCD_DATA(2);
    LCD_STROBE();
    
    lcd_write(0x28); // Set interface length
    lcd_write(0x0C); // Display On, Cursor On, Cursor Blink
    lcd_clear(); // Clear screen
    lcd_write(0x6);
    }
    Code "main.c"
    Code:
    #include "stm32f4xx.h"
    #include "main.h"
    int main (void)
    {
    	lcd_init();
            lcd_clear();
    	while(1)
    	{
    		lcd_gotoxy(0,2);
    		lcd_putsf(" DIEN TU ");
    	}
    }
    #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) */
    
      while (1)
      {}
    }
    #endif
    Nhưng mà mình sử dụng code do ST cung cấp thì sử dụng được
    Code:
    #include "stm32f4xx.h"
    
    #define     LCM_OUT               GPIOB->ODR
    
    // connect RW leg to GND, and power supply rails to +5V and gnd
    // Define symbolic LCM - MCU pin mappings
    // We've set DATA PIN TO 4,5,6,7 for easy translation
    //
    #define     LCM_PIN_RS            GPIO_Pin_0          // P1.0
    #define     LCM_PIN_EN            GPIO_Pin_2          // P1.2
    #define     LCM_PIN_D7            GPIO_Pin_7          // P1.7
    #define     LCM_PIN_D6            GPIO_Pin_6          // P1.6
    #define     LCM_PIN_D5            GPIO_Pin_5          // P1.5
    #define     LCM_PIN_D4            GPIO_Pin_4          // P1.4
    
    GPIO_InitTypeDef  GPIO_InitStructure;
    #define     LCM_PIN_MASK  ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4))
    
    #define     FALSE                 0
    #define     TRUE                  1
    
    void __delay_cycles(int a)
    {
        int i = 0;
        int f = 0;
        while(f<a)
        {
                while(i<60)
                    {i++;}
            f++;
        }
    }
    
    void PulseLcm()
    {
        LCM_OUT &= ~LCM_PIN_EN;
        __delay_cycles(220);
        LCM_OUT |= LCM_PIN_EN;
        __delay_cycles(220);
        LCM_OUT &= (~LCM_PIN_EN);
        __delay_cycles(220);
    }
    
    void SendByte(char ByteToSend, int IsData)
    {
        LCM_OUT &= (~LCM_PIN_MASK);
        LCM_OUT |= (ByteToSend & 0xF0);
    
        if (IsData == TRUE)
        {
            LCM_OUT |= LCM_PIN_RS;
        }
        else
        {
            LCM_OUT &= ~LCM_PIN_RS;
        }
        PulseLcm();
        LCM_OUT &= (~LCM_PIN_MASK);
        LCM_OUT |= ((ByteToSend & 0x0F) << 4);
    
        if (IsData == TRUE)
        {
            LCM_OUT |= LCM_PIN_RS;
        }
        else
        {
            LCM_OUT &= ~LCM_PIN_RS;
        }
    
        PulseLcm();
    }
    
    void Cursor(char Row, char Col)
    {
        char address;
        if (Row == 0)
        {
            address = 0;
        }
        else
        {
            address = 0x40;
        }
    
        address |= Col;
        SendByte(0x80 | address, FALSE);
    }
    
    
    void ClearLcmScreen()
    {
        SendByte(0x01, FALSE);
        SendByte(0x02, FALSE);
    }
    
    void InitializeLcm(void)
    {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
    
        LCM_OUT &= ~(LCM_PIN_MASK);
    
        __delay_cycles(32000);
        __delay_cycles(32000);
        __delay_cycles(32000);
    
        LCM_OUT &= ~LCM_PIN_RS;
        LCM_OUT &= ~LCM_PIN_EN;
        LCM_OUT = 0x20;
        PulseLcm();
        SendByte(0x28, FALSE);
        SendByte(0x0E, FALSE);
        SendByte(0x06, FALSE);
    }
    
    
    void PrintStr(char *Text)
    {
        char *c;
    
        c = Text;
    
        while ((c != 0) && (*c != 0))
        {
            SendByte(*c, TRUE);
            c++;
        }
    }
    //***************************************************************
    main
    Code:
    #include "stm32f4xx.h"
    #include "lcd.h"
    
    int main(void)
    {
       int a = 0;
                while(a<100)
                {
                    __delay_cycles(32000);
                    a++;
                }
    
        InitializeLcm();
        __delay_cycles(32000);
        ClearLcmScreen();
        __delay_cycles(32000);
        Cursor(0,0);
        PrintStr("DIEN TU");
        Cursor(1,0);
        __delay_cycles(32000);
        PrintStr("VIET NAM");
    
          while(1);
    }
    //******************************************************
    #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****/
    Mong mọi người giúp đỡ.

  • #2
    Tìm ra chỗ rồi. Cảm ơn mấy bạn đã xem.


    void lcd_init(void)
    {
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_APB2PeriphClockCmd(LCD_DATA_GPIO_CLK, ENABLE);

    GPIO_InitStruct.GPIO_Pin = LCD_RS_GPIO_PIN | LCD_RW_GPIO_PIN | LCD_EN_GPIO_PIN | LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7 ;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init(LCD_DATA_GPIO_PORT, &GPIO_InitStruct);

    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_RS_GPIO_PIN) ;
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_EN_GPIO_PIN) ;
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_RW_GPIO_PIN) ;

    LCD_Delay_US(15000);
    LCD_DATA(0x03);
    LCD_STROBE();
    LCD_Delay_US(5000);
    LCD_STROBE();
    LCD_Delay_US(200);
    LCD_STROBE();
    LCD_Delay_US(200);
    LCD_DATA(2);
    LCD_STROBE();

    lcd_write(0x28); // Set interface length
    lcd_write(0x0C); // Display On, Cursor On, Cursor Blink
    lcd_clear(); // Clear screen
    lcd_write(0x6);
    }


    Thay bằng

    void lcd_init(void)
    {
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHB1PeriphClockCmd(LCD_DATA_GPIO_CLK, ENABLE);

    GPIO_InitStruct.GPIO_Pin = LCD_RS_GPIO_PIN | LCD_RW_GPIO_PIN | LCD_EN_GPIO_PIN | LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7 ;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

    GPIO_Init(LCD_DATA_GPIO_PORT, &GPIO_InitStruct);

    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_RS_GPIO_PIN) ;
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_EN_GPIO_PIN) ;
    GPIO_ResetBits(LCD_DATA_GPIO_PORT,LCD_RW_GPIO_PIN) ;

    LCD_Delay_US(15000);
    LCD_DATA(0x03);
    LCD_STROBE();
    LCD_Delay_US(5000);
    LCD_STROBE();
    LCD_Delay_US(200);
    LCD_STROBE();
    LCD_Delay_US(200);
    LCD_DATA(2);
    LCD_STROBE();

    lcd_write(0x28); // Set interface length
    lcd_write(0x0C); // Display On, Cursor On, Cursor Blink
    lcd_clear(); // Clear screen
    lcd_write(0x6);
    }

    Comment


    • #3
      Sao minh test thu no ko chay ta?? Co chay ko ban?

      Comment


      • #4
        Ban co the cho minh xin project ve LCD 16x2 ma ST cung cap ve STM32F4xx nay duoc ko? Tks ban nhieu...

        Comment


        • #5
          Các bạn cho mình hỏi STM32Fx này thì bạn dùng toolchain nào để lập trình, free, bản quyền hay cracked thế ? Mình lâu không nghịch mấy con microcontrollers, google sơ thì thấy Keil, Atollic ... nhưng đều là phải mua thì phải ?
          Sorry vì câu hỏi hơi bị ngu ngơ

          Comment


          • #6
            Đây là bài project do mình viết nó chạy được mà.
            LCD_1.rar

            Comment


            • #7
              Cái này thì bạn dùng Keil Arm. Có cách bẻ khoá hết mà bạn.

              Comment


              • #8
                hi hi ... Dùng Keil khoai thế ... Mình nghe anh QD dùng sang MikroC ... ngon hơn, đơn giản thật
                Code:
                // LCD module connections
                sbit LCD_RS at GPIO_PORTA_DATA.B2;
                sbit LCD_EN at GPIO_PORTA_DATA.B3;
                sbit LCD_D4 at GPIO_PORTA_DATA.B4;
                sbit LCD_D5 at GPIO_PORTA_DATA.B5;
                sbit LCD_D6 at GPIO_PORTA_DATA.B6;
                sbit LCD_D7 at GPIO_PORTA_DATA.B7;
                
                
                sbit LCD_RS_Direction at GPIO_PORTA_DIR.B2;
                sbit LCD_EN_Direction at GPIO_PORTA_DIR.B3;
                sbit LCD_D4_Direction at GPIO_PORTA_DIR.B4;
                sbit LCD_D5_Direction at GPIO_PORTA_DIR.B5;
                sbit LCD_D6_Direction at GPIO_PORTA_DIR.B6;
                sbit LCD_D7_Direction at GPIO_PORTA_DIR.B7;
                // End LCD module connections
                
                char txt1[] = "mikroElektronika";    
                char txt2[] = "Stellaris";
                char txt3[] = "Lcd4bit";
                char txt4[] = "example";
                
                char i;                              // Loop variable
                
                void Move_Delay() {                  // Function used for text moving
                  Delay_ms(750);                     // You can change the moving speed here
                }
                
                void main(){
                  Lcd_Init();                        // Initialize LCD
                
                  Lcd_Cmd(_LCD_CLEAR);               // Clear display
                  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
                  Lcd_Out(1,6,txt3);                 // Write text in first row
                
                  Lcd_Out(2,6,txt4);                 // Write text in second row
                  Delay_ms(2000);
                  Lcd_Cmd(_LCD_CLEAR);               // Clear display
                
                  Lcd_Out(1,1,txt1);                 // Write text in first row
                  Lcd_Out(2,4,txt2);                 // Write text in second row
                
                  Delay_ms(2000);
                
                  // Moving text
                  for(i=0; i<4; i++) {               // Move text to the right 4 times
                    Lcd_Cmd(_LCD_SHIFT_RIGHT);
                    Move_Delay();
                  }
                
                  while(1) {                         // Endless loop
                    for(i=0; i<7; i++) {             // Move text to the left 7 times
                      Lcd_Cmd(_LCD_SHIFT_LEFT);
                      Move_Delay();
                    }
                
                    for(i=0; i<7; i++) {             // Move text to the right 7 times
                      Lcd_Cmd(_LCD_SHIFT_RIGHT);
                      Move_Delay();
                    }
                  }
                }
                (Phi)
                Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

                Comment

                Về tác giả

                Collapse

                kunboy Tìm hiểu thêm về kunboy

                Bài viết mới nhất

                Collapse

                • Andrea14
                  Vấn đề về tốc độ quay
                  bởi Andrea14
                  Chào mọi người,

                  Tôi muốn mô phỏng sự thay đổi các mùa bằng cách từ từ nghiêng một quả địa cầu 16 inch bằng một động cơ bước nhỏ. Một động cơ bước khác sẽ quay quả địa cầu theo thời gian thực. Hệ thống truyền động...
                  Hôm qua, 12:42
                • bqviet
                  Trả lời cho Đấu tắt điện cho máy tính bảng
                  bởi bqviet
                  Bqv cáo lỗi vì chưa đủ khả năng diễn giải để người đọc hiểu. Người làm kỹ thuật sâu đôi khi như thế đó. Về việc nạp pin không vào dù cell mới, khả năng cái mạch quản lý đó đã hỏng - cũng chính là nguyên nhân đám cell cũ hỏng từ đầu.
                  06-12-2025, 17:17
                • nguyendinhvan
                  Trả lời cho Xin hỏi về mạch thu FM/AM trong catsette
                  bởi nguyendinhvan
                  Theo tôi, nó chỉ là cái Tuy- ê - nơ, hoặc là khối Trung Văn Tần, nó một phần trong cái Da đì ô thôi. Vì có thấy một chỗ có ba chân hàn, giiống như chân Cờ rít sờ tăng 455 ki nô hẹc. Còn khối Tuy ê nơ thì không nhìn thây cái Di ốt Va di cáp...
                  05-12-2025, 19:59
                • afrendly
                  Trả lời cho Đấu tắt điện cho máy tính bảng
                  bởi afrendly
                  Có vẻ ngoài hiểu biết của mình rồi. Cuối cùng mình quyết định tìm mua 2 pin trên Shopee, giá 200K thay vào. Tuy nhận pin được 1%, sạc mãi không vào nhưng cũng mở được máy lên. Vậy cũng tạm. Cảm ơn bạn đã hỗ trợ nhé....
                  04-12-2025, 01:27
                Đang tải...
                X