<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> STM32 >> 瀏覽文章

        STM32F4 Discovery + FreeRTOS + 中文字庫 + 12864LCD

        作者:c_gao   來源:轉的   點擊數:  更新時間:2014年06月25日   【字體:
        通過幾天時間空余時間研究,將FreeRTOS移植到了STM32 Discovery的板子上,并將以前自己做的中文字庫解析和簡易電子書閱讀的程序移植過來.同時采用了SPI接口的12864 OLED液晶屏.再加上板載的幾個LED控制以及板載User Button按鈕控制電子書向下翻頁. 通過配置USART1連接串口藍牙模塊和我的老本本Thinkpad T40p通信.先上圖:


        FreeRTOS的移植我是基于FreeRTOS最新官方7.5.2版的Demo: CORTEX_M4F_STM32F407ZG-SK 移植的.不過這個Demo里的RCC,PLL,HSE等相關配置不符合STM32 Discovery的實際情況,我重新用ST公司官方提供的system_stm32f4xx.c重新替換實現,同時去掉了Demo里的除LED任務外的所有其它任務,并修改中斷等其它配置.重新自己寫了幾個Task實現自己的要求.

        這里提一下,網上流傳甚廣的12864的SPI驅動是有問題的.主要表現在一個重要的設置坐標的函數,錯誤版本代碼如下:

        void LCD_Set_Pos(unsigned char x, unsigned char y)
        {
            LCD_WrCmd(0xb0+y);
            LCD_WrCmd((x&0x0f)|0x01);       //0000 1111
            LCD_WrCmd(((x&0xf0)>>4)|0x10);//0001 1111
        }
        使用這個函數明顯的錯誤發生在x的坐標定位會出問題,比如當你使用LCD_Set_Pos(126,0)和LCD_Set_Pos(127,0)時效果是一樣的,都定位到(126,0)位置,無法點亮x=127這最后一列的像素.結果通過查看12864控制芯片的硬件文檔找到原因:


        文檔明確表示,x坐標的設置將坐標字節的低4位直接寫入,將D4位置1后再將坐標字節的高4位一起寫入設置.而上面的代碼中:
        LCD_WrCmd((x&0x0f)|0x01);       //0000 1111
        顯然畫蛇添足,應改為:
        LCD_WrCmd(x&0x0f);
        即可.

        另外, 由于12864的控制芯片內的顯存是按位進行素像迭制的,并且寫入顯存時還得按節字為單位進行.實際程序中非常不方便進行單像素的隨意控制.為此,我寫了個中間層,這個中間層對每個像素按字節操作,GUI操作都在位于內存中開辟的中間層顯存中進行.然后渲染到屏上去時再轉換成為控制芯片要求的格式.

        代碼如下:
        [1]. hal_lcd.h
        #ifndef HAL_LCD_H
        #define HAL_LCD_H

        #include

        #define LCD_WIDTH   128
        #define LCD_HEIGHT  64
        #define PIXEL_PER_BYTE      8
        #define LOG_PIXEL_PER_BYTE  3

        #define USE_LOG_WIDTH_32  5
        #define USE_LOG_WIDTH_64  6
        #define USE_LOG_WIDTH_128 7
        #define USE_LOG_WIDTH_256 8

        #define CUR_LOG_WIDTH USE_LOG_WIDTH_128

        #define BIT(n)  (1<<(n))

        extern unsigned char hal_lcd_buff[LCD_WIDTH*LCD_HEIGHT];
        extern unsigned char lcd_buff[(LCD_WIDTH*LCD_HEIGHT)>>LOG_PIXEL_PER_BYTE];
        extern unsigned long render_count;

        inline void set_pixel(int x, int y, unsigned char clr)
        {
          hal_lcd_buff[(y<<CUR_LOG_WIDTH)+x]=clr;
        }

        inline unsigned char get_pixel(int x, int y)
        {
          return hal_lcd_buff[(y<<CUR_LOG_WIDTH)+x];
        }

        inline void clear_hal_lcd_buff()
        {
          int num = LCD_WIDTH*LCD_HEIGHT;
          for(int i=0; i
            hal_lcd_buff[i]=0;
        }

        inline void clear_lcd_buff()
        {
          int num = (LCD_WIDTH*LCD_HEIGHT)>>LOG_PIXEL_PER_BYTE;
          for(int i=0; i
            lcd_buff[i]=0;
        }

        inline void clear_buff()
        {
          clear_hal_lcd_buff();
          clear_lcd_buff();
        }

        void DrawCharacter10(unsigned char color);
        void GenLcdBuff();
        void RenderBuff();
        void Render();

        #endif

        [2]. hal_lcd.c
        #include "hal_lcd.h"
        #include "LQ12864.h"
        #include "gb_10_zhi.h"
        #include "5_7font.h"
        #include "mylife_txt.h"

        unsigned char hal_lcd_buff[LCD_WIDTH*LCD_HEIGHT];
        unsigned char lcd_buff[(LCD_WIDTH*LCD_HEIGHT)>>LOG_PIXEL_PER_BYTE];
        unsigned long render_count=1;

        #define ASC_COUNT            95    //????
        #define ASC_START                32    //????
        #define ASC_WIDTH                  //???????(??)
        #define ASC_HEIGHT                  //???????(??)
        #define ROW_SPACE                  //???(??)
        #define COL_SPACE                  //???(??)
        #define TAB_SPACE_NUM          //??TAB?????????

        #define CN_CHAR_HEIGHT        10//??????
        #define CN_CHAR_WIDTH        10//??????


        void GenLcdBuff()
        {
          int x,y,k;
          unsigned char dist_byte;
          int start_y,end_y;
          int i;
          int ii=0;
          for(y=0; y<(LCD_HEIGHT>>LOG_PIXEL_PER_BYTE); y++)
          {
            for(x=0; x
            {
              dist_byte = 0;
              start_y = (y<<LOG_PIXEL_PER_BYTE);
              end_y = start_y + PIXEL_PER_BYTE;
              for(i=0,k=start_y; k
              {
                if(get_pixel(x,k))
                  dist_byte |= BIT(i);
              }
              lcd_buff[ii++]=dist_byte;
            }
          }
        }

        void RenderBuff()
        {
          Draw_BMP(0,0,127,7,lcd_buff);
        }

        void Render()
        {
          GenLcdBuff();
          Draw_BMP(0,0,127,7,lcd_buff);
        }

        char* file;//file pointer
        unsigned int nFilePosition;
        unsigned int nOffset;

        static void memcpy(void* dst, const void* src, unsigned int count)
        {
          unsigned char* cdst = (unsigned char*)dst;
          unsigned char* csrc = (unsigned char*)src;
          int i=0;
          while((i++)
            *(cdst++) = *(csrc++);
        }

        int DrawASC(int nRow,int nCol,int nIndex,unsigned char color)
        {
            if( nIndex == ' ' - ASC_START ) //?????,??,????3,????,?????????,??????
                return 3;
               
            int nWidth=0;
            if(nIndex > ASC_COUNT || nIndex < 0)
                return nWidth;
            unsigned char * pLocation=nAsciiDot+nIndex*ASC_WIDTH;
            unsigned char * ptemp=NULL;
            //int n=0;
            int i=0,j=0;
            int row=nRow,col=nCol;
            //uint16 color=RGB15(31,31,31)|BIT(15);
           
            for(i=0; i
            {
                ptemp=pLocation+i;
                for(j=0; j
                {
                    if( (*ptemp)&BIT(ASC_WIDTH-j-1) )
                    {
                        set_pixel(col,row,color);
                        if( j > nWidth)
                            nWidth=j;
                    }
                    //else //???
                    //    putpixel_FB(row,col,RGB15(31,0,0)|BIT(15),buffer);
                    col++;
                }
                col=nCol;
                row++;
            }
            if(    nIndex == '!'-ASC_START ||
                    nIndex == ','-ASC_START ||
                    nIndex == '.'-ASC_START ||
                    nIndex == '?'-ASC_START ||
                    nIndex == '"'-ASC_START ||
                    nIndex == ';'-ASC_START ||
                    nIndex == ':'-ASC_START )
                    return ASC_WIDTH;
            else
                return nWidth+1;
        }

        typedef struct tag_Pos
        {
            int row;
            int col;
        } Pos;

        void DrawCharacter10(unsigned char color)
        {
            char bDual=0;
            unsigned char cnChar[2];
           
            unsigned int nSection;
            unsigned int nPosition;

            int xx=0;
            int yy=0;
           
            file=(char*)(mylife_txt+nFilePosition);
            char* pStr=file;
           
            unsigned int nIndex=0;//gb_10_zhi_size;abcdef
           
            cnChar[0]=pStr[nIndex++];
           
            unsigned int nLen=mylife_txt_size;//strlen(pStr);
           
            while(nFilePosition+nIndex < nLen && yy < LCD_HEIGHT-CN_CHAR_HEIGHT)
            {
                if(cnChar[0] & BIT(7))
                {
                    cnChar[1]=pStr[nIndex++];
                    bDual=1;
                }
                else
                    bDual=0;
               
                if(bDual)
                {
                    nSection=( (cnChar[0]-0xA0) & 0x7f ) -1;
                    nPosition=(cnChar[1]-0xA0) & 0x7f;
                   
                    long nOffset=(nSection*94+nPosition)*13;//((9*94)+1)*13+k*13;//
                   
                   
                    unsigned char font[13];
                    memcpy(font,gb_10_zhi+nOffset,13);
                   
                   
                    int i=0;
                    int j=0;
                    int x=0,y=0;
                    for(i=0; i<10; i++)
                    {
                        for(j=0; j<8; j++)
                        {
                            if(font[i] & BIT(j))
                            {
                                x=xx+8-j-1;//(i*8+j);
                                y=i;//(i*8+j)/12;
                                set_pixel(x,yy+y,color);
                            }
                        }
                    }
                   
                    for(i=10; i<13; i++)
                    {
                        for(j=0; j<8; j++)
                        {
                            if(font[i] & BIT(j))
                            {
                                x=xx+8+(2-j%2-1);
                                y=4*(i-9)-j/2-1;//(i-10)*4+j/2;
                                set_pixel(x,yy+y,color);
                            }
                        }
                    }
                   
                    xx+=(CN_CHAR_WIDTH+COL_SPACE);
                }
                else
                {
                    if(cnChar[0] == 0x0D && nIndex < nLen-1)
                    {
                        cnChar[1]=pStr[nIndex++];
                        if(cnChar[1]== 0x0A)
                        {
                            yy+=(CN_CHAR_HEIGHT+ROW_SPACE);
                            xx=0;
                        }
                           
                    }
                    else
                    {
                        switch(cnChar[0])
                        {
                        case '\n':
                            xx=0;
                            yy+=(CN_CHAR_HEIGHT+ROW_SPACE);
                            break;
                        case '\t'://???????,????4???
                        {
                            if(xx < LCD_WIDTH)
                            {
                                xx=xx+TAB_SPACE_NUM*(CN_CHAR_WIDTH+ROW_SPACE);
                                if(xx >= LCD_WIDTH)
                                {
                                    yy+=(CN_CHAR_HEIGHT+ROW_SPACE);
                                    xx=0;
                                }
                            }
                            break;
                        }
                        default:
                            xx+=DrawASC(yy+(CN_CHAR_HEIGHT-ASC_HEIGHT),xx,cnChar[0]-ASC_START,color);
                            xx+=COL_SPACE;
                            break;
                        }//switch
           
                    }
                }
               
                cnChar[0]=pStr[nIndex++];
               
                nOffset=nIndex-1;
               
                if(xx+CN_CHAR_WIDTH >= LCD_WIDTH)
                {
                    yy+=(CN_CHAR_HEIGHT+ROW_SPACE);
                    xx=0;
                }
               
            }

        }
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮