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

標題: keilC51單片機怎么實現字節對齊? [打印本頁]

作者: 不萬能的喜劇    時間: 2021-12-29 17:11
標題: keilC51單片機怎么實現字節對齊?
現在正常做一個任務是將一個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 ;
                }
        }
}


作者: Hephaestus    時間: 2021-12-29 17:44
這么大的工作量是51這么ws的東西承擔不起的,先別考慮什么對齊問題,先把編譯搞通過了證明在51上面跑起來再想細節問題。
作者: AUG    時間: 2021-12-29 17:48
51單片機能解析BMP圖片?
我記得是不能的吧,顯示圖片是沒問題的,直接從存儲器中讀取,可以是外掛FLASH啥的,串口接收的數據也可以,SD卡和USB好像不行,而且是需要你轉化為hex格式才行。
作者: AUG    時間: 2021-12-29 17:49
51單片機是8位機,所有不需要字節對齊,本身就是單字節對齊的。你這還去字節對齊就過于畫蛇添足了。
作者: 不萬能的喜劇    時間: 2021-12-29 18:06
AUG 發表于 2021-12-29 17:48
51單片機能解析BMP圖片?
我記得是不能的吧,顯示圖片是沒問題的,直接從存儲器中讀取,可以是外掛FLASH啥 ...

用的是迪文的T5L 51內核的 計劃是將圖片數據讀取到flash 再從flash讀出來解析顯示 那就不是字節對齊的問題了 我再想想吧 謝謝回答
作者: 不萬能的喜劇    時間: 2021-12-29 18:09
Hephaestus 發表于 2021-12-29 17:44
這么大的工作量是51這么猥瑣的東西承擔不起的,先別考慮什么對齊問題,先把編譯搞通過了證明在51上面跑起來 ...

謝謝回復 那我再想想
作者: 風之痕于夢想    時間: 2021-12-29 23:07
這程序跑不動啊,用增強型51都未必可以,運算量太大了
作者: iacyf    時間: 2022-4-8 09:55
不萬能的喜劇 發表于 2021-12-29 18:06
用的是迪文的T5L 51內核的 計劃是將圖片數據讀取到flash 再從flash讀出來解析顯示 那就不是字節對齊的問 ...

這個平臺BMP最好是做成ICL,如果是實時顯示,最好用jpeg,你這種寫入flash的方法會損耗FLASH
作者: hezezeze    時間: 2022-4-13 17:42
程序可能太復雜了 試試精簡吧
作者: xinwuhen    時間: 2023-12-20 15:10
同樣遇到字節對齊的問題,估且算是吧。 問題就是:
作者: xinwuhen    時間: 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的索引漢字就能看出來。
作者: 624353765    時間: 2023-12-20 15:25
51沒有字節對齊概念,默認就是緊湊型的
作者: Hephaestus    時間: 2023-12-20 16:19
xinwuhen 發表于 2023-12-20 15:16
同樣遇到字節對齊的問題,問題就是:
漢字取模后,只有一個漢字無法顯示,這個漢字是“過”這個字。存在結 ...

8位機哪來的對齊問題?
作者: nearsea    時間: 2023-12-21 09:07
風之痕于夢想 發表于 2021-12-29 23:07
這程序跑不動啊,用增強型51都未必可以,運算量太大了

32位肯定效率要高一些,不過迪文的OS核跑起來還是很快的,主頻好像是快300Mhz,指令周期基本都是1.
作者: yzw846562238    時間: 2023-12-21 09:31
xinwuhen 發表于 2023-12-20 15:16
同樣遇到字節對齊的問題,問題就是:
漢字取模后,只有一個漢字無法顯示,這個漢字是“過”這個字。存在結 ...

你這個是keil c51的0xFDbug,你只要把index寫成"過\0xFD"就好了
作者: coody_sz    時間: 2023-12-21 10:48
8位機沒有對齊問題,永遠都是對齊的。
作者: xinwuhen    時間: 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 種方案。一勞永逸。
作者: xinwuhen    時間: 2023-12-26 23:20
一并感謝各位大佬,后來查到問題的解決辦法了。\xFD加在無法顯示的漢字背后,以及修改Keil下的C51執行文件,自己改了后作為補丁打到了Keil程序里。




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 亚洲天堂一区 | 日韩一区二区三区视频 | 日韩在线播放一区 | 久久成人精品视频 | 一区二区成人 | 91亚洲一区 | 亚洲精品久久久久久久久久久 | 中文字幕一区二区三区乱码在线 | 亚洲国产自产 | 亚洲精品久久久久久下一站 | 久精品久久| 婷婷在线视频 | 欧美日韩精品一区 | 欧美日韩一二三区 | 在线成人 | 日本精品免费 | 亚洲女人天堂成人av在线 | 91 久久| 亚洲欧美在线一区 | 97超碰站| 精品在线一区二区三区 | 亚洲成人免费在线观看 | 日韩伦理一区二区 | 国产xxxx搡xxxxx搡麻豆 | 亚洲精品免费看 | 久久综合一区二区三区 | 久久久久久亚洲精品 | www.久久99| 国户精品久久久久久久久久久不卡 | 伊大人久久 | a视频在线观看 | 国产亚洲精品综合一区 | 久久99深爱久久99精品 | 国产亚韩 | 欧美天堂在线观看 | 婷婷成人在线 | a级免费视频 | 日日天天| 精品国产一区二区三区成人影院 | 在线观看国产视频 | 粉嫩高清一区二区三区 |