新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 文本LCD模塊的控制FPGA

        文本LCD模塊的控制FPGA

        作者: 時間:2023-12-22 來源:電子森林 收藏

        文本便宜且易于使用微控制器或進行接口。

        本文引用地址:http://www.104case.com/article/202312/454184.htm

        這是一個1行x 16個字符的模塊:

        要控制,您需要11個IO引腳來驅動8位數據總線和3個控制信號。3個控制信號是:

        • E:啟用或“ LCD選擇”。高活躍。
        • 讀/寫:讀/寫。0寫入,1讀取。
        • RS:寄存器選擇,0表示命令字節,1表示數據字節。

        大多數都基于HD44780芯片或是兼容的。查閱Wikipedia以獲取更多信息。

        7位設計

        讓我們用板驅動LCD模塊。
        這是我們設計的框圖:

        Pluto從PC串行端口接收數據,對其進行反序列化,然后將其發送到LCD模塊。解串器與串行接口項目中的模塊相同,因此此處僅對其進行實例化。

        module LCDmodule(clk, RxD, LCD_RS, LCD_RW, LCD_E, LCD_DataBus);
        input clk, RxD;
        output LCD_RS, LCD_RW, LCD_E;
        output [7:0] LCD_DataBus; 
        wire RxD_data_ready;
        wire [7:0] RxD_data;
        async_receiver deserializer(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));

        每當串行端口提供一個字節時,“ RxDdataready”將在一個時鐘周期內處于活動狀態。
        PC通過串口以8位模式向我們發送數據。理想情況下,我們需要從PC接收9位,以便我們可以驅動8位數據總線和LCD模塊的“ RS”線?,F在,讓我們使用接收到的數據的MSB(第7位)來驅動“ RS”,并將僅7位發送到數據總線。

        assign LCD_RS = RxD_data[7];
        assign LCD_DataBus = {1'b0, RxD_data[6:0]};   
        // sends only 7 bits to the module, padded with a '0' in front to make 8 bits 
        assign LCD_RW = 0;

        我們從不讀取LCD模塊,所以R / W線是接地的。

        最后一個麻煩是“ E”信號需要長時間激活,即220ns。從的角度來看,這很長,因為我使用的是25MHz時鐘(周期為40ns)。因此,“ E”至少需要驅動5.5個時鐘。在這里,我們使用一個計數器對時鐘進行計數,將其驅動7個時鐘。

        reg [2:0] count;
        always @(posedge clk) if(RxD_data_ready | (count!=0)) count <= count + 1;

        “ E”信號是通過寄存器創建的,因此可以保證無干擾。

        reg LCD_E;
        always @(posedge clk) LCD_E <= (count!=0);

        波形如下所示:

        HDL設計在這里。

        軟件方面

        我們對LCD進行初始化并發送一些要顯示的數據。

        以下是初始化LCD模塊并顯示“ hello”的C代碼。

        void main(){
          OpenComm();   // initialize the LCD module
          WriteCommByte(0x38);   // "Function Set" in 8 bits mode
          WriteCommByte(0x0F);   // "Display ON" with cursors ON
          WriteCommByte(0x01);   // "Clear Display", can take up to 1.64ms, so the delay
          Sleep(2);   // display "hello"
          WriteCommByte('h' + 0x80);
          WriteCommByte('e' + 0x80);
          WriteCommByte('l' + 0x80);
          WriteCommByte('l' + 0x80);
          WriteCommByte('o' + 0x80); 
          CloseComm();
          }

        完整的代碼在這里。

        要獲取有關HD44780指令集的更多信息,請在此處檢查。

        8位設計

        主要缺點是較早的設計是我們僅向LCD數據總線發送7位。這是一個問題,因為無法再使用LCD模塊的設置DD RAM地址命令。

        一種簡單的解決方法是使用轉義符。我們選擇了字符0x00。

        新協議如下:

        • 要發送命令字節,請在其前面加上0x00。
        • 要發送數據字節,只需發送它,不需要前綴。

        新的C代碼是:

        void main(){
          OpenComm();   // initialize the LCD module
          WriteCommByte(0x00);  WriteCommByte(0x38);   // "Function Set" in 8 bits mode
          WriteCommByte(0x00);  WriteCommByte(0x0F);   // "Display ON" with cursors ON
          WriteCommByte(0x00);  WriteCommByte(0x01);   // "Clear Display", can take up to 1.64ms, so the delay
          Sleep(2); 
          WriteCommByte('h');
          WriteCommByte('e');
          WriteCommByte('l');
          WriteCommByte('l');
          WriteCommByte('o'); 
          WriteCommByte(0x00);  WriteCommByte(0xC0);   // go on second half of LCD
          WriteCommByte('e');
          WriteCommByte('v');
          WriteCommByte('e');
          WriteCommByte('r');
          WriteCommByte('y');
          WriteCommByte('o');
          WriteCommByte('n');
          WriteCommByte('e'); 
          CloseComm();
          }

        新的HDL代碼如下所示:

        module LCDmodule(clk, RxD, LCD_RS, LCD_RW, LCD_E, LCD_DataBus);
        input clk, RxD;output LCD_RS, LCD_RW, LCD_E;
        output [7:0] LCD_DataBus; 
        wire RxD_data_ready;
        wire [7:0] RxD_data;
        async_receiver deserialer(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data)); 
        assign LCD_RW = 0;assign LCD_DataBus = RxD_data; 
        wire Received_Escape = RxD_data_ready & (RxD_data==0);
        wire Received_Data = RxD_data_ready & (RxD_data!=0); reg [2:0] count;
        always @(posedge clk) if(Received_Data | (count!=0)) count <= count + 1; 
        // activate LCD_E for 6 clocks, so at 25MHz, that's 6x40ns=240ns
        reg LCD_E;
        always @(posedge clk)if(LCD_E==0)
          LCD_E <= Received_Data;
          else
          LCD_E <= (count!=6); 
          reg LCD_instruction;
          always @(posedge clk)if(LCD_instruction==0)
          LCD_instruction <= Received_Escape;
          else
          LCD_instruction <= (count!=7); 
          assign LCD_RS = ~LCD_instruction; 
          endmodule

        HD44780規范顯示,“ E”變低后,“ RS”必須在10ns內有效。因此,您會注意到這里“ E”僅被驅動6個時鐘,并且“ LCDinstruction”標志僅在時鐘7之后被復位,以提供25ns的空間。

        That's all folks!輪到您嘗試了。



        關鍵詞: FPGA LCD模塊

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 南丹县| 巴南区| 孙吴县| 开封市| 门头沟区| 泉州市| 巧家县| 历史| 郁南县| 循化| 西林县| 聊城市| 越西县| 迁安市| 大庆市| 额尔古纳市| 昌宁县| 富源县| 绥阳县| 邹城市| 乐至县| 岑溪市| 德州市| 杭锦后旗| 喀喇沁旗| 麻江县| 东明县| 新营市| 尼玛县| 江源县| 武宣县| 昌江| 潍坊市| 紫阳县| 门头沟区| 瑞昌市| 奉节县| 西宁市| 太谷县| 盐城市| 永嘉县|