久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

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

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

作者:c_gao   來源:轉自c_gao   點擊數:  更新時間:2014年07月05日   【字體:
通過幾天時間空余時間研究,將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;
        }
       
    }

}
關閉窗口

相關文章

主站蜘蛛池模板: 欧洲一区在线观看 | 久久久久久av | av在线一区二区三区 | 国产精品美女www爽爽爽视频 | 久久久av | 欧美精品在线视频 | 99精品久久 | 亚洲一区免费在线 | 一级片网址 | 岛国av免费在线观看 | 久久国产一区二区三区 | 午夜理伦三级理论三级在线观看 | 欧美日韩亚洲一区 | 久久久久国产一区二区三区 | 欧美日韩亚洲视频 | 国产在线播 | 国产乱码久久久久久 | 一道本视频 | 视频精品一区 | 色综合天天天天做夜夜夜夜做 | 91精品一区二区三区久久久久久 | 国产在线一区二区三区 | 国产一区二区三区免费视频 | 成年免费大片黄在线观看一级 | 久久久久久免费精品一区二区三区 | 狠狠躁天天躁夜夜躁婷婷老牛影视 | 女同videos另类 | 97综合在线 | 精品久久久久久久久久久院品网 | 亚洲成av人片在线观看无码 | 正在播放亚洲 | 亚洲国产精品一区二区第一页 | 久草综合在线视频 | 天天拍天天射 | 嫩草影院网址 | 欧美日韩黄 | 中文字幕在线观看一区 | 在线a视频网站 | 国产精品女人久久久 | 国产探花 | 欧美在线视频a |