Thông báo

Collapse
No announcement yet.

LCD kit spartan3E

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

  • #16
    LCD Firmware

    Phần trước giới thiệu xong phần import customer hadware, phần này giới thiệu về driver cho LCD.
    Sau khi import lcd_port vào bus hệ thống, XPS tự động tạo ra thư viện hỗ trợ cho việc phát triển phần mềm. Ngoài ra các file hệ thống cũng được cập nhật.

    file: system.mhs

    Code:
     BEGIN lcd_port
     PARAMETER INSTANCE = lcd_port_0
     PARAMETER HW_VER = 1.00.a
     PARAMETER C_BASEADDR = 0x77400000
     PARAMETER C_HIGHADDR = 0x7740ffff
     BUS_INTERFACE SOPB = mb_opb
     PORT lcd_port_pin = lcd_port_0_lcd_port_pin
     PORT OPB_Clk = sys_clk_s
     END
    file: system.mss

    Code:
     BEGIN DRIVER
     PARAMETER DRIVER_NAME = lcd_port
     PARAMETER DRIVER_VER = 1.00.a
     PARAMETER HW_INSTANCE = lcd_port_0
     END
    Driver được tạo ra trong đường dẫn :
    ...drivers/lcd_port_v1_00_a/src/
    /lcd_port.c
    /lcd_port.h
    /lcd_port_selftest.c
    /Makefile

    File lcd_port_selftest.c được tạo ra cho việc test thanh ghi reg0 (lcd_port), ta có thể tham khảo, sữa chữa tùy vào mục đích xử dụng.
    Các prototype cho các hàm truy xuất thanh ghi được khai báo trong lcd_port.h

    Sau đây là các bước tạo project mới dùng công cụ phát triển phần mềm SDK của xilinx.

    1> Trên tool bar của XPS:
    Chọn Software -> Lauch Platform Studio SDK



    2> Trong hộp thoại Application Wizard:
    Chọn Creat a New SDK Application Project -> Next

    3> Trong mục New Project
    Đặt tên project -> Next



    Lấy thông số mặc định Xilinx MicroBlaze Executable -> Next



    Finish thao tác create new project



    Sau khi hoàn tất các bước trên xilinx tự động tạo các thư mục và các file trong thư mục có tên project name, và một danh sách các thư viện có liên quan đến microblaze.



    4> Tạo Linker Script :
    Trong mục Navigator, click chuột phải lcd_disp -> Gnenerate Linker Script...



    Trong crop down list chọn DDRAM, dùng làm vùng nhớ data , text ....

    6> Creat New Source file
    Click vào biểu tượng C+ trên tool bar



    Đặt tên file lcd.c



    Để viết chương trình giao tiếp lcd, tức là dùng microblaze xuất tín hiệu điều khiển lên port_lcd, ngoài lcd_port còn có các ngoại vi khác. Microblaze là processor có cấu trúc tổ chức bộ nhớ Havard, Vùng Intruction và vùng IO, memory nằm riêng biệt. Các IO được truy xuất thông qua địa chỉ, mỗi IO chiếm một vùng nhớ có tầm từ C_BASEADDR - C_HIGHADDR. Các base add được cập nhật trong file system.mhs sau khi thực hiện thao tác Generate Address trong mục trình bày trên. Ta có thể tham khảo C_BASEADDR thông qua bước sau:
    Trong XPS -> System Essembly View -> chọn IO -> click chuột phải -> Conigure IP ...





    Và địa chỉ đầu tiên 0x77400000 được dùng cho việc truy xuất thanh ghi reg0 (Do phần creat custom hardware ta chọn option cho 1 thanh ghi, trong trường hợp tạo nhiều thanh ghi, ví dụ như reg0, reg1, reg2 thì địa chỉ truy xuất các thanh ghi này sẽ lần lượt là C_BASEADDR,C_BASEADDR+0x04,C_BASEADDR +0x08...)



    Hàm LCD_PORT_mWriteSlaveReg0(LCD_PORT_BASE_ADDR, (value)) được định nghĩa sẵn bởi Xilinx, ghi giá trị "value" ra lcd_port.

    7> Edit lcd.c
    Công việc kế tiếp là soạn thảo code điểu khiển LCD, hầu hết các board FPGA đều thiết kế cho việc giao tiếp mode 4 bit. Trong phần thiết kế này dùng 1 port xuất để điểu khiển, lcd_port<6:0> <-> (E, RW,RS,D7,D6,D5,D4)



    Code:
    //////////////////////////////////////////////////////////////////////////////
    // Filename:          lcd.c
    // Version:           1.00.a
    // Description:       lcd_port Driver Source File
    // Date:              21/09/2007
    //////////////////////////////////////////////////////////////////////////////
    
    /***************************** Include Files *******************************/
    #include "lcd_port.h"
    #include "string.h"
    /************************* Constant Definitions ****************************/
    #define LCD_PORT_BASE_ADDR  0x77400000
    /************************* Macro Definitions *******************************/
    #define LCD_PORT_WRITE(value)\
            LCD_PORT_mWriteSlaveReg0(LCD_PORT_BASE_ADDR, (value)) 
    
    /**************************************************************************
    /* @Function name   : wait_us()                                             
    /* Description      : wait n micro seconds                                
    /* Argument         : unsigned int n                            
    /* Return value     : void
    /* Author           : Kamejoko80
    /* Date             : 21/09/2007   
    **************************************************************************/
    void wait_us(unsigned int n)
    {
    	unsigned int i,j;
    	for(i=1;i<=n;i++)
    	{
    		for(j=1;j<=50;j++)
    		{
    		}	
    	}
    }
    /**************************************************************************
    /* @Function name   : write_lcd_reg()                                             
    /* Description      : write lcd command                                
    /* Argument         : char value                            
    /* Return value     : void
    /* Author           : Kamejoko80
    /* Date             : 21/09/2007   
    **************************************************************************/
    void write_lcd_reg(char value)
    {
    	char temp;
    	temp = (value>>4)&0x0F;     /* get nibble high   */
    	LCD_PORT_WRITE(temp);       /* write to lcd port */
    	wait_us(1);
    	LCD_PORT_WRITE(temp|0x40);  /* E=1               */
        wait_us(1);
        LCD_PORT_WRITE(temp);       /* E=0               */
        wait_us(2);
        
        temp = value&0x0F;          /* get nibble low    */
        LCD_PORT_WRITE(temp);       /* write to lcd port */
        wait_us(1);
        LCD_PORT_WRITE(temp|0x40);  /* E=1               */
        wait_us(1);
        LCD_PORT_WRITE(temp);       /* E=0               */
        wait_us(2); 
        
    }
    /**************************************************************************
    /* @Function name   : write_lcd_reg()                                             
    /* Description      : write lcd command                                
    /* Argument         : char value                            
    /* Return value     : void
    /* Author           : Kamejoko80
    /* Date             : 21/09/2007   
    **************************************************************************/
    void write_lcd_data(char value)
    {
    	char temp;
    	temp = (value>>4)&0x0F;     /* get nibble high   */
    	temp |= 0x10;               /* RS=1              */
    	LCD_PORT_WRITE(temp);       /* write to lcd port */
    	wait_us(2);
    	LCD_PORT_WRITE(temp|0x40);  /* E=1               */
        wait_us(2);
        LCD_PORT_WRITE(temp);       /* E=0               */
        wait_us(4);
        
        temp = value&0x0F;          /* get nibble low    */
        temp |= 0x10;               /* RS=1              */
        LCD_PORT_WRITE(temp);       /* write to lcd port */
        wait_us(2);
        LCD_PORT_WRITE(temp|0x40);  /* E=1               */
        wait_us(2);
        LCD_PORT_WRITE(temp);       /* E=0               */
        wait_us(40); 
    }
    /**************************************************************************
    /* @Function name   : lcd_mode_init()                                             
    /* Description      : 4 bit mode initialization                               
    /* Argument         : void                            
    /* Return value     : void
    /* Author           : Kamejoko80
    /* Date             : 21/09/2007   
    **************************************************************************/
    void lcd_mode_init(void)
    {
    	wait_us(10000);      /* waits 10ms     */
    	write_lcd_reg(0x18); /* set 8 bit mode */
    	wait_us(5000);
    	write_lcd_reg(0x18); /* set 8 bit mode */
    	wait_us(500);
    	write_lcd_reg(0x18); /* set 8 bit mode */
    	wait_us(40);
    	write_lcd_reg(0x08); /* set 4 bit mode */
    	wait_us(40);
    	write_lcd_reg(0x28); /* set 2 lines    */
    	wait_us(40);
    	write_lcd_reg(0x08); /* display off    */
    	wait_us(40);          
    	write_lcd_reg(0x01); /* clear display  */ 
    	wait_us(2000);
    	write_lcd_reg(0x06); /* entry mode     */
    	wait_us(40);
    	write_lcd_reg(0x0C); /* display on     */
    	wait_us(10000);      /* waits 10ms     */ 	
    }
    /**************************************************************************
    /* @Function name   : lcd_clr_disp()                                             
    /* Description      : clear display & cursor home                               
    /* Argument         : void                            
    /* Return value     : void
    /* Author           : Kamejoko80
    /* Date             : 21/09/2007   
    **************************************************************************/
    void lcd_clr_disp(void)
    {
    	write_lcd_reg(0x01); /* clear lcd    */ 
    	wait_us(2000);
    	write_lcd_reg(0x02); /* cursor home  */ 
        wait_us(2000);
    }
    /**************************************************************************
    /* @Function name   : lcd_line_feed()                                             
    /* Description      : goto 2th line                               
    /* Argument         : void                            
    /* Return value     : void
    /* Author           : Kamejoko80
    /* Date             : 21/09/2007   
    **************************************************************************/
    void lcd_line_feed()
    {
    	write_lcd_reg(0x80|0x40); /* goto line 2  */
    	wait_us(40); 
    }
    /**************************************************************************
    /* @Function name   : lcd_print_str()                                             
    /* Description      : lcd print string                               
    /* Argument         : char *s                            
    /* Return value     : void
    /* Author           : Kamejoko80
    /* Date             : 21/09/2007   
    **************************************************************************/
    void lcd_print_str(char *s)
    {
    	int i=0;
    	while(i<strlen(s))
    	{
    		write_lcd_data(s[i++]);	
    	}
    }
    8> Edit main.c
    Chương trình chạy thử hiển thị ký tự trên LCD.

    Code:
    // Welcome to Xilinx Platform Studio SDK !
    //
    // This is an automatically created source file to help you get started.
    // To add more files, navigate to File -> New -> File
    // You may delete this file if you want to use only other files for your project.
    //
    int main()
    {
    	print("Enter main program \r\n");
    	
    	lcd_mode_init();
    	lcd_print_str("ML403 LCD DEMO");
    	lcd_line_feed();
    	lcd_print_str("microblaze v5.00");
    	
    	print("Exit main program \r\n");
    	return 0;
    	
    }

    Sau khi edit xong phần code
    CTRL+S : Save file
    CTRL+B : Build ( Hoặc click vào mục Build trên tool bar)
    Last edited by kamejoko80; 23-09-2007, 00:07.

    Comment


    • #17
      LCD Firmware Continue

      Sau Khi thực hiện 2 phần Hardware và Firmware, ta có thể load lên board để chạy thử. Để chạy micoblaze cần phải cấu hình thành hệ thống hoàn chỉnh, sau đó load chương trình.

      1> Kết nối cable Jtag vào taget board
      2> Trên tool bar SDK ấn vào Icon "Program Hardware" chương trình tự động load bitstream xuống board.
      3> Trong mục Navigator -> chọn lcd_port -> click chuột phải -> run



      Trên hộp thoại Run click "New"



      Chọn tab XMD Target Connection



      Sau khi ấn "Run" SDK load chương trình và microblaze bắt đầu chạy.
      SDK hỗ trợ chức năng deburg chạy step by step thông qua đường JTAG.
      Có thể điều khiển hoạt động của microblaze thông qua cửa sổ console:
      Tại dấu nhắc XMD%
      type lệnh run -> cho microbalze chạy
      type lệnh stop -> cho microblaze dừng

      Code:
      run
      XMD% 
      XMD% RUNNING>
      Code:
      XMD% RUNNING> stop
      XMD% 
      XMD% RUNNING> Processor stopped at PC: 0x2800001c
      Ta có thể dùng Terminal để hiển thị message qua đường UART



      Dùng microblze hiển thị chữ trên LCD phải qua nhiều bước tạo port, viết chương trình thủ tục rườm rà, nhưng không kém phần thú vị. Việc chọn FPGA cho việc nghiên cứu hệ thống nhúng có một số lợi điểm. Trong lúc phát triển phần mềm, người lập trình có thể đụng đến cả hardware thay vì phải đọc datasheet và lập trình đơn thuần. Và như thế ta có thể nắm rõ hơn chút ít những gì mình đang làm. Người phát triển có thể custom hệ thống theo chủ ý của mình nhằm mang lại tính hiệu quả về kinh tế nhưng vẫn đảm bảo đáp ứng yêu cầu đặt ra.

      Comment


      • #18
        Phiên bản EDK mình xài là 10.1, dùng ML402 nhưng không thể hiện OPB BUS để kết nối led, uart mà nó chỉ hiện XPS_GPIO với XPS_UART thì mình phải làm sao, có khi nào EDK của mình bị lỗi không. Mình xài bản full down trên mạng.

        Comment


        • #19
          Cái xps_*** là giao tiếp PLB4.6. Từ phiên bản 9.2, Xilinx chuyển hầu hết các ngoại vi từ bus OPB sang PLB. Bạn có thể chọn lại các bus OPB, nhưng BSB default sẽ tạo ra MicroBlaze với ngoại vi PLB.

          Cách liệt kê tất cả các ngoại vi:
          trong giao diện Xilinx Platform Studio, vào Edit/Preferences,
          chọn "IP Catalog and IP Config Dialog",
          tick vào "Display "Depricated" IP Cores in IP Catalog"

          Comment


          • #20
            Bạn Kamejiko80 có thể hướng dẫn cách tạo IPcore lcd_port để kết nối với bus PLB v4.6 không. Mình dùng phiên bản 10.1 nên không thể import cái IPcore của bạn vào mà không dùng OPB được, project của mình không dùng OPB. Mình đã làm thử tạo một IPcore cho PLB v4.6 nhưng không có chỗ để chọn độ rộng bit dữ liệu =8 như ở trên.

            Comment


            • #21
              Mình làm được rồi. Nhưng ở phần XPS, file lcd_port.h không tìm thấy. Bạn có thể xem lại giùm được không. Thanks.

              Comment


              • #22
                cho em hoi cac vi dieu khien vi du nhu 8051 khc FPGA o diem nao sao em thay 2 cai no na na nhu nhau vay

                Comment


                • #23
                  8051 hay các MCU khác thì là lập trình được reprogrammable,
                  còn FPGA thì là cấu hình được reconfigurable. 1 cái là phần mềm, còn 1 cái là phần cứng, bạn có thể cấu reconfigure FPGA để thành 1 MCU 8051 hay ARM, sau đó nó sẽ hoạt động như 1 MCU thực thụ.

                  Comment


                  • #24
                    kit3e
                    Ví dụ thì không thiếu
                    Nhưng với beginer, mình khuyên nên làm với picoBlaze8bit trước chứ.Chưa gì đã táng micoPlaze32bit với EDK thì chịu sao nổi.Hic hic.
                    Ví dụ LCD cho s3e có đấy.Làm trên sysgen.(matlab).Mà mình thấy anh em it nói tới corgen,sysgen,accelDSP nhỉ.Giờ căn bản là phải tạo core.Mà tạo core bằng VHDL thì bao giờ mới xong.Thầy mình khuyên phải dùng core của bọn nó,vì core tối ưu hơn.Mình không tạo được core tối ưu như bọn nó đâu.

                    Comment


                    • #25
                      LCD cũng lằng nhằng phết đấy
                      bạn đọc datasheet của nó chưa.
                      Mà điều khiển LCD dùng picoBlaze.Chứ viết bằng VHDL thì ai mà xem lỗi nổi cơ chứ.Hichic

                      Comment


                      • #26
                        Không hẳn như vậy đâu, cái điều khiển LCD là một GPIO, thực chất là 1 IP nối với MicroBlaze qua bus OPB, PLB hay FSL tùy bạn. Cái IP này thì mới viêt bằng VHDL,còn chương trình điều khiển LCD thì vẫn là code C thông thường.

                        Comment


                        • #27
                          Nói chung dùng EDK là các bạn chỉ chủ yếu viết C thôi. Bạn lấy IP GPIO có sẵn add vào project, đổi tên thành LCD_16x2, cấu hình độ rộng data là 7bit rồi lấy các port IO của nó kết nối mà xài thôi, không phải tạo IP LCD và chỉnh sửa file user_logic.vhd như trên đâu.
                          LCD thì vào trang này tìm hiểu thêm nhé
                          Code:
                          http://svenand.blogdrive.com/comments?id=62

                          Comment


                          • #28
                            Dùng picoblaze (một microcontroller core) để hiển thị LCD. Bạn vào website http://www.friendlykit.com để download chương trình

                            Comment


                            • #29
                              bác kamejoko80 cho em hỏi chút:
                              ở phần "data with of each register" bác chọn là 8.Như vậy slv_reg0 của bác là từ 0...7
                              nếu bác gán: lcd_port <= slv_reg0; thì liệu có làm sao ko?

                              Comment


                              • #30
                                Em hiểu rùi,chắc là vẫn được.Nó sẽ gán các bit thấp của slv_reg0 cho lcd_port_pin.
                                Còn 1 vấn đề nhỏ nữa em muốn hỏi bác:
                                hàm wait_us(n) của bác.Hàm này do bác tự viết ra,chứ ko phải do Xilinx tạo ra.Viết như vậy liệu nó có hiểu được mình định delay bao nhiêu ko?và lệnh for() của bác thì mỗi lần biến i,j tăng lên thì phụ thuộc vào clock nào ah.
                                Em cũng đọc các tutorial của xilinx nhưng chưa thấy có tutorial nào viết về đoạn lập trình C này cả.Bác có tài liệu nào ko ah.share cho em tham khảo với.Em cũng đang làm về giao tiếp lcd,Erthenet.Có j khó khăn mong bác chỉ giáo

                                Comment

                                Về tác giả

                                Collapse

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

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

                                Collapse

                                Đang tải...
                                X