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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4195|回復: 18
打印 上一主題 下一主題
收起左側

keilC51單片機怎么實現字節對齊?

  [復制鏈接]
回帖獎勵 15 黑幣 回復本帖可獲得 15 黑幣獎勵! 每人限 1 次
跳轉到指定樓層
樓主
ID:834913 發表于 2021-12-29 17:11 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
現在正常做一個任務是將一個BMP顯示程序從STM32移植到一個51內核的單片機上,下面是解析BMP的結構體 可以看到都用__packed關鍵字進行了一字節對齊
//BMP信息頭
typedef __packed struct
{
    DWORD biSize ;                   //說明BITMAPINFOHEADER結構所需要的字數。
    LONG  biWidth ;                   //說明圖象的寬度,以象素為單位
    LONG  biHeight ;           //說明圖象的高度,以象素為單位
    WORD  biPlanes ;           //為目標設備說明位面數,其值將總是被設為1
    WORD  biBitCount ;           //說明比特數/象素,其值為1、4、8、16、24、或32
    DWORD biCompression ;  //說明圖象數據壓縮的類型。其值可以是下述值之一:
        //BI_RGB:沒有壓縮;
        //BI_RLE8:每個象素8比特的RLE壓縮編碼,壓縮格式由2字節組成(重復象素計數和顏色索引);  
    //BI_RLE4:每個象素4比特的RLE壓縮編碼,壓縮格式由2字節組成
          //BI_BITFIELDS:每個象素的比特由指定的掩碼決定。
    DWORD biSizeImage ;//說明圖象的大小,以字節為單位。當用BI_RGB格式時,可設置為0  
    LONG  biXPelsPerMeter ;//說明水平分辨率,用象素/米表示
    LONG  biYPelsPerMeter ;//說明垂直分辨率,用象素/米表示
    DWORD biClrUsed ;           //說明位圖實際使用的彩色表中的顏色索引數
    DWORD biClrImportant ; //說明對圖象顯示有重要影響的顏色索引的數目,如果是0,表示都重要。
}BITMAPINFOHEADER ;

//BMP頭文件
typedef __packed struct
{
    WORD  bfType ;     //文件標志.只對'BM',用來識別BMP位圖類型
    DWORD bfSize ;           //文件大小,占四個字節
    WORD  bfReserved1 ;//保留
    WORD  bfReserved2 ;//保留
    DWORD bfOffBits ;  //從文件開始到位圖數據(bitmap data)開始之間的的偏移量
}BITMAPFILEHEADER;

//彩色表
typedef __packed struct
{
        BYTE    rgbBlue;                 /*指定藍色強度 */
        BYTE    rgbGreen;                                 /*指定綠色強度 */
        BYTE    rgbRed;                                         /*指定紅色強度 */
        BYTE    rgbReserved;                         /*保留,設置為0*/
} RGBQUAD;

//位圖信息頭
typedef __packed struct
{
        BITMAPFILEHEADER bmfHeader;
        BITMAPINFOHEADER bmiHeader;  
        RGBQUAD bmiColors[1];  
}BITMAPINFO;



但是keil51似乎不能這么做 我試過了其他方法 比如說偽指令#pragma pack(n) 也行不通 編譯器不能識別 這樣解析函數就無法正確解析BMP圖片了 所以想請教一下有了解BMP圖片或者字節對齊的大神我該怎么辦


下面是BMP解析函數
/*********************************************************************
* 名    稱:BmpDecode()
* 功    能:解碼BMP圖片
* 入口參數:address        地址        
* 出口參數:0x00           不是BMP位圖
*                 0x01           位圖大小不對
            0x02           讀取正確   
**********************************************************************/

u8 BmpDecode(u32 address)
{
    u8          readcount =0;         
        u8          rgb = 0;
        u8          color_byte =0;                                        /*顏色位數          */                                                
        u16         count = 0;                                                /*數據偏移值        */
        u16         uiTemp = 0;                            /*x軸方向像素總和   */
        u16         xpels = 0;                                                 /*x軸方向像素計數器 */
        u16         ypels = 0;                                                 /*y軸方向像素計數器 */
        u16         pageadd = 0;                    /*頁地址            */
        u32         countpix = 0;                                        /*x軸方向像素累加器 */

        BITMAPINFO *pbmp;                                                /*bmp文件頭指針     */
        DWORD       tmp_color,color;                        /*顏色值            */


               
   Read_BmpData(address);                            /* 讀取1024字節到jpg_buffer */
        
        
        pbmp = (BITMAPINFO*)jpg_buffer;                   /* 得到BMP的頭部信息        */
        if (pbmp->bmfHeader.bfType != 0x424d)                      /*如果不是BMP圖片           */
        {
            return 0x00;
        }
        else
        {
            count      = pbmp->bmfHeader.bfOffBits ;              /*數據偏移,得到數據段的開始地址*/
            color_byte = pbmp->bmiHeader.biBitCount/8;        /*彩色位 16/24/32              */

                PICINFO.ImgHeight = pbmp->bmiHeader.biHeight; /*得到圖片高度                                  */
            PICINFO.ImgWidth  = pbmp->bmiHeader.biWidth;  /*得到圖片寬度                                 */
               
                if(        PICINFO.ImgWidth != 140 || PICINFO.ImgHeight != 32)
                {
                    return 0x01;
                }
        

            if((PICINFO.ImgWidth*color_byte)%4)
                {
                    uiTemp = ((PICINFO.ImgWidth*color_byte)/4+1)*4;
                }
             else
                {
                    uiTemp = PICINFO.ImgWidth*color_byte;
                }



                rgb   = 0;
                xpels = 0;
                ypels = 0;
                pageadd = 0;
                readcount = 0;
                color = 0x00;
                memset(BMP_buffer,0,sizeof(BMP_buffer));
        
                while(1)
                {
                    while( count < 1024 )
                        {
                            if(color_byte == 3)                                  /*24位顏色圖                */
                                {
                                           switch (rgb)
                                        {
                                                case 0:
                                                        tmp_color = jpg_buffer[count]*0.299 ;
                                                        color += tmp_color;
                                                        break ;           
                                                case 1:
                                                        tmp_color = jpg_buffer[count]*0.587 ;                        
                                                        color += tmp_color ;
                                                        break;         
                                                case 2 :
                                                        tmp_color = jpg_buffer[count]*0.114 ;
                                                        color += tmp_color ;
                                                        break ;                        
                                        }
                                }
                                rgb++;
                                count++ ;

                                if(rgb == color_byte)                /*水平方向讀取到1像素數數據后放入緩沖區中*/
                                {
                                   xpels++;                          /*x軸增加一個像素                                */
                                   if(xpels <= PICINFO.ImgWidth)         /*如果未掃描完一行                                */
                                   {
                                         if(color > 255)  
                                     {
                             color = 0;  
                                     }
                         if(color < 0 )
                                                   {
                                           color = 255;   
                                               }
                                         if(color > 127)
                                             {
                                                 BMP_buffer[xpels-1] = BMP_buffer[xpels-1]| 1<<(ypels%8);
                                             }
                                   }
                                   color = 0x00;
                                   rgb   = 0;
                                }

                                countpix++;                                                   /*像素累加                             */

                                if(countpix >= uiTemp)                                        /*水平方向像素值到了.換行                 */
                                {
                                   ypels++;
                                   if(ypels%8 == 0)                                                              /*如果解碼一頁                                 */
                                   {
                                       LCD_PutBmp(pageadd,BMP_buffer);                        /*顯示到lcd                                     */
                                           memset(BMP_buffer,0,sizeof(BMP_buffer));
                                           pageadd++;
                                   }

                                   if(ypels >= PICINFO.ImgHeight)   
                                   {
                                       return 0x02 ;                                                   /*正常退出                                   */
                                   }

                                   xpels   = 0;
                                   countpix= 0;
                                   color   = 0x00;
                                   rgb     = 0;
                                }
                                
                        }
                        readcount++;
                        
                        Read_BmpData(address + readcount*1024);
                        count = 0 ;
                }
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:883242 發表于 2021-12-29 17:44 | 只看該作者
這么大的工作量是51這么ws的東西承擔不起的,先別考慮什么對齊問題,先把編譯搞通過了證明在51上面跑起來再想細節問題。
回復

使用道具 舉報

板凳
ID:313048 發表于 2021-12-29 17:48 | 只看該作者
51單片機能解析BMP圖片?
我記得是不能的吧,顯示圖片是沒問題的,直接從存儲器中讀取,可以是外掛FLASH啥的,串口接收的數據也可以,SD卡和USB好像不行,而且是需要你轉化為hex格式才行。
回復

使用道具 舉報

地板
ID:313048 發表于 2021-12-29 17:49 | 只看該作者
51單片機是8位機,所有不需要字節對齊,本身就是單字節對齊的。你這還去字節對齊就過于畫蛇添足了。
回復

使用道具 舉報

5#
ID:834913 發表于 2021-12-29 18:06 | 只看該作者
AUG 發表于 2021-12-29 17:48
51單片機能解析BMP圖片?
我記得是不能的吧,顯示圖片是沒問題的,直接從存儲器中讀取,可以是外掛FLASH啥 ...

用的是迪文的T5L 51內核的 計劃是將圖片數據讀取到flash 再從flash讀出來解析顯示 那就不是字節對齊的問題了 我再想想吧 謝謝回答
回復

使用道具 舉報

6#
ID:834913 發表于 2021-12-29 18:09 | 只看該作者
Hephaestus 發表于 2021-12-29 17:44
這么大的工作量是51這么猥瑣的東西承擔不起的,先別考慮什么對齊問題,先把編譯搞通過了證明在51上面跑起來 ...

謝謝回復 那我再想想
回復

使用道具 舉報

7#
ID:893997 發表于 2021-12-29 23:07 | 只看該作者
這程序跑不動啊,用增強型51都未必可以,運算量太大了
回復

使用道具 舉報

8#
ID:888298 發表于 2022-4-8 09:55 | 只看該作者
不萬能的喜劇 發表于 2021-12-29 18:06
用的是迪文的T5L 51內核的 計劃是將圖片數據讀取到flash 再從flash讀出來解析顯示 那就不是字節對齊的問 ...

這個平臺BMP最好是做成ICL,如果是實時顯示,最好用jpeg,你這種寫入flash的方法會損耗FLASH
回復

使用道具 舉報

9#
ID:982617 發表于 2022-4-13 17:42 | 只看該作者
程序可能太復雜了 試試精簡吧
回復

使用道具 舉報

10#
ID:1004160 發表于 2023-12-20 15:10 | 只看該作者
同樣遇到字節對齊的問題,估且算是吧。 問題就是:
回復

使用道具 舉報

11#
ID:1004160 發表于 2023-12-20 15:16 | 只看該作者
同樣遇到字節對齊的問題,問題就是:
漢字取模后,只有一個漢字無法顯示,這個漢字是“過”這個字。存在結構體中用漢字來當索引,檢索取模后的十六進制數。結構體如下:
typedef struct  
{
        unsigned char Index[2];
        unsigned char Msk[128];
}typFNT_GB32;
//#pragma pack()

const typFNT_GB32 code tfont32[]={
"未",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x81,0x01,0xC0,0xFF,
0xFF,0x03,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x0C,0xF8,0xFF,0xFF,0x1F,0x00,0xE0,0x03,0x00,
0x00,0xE0,0x05,0x00,0x00,0xB0,0x0D,0x00,0x00,0xB8,0x09,0x00,0x00,0x98,0x11,0x00,0x00,0x8C,0x31,0x00,0x00,0x86,0x61,0x00,0x00,0x83,0xC1,0x01,0x80,0x81,0x81,0x03,0x60,0x80,
0x01,0x0F,0x30,0x80,0x01,0x3E,0x08,0x80,0x01,0x0C,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,/*"未",0*/


通過分析發現,當結構內存儲的是“過”這個字的時候是無法顯示的。調試發現,Index[2]數組中的Index[1]取值不完整。如下:
k=10
indx0=0xd5
indx1=0xcf
k=11
indx0=0xb9
indx1=0x0
k=12
indx0=0xc7
indx1=0xb7

上邊的“k=11”這個就是“過”這個漢字的序號,打印出來后居然是“indx1=0x0”,缺少數據,正常應該是“indx1=0xfd”。即:indx0=0xb9,indx1=0xfd。正好對應GB2312碼表中“過”這個漢字十六進制編碼0xb9fd。

請各位大神指教,如何解決。問題是:只有這一個漢字這樣,其它漢字沒有問題。從上述打印出來的k=10、k=12的索引漢字就能看出來。
回復

使用道具 舉報

12#
ID:526108 發表于 2023-12-20 15:25 | 只看該作者
51沒有字節對齊概念,默認就是緊湊型的
回復

使用道具 舉報

13#
ID:883242 發表于 2023-12-20 16:19 | 只看該作者
xinwuhen 發表于 2023-12-20 15:16
同樣遇到字節對齊的問題,問題就是:
漢字取模后,只有一個漢字無法顯示,這個漢字是“過”這個字。存在結 ...

8位機哪來的對齊問題?
回復

使用道具 舉報

14#
ID:1101997 發表于 2023-12-21 09:07 | 只看該作者
風之痕于夢想 發表于 2021-12-29 23:07
這程序跑不動啊,用增強型51都未必可以,運算量太大了

32位肯定效率要高一些,不過迪文的OS核跑起來還是很快的,主頻好像是快300Mhz,指令周期基本都是1.
回復

使用道具 舉報

15#
ID:458247 發表于 2023-12-21 09:31 | 只看該作者
xinwuhen 發表于 2023-12-20 15:16
同樣遇到字節對齊的問題,問題就是:
漢字取模后,只有一個漢字無法顯示,這個漢字是“過”這個字。存在結 ...

你這個是keil c51的0xFDbug,你只要把index寫成"過\0xFD"就好了
回復

使用道具 舉報

16#
ID:1034262 發表于 2023-12-21 10:48 | 只看該作者
8位機沒有對齊問題,永遠都是對齊的。
回復

使用道具 舉報

17#
ID:1004160 發表于 2023-12-26 23:19 | 只看該作者
yzw846562238 發表于 2023-12-21 09:31
你這個是keil c51的0xFDbug,你只要把index寫成"過\0xFD"就好了

感謝,是這個問題。我采用了2種方案。一個是\xFD加在GBK碼低8位包含FD的漢字上。 另一種是,我直接修改了Keil51的C51.exe程序。 目前 采用了第2 種方案。一勞永逸。
回復

使用道具 舉報

18#
ID:1004160 發表于 2023-12-26 23:20 | 只看該作者
一并感謝各位大佬,后來查到問題的解決辦法了。\xFD加在無法顯示的漢字背后,以及修改Keil下的C51執行文件,自己改了后作為補丁打到了Keil程序里。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成人av一区二区亚洲精 | 欧美日韩亚洲系列 | 在线婷婷 | 国产高清视频在线观看播放 | 麻豆久久久9性大片 | 欧美在线观看一区 | 激情欧美一区二区三区中文字幕 | 欧美不卡在线 | 中国一级大毛片 | 日韩欧美中文在线 | 国产 日韩 欧美 制服 另类 | 久久久精品一区二区 | av免费观看在线 | 午夜精品一区二区三区在线播放 | 91大神在线资源观看无广告 | 精品一二三区视频 | 亚洲影音 | 国精产品一品二品国精在线观看 | 国产一区二区精品在线观看 | 久久久99国产精品免费 | 亚洲精品自拍视频 | 久久99国产精品 | 天天看天天摸天天操 | 在线国产视频 | 狠狠操av| 国产高清视频在线播放 | 成人国产精品一级毛片视频毛片 | 麻豆久久精品 | 国产片一区二区三区 | 一区二区三区视频在线观看 | 国产在线中文字幕 | 亚洲精品中文字幕在线 | 九色网址| 久久亚洲欧美日韩精品专区 | 视频一区中文字幕 | 亚洲精品一区二区三区四区高清 | 中文字幕免费中文 | 欧美人成在线视频 | 日韩中文字幕视频在线 | 国产一区二区三区四区 | 日韩www|