往SD卡里图片文件写bmp首部时,写不进去怎么回事

2019-08-11 17:53发布

本帖最后由 qweSSS 于 2017-10-22 17:10 编辑

程序如下:
int main()
{
        u8 i=0;
        u8 key;
        u8 lightmode=0,saturation=2,brightness=2,contrast=2;
        u8 effect=0;
        u8 sbuf[15];
        u8 count;
        u8 *pname;
        u8 res;
        u8 sd_ok=1;        
   char *g = "ashining";
        
        SysTick_Init(72);
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
        LED_Init();
        USART1_Init(9600);
        TFTLCD_Init();                        //LCD初始化
        KEY_Init();
        EN25QXX_Init();                                //初始化EN25Q128         
               
        FRONT_COLOR=RED;//设置字体为红 {MOD}
        FSMC_SRAM_Init();
        //my_mem_init(SRAMEX);         
        my_mem_init(SRAMIN);//初始化内部内存池
        FATFS_Init();
//         while(SD_Init())
//    {
//        LCD_ShowFont12Char(0, 126, "SD 卡初始化错误");   
//    }
                f_mount(fs[0],"0:",1);                 //挂载SD卡
                f_mount(fs[1],"1:",1);                 //挂载FLASH.

        res=f_mkdir("0:/PHOTO");                //创建PHOTO文件夹
                if(res!=FR_EXIST&&res!=FR_OK)         //发生了错误
        {                    
                LCD_ShowFont12Char(10, 80, "SD卡错误!");
                delay_ms(200);                                 
                sd_ok=0;         
        }         
                pname=mymalloc(SRAMIN,30);//为带路径的文件名分配30个字节的内存
                while(pname==NULL)
                {
                        LCD_ShowFont12Char(10, 80, "内存分配失败!");
                        delay_ms(200);
                        LCD_Fill(10,80,239,206,WHITE);
                        delay_ms(200);
                }
        
        LCD_ShowFont12Char(10, 50, "摄像头应用--OV7670");
        
        while(OV7670_Init())//初始化OV7670
        {
                LCD_ShowString(10,80,tftlcd_data.width,tftlcd_data.height,16,"OV7670 Error!");
                delay_ms(200);
                LCD_Fill(10,80,239,206,WHITE);
                delay_ms(200);
        }
         LCD_ShowString(10,80,tftlcd_data.width,tftlcd_data.height,16,"OV7670 OK!     ");
        delay_ms(1500);        
        
        OV7670_Light_Mode(0);
        OV7670_Color_Saturation(2);
        OV7670_Brightness(2);
        OV7670_Contrast(2);
         OV7670_Special_Effects(0);
               
        TIM4_Init(10000,7199);                        //10Khz计数频率,1秒钟中断                                                                          
        EXTI7_Init();                        
        OV7670_Window_Set(12,176,240,320);        //设置窗口        
          OV7670_CS=0;        
        LCD_Clear(BLACK);
        while(1)
        {
                key=KEY_Scan(0);
                if(key)
                {
                switch(key)
                {
                        case KEY_UP:           //灯光模式设置
                                        //        Vsync=1-Vsync;
                        if(sd_ok)
                        {
                                led1=0;//提示正在拍照
                                camera_new_pathname(pname,0);//得到文件名        
                                //send(pname);
//                                res=bmp_encode(pname,0,0,tftlcd_data.width,tftlcd_data.height,0);
                                        res=bmp_encode(pname,(tftlcd_data.width-320)/2,(tftlcd_data.height-240)/2,320,240,0);//height-240;width-320
                                if(res)//拍照有误
                                {
                                        LCD_ShowFont12Char(10, 80, "写入文件错误");                 
                                }else
                                {
                                        LCD_ShowFont12Char(10, 80, "拍照成功");
                                            
                                        delay_ms(100);
                                }                           
                        }
                        else
                        {
                                LCD_ShowFont12Char(10, 120, "SD卡错误!");
                        }

//////////////////////////////////////////////////////////////////////////////////////////////////////////
u8 bmp_encode(u8 *filename,u16 x,u16 y,u16 width,u16 height,u8 mode)
{                                
        FIL* f_bmp;
        u16 bmpheadsize;                        //bmp头大小                  
         BITMAPINFO hbmp;                        //bmp头         
        u8 res=0;
        u16 tx,ty;                                           //图像尺寸
        u16 *databuf;                                //数据缓存区地址                  
        u16 pixcnt;                                           //像素计数器
        u16 bi4width;                               //水平像素字节数           
        if(width==0||height==0)return PIC_WINDOW_ERR;        //区域错误
        if((x+width-1)>tftlcd_data.width)return PIC_WINDOW_ERR;                //区域错误
        if((y+height-1)>tftlcd_data.height)return PIC_WINDOW_ERR;        //区域错误
         
#if BMP_USE_MALLOC == 1        //使用malloc        
        databuf=(u16*)pic_memalloc(1024);                //开辟至少bi4width大小的字节的内存区域 ,对240宽的屏,480个字节就够了.
        if(databuf==NULL)return PIC_MEM_ERR;                //内存申请失败.
        f_bmp=(FIL *)pic_memalloc(sizeof(FIL));        //开辟FIL字节的内存区域
        if(f_bmp==NULL)                                                                //内存申请失败.
        {                 
                pic_memfree(databuf);
                return PIC_MEM_ERR;                                
        }         
#else
        databuf=(u16*)bmpreadbuf;
        f_bmp=&f_bfile;
#endif              
        bmpheadsize=sizeof(hbmp);//得到bmp文件头的大小   
        my_mem_set((u8*)&hbmp,0,sizeof(hbmp));//置零空申请到的内存.            
        hbmp.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);//信息头大小
        hbmp.bmiHeader.biWidth=width;                 //bmp的宽度
        hbmp.bmiHeader.biHeight=height;         //bmp的高度
        hbmp.bmiHeader.biPlanes=1;                         //恒为1
        hbmp.bmiHeader.biBitCount=16;                 //bmp为16位 {MOD}bmp
        hbmp.bmiHeader.biCompression=BI_BITFIELDS;//每个象素的比特由指定的掩码决定。
         hbmp.bmiHeader.biSizeImage=hbmp.bmiHeader.biHeight*hbmp.bmiHeader.biWidth*hbmp.bmiHeader.biBitCount/8;//bmp数据区大小
                                    
        hbmp.bmfHeader.bfType=((u16)'M'<<8)+'B';//BM格式标志
        hbmp.bmfHeader.bfSize=bmpheadsize+hbmp.bmiHeader.biSizeImage;//整个bmp的大小
           hbmp.bmfHeader.bfOffBits=bmpheadsize;//到数据区的偏移

        hbmp.RGB_MASK[0]=0X00F800;                         //红 {MOD}掩码
        hbmp.RGB_MASK[1]=0X0007E0;                         //绿 {MOD}掩码
        hbmp.RGB_MASK[2]=0X00001F;                         //蓝 {MOD}掩码

        if(mode==1)res=f_open(f_bmp,(const TCHAR*)filename,FA_READ|FA_WRITE);//尝试打开之前的文件
         if(mode==0||res==0x04)
                res=f_open(f_bmp,(const TCHAR*)filename,FA_WRITE|FA_CREATE_NEW);//模式0,或者尝试打开失败,则创建新文件                  
         if((hbmp.bmiHeader.biWidth*2)%4)//水平像素(字节)不为4的倍数
        {
                bi4width=((hbmp.bmiHeader.biWidth*2)/4+1)*4;//实际要写入的宽度像素,必须为4的倍数.        
        }else bi4width=hbmp.bmiHeader.biWidth*2;                //刚好为4的倍数         
         if(res==FR_OK)//创建成功
        {
                res=f_write(f_bmp,(u8*)&hbmp,bmpheadsize,&bw);//写入BMP首部  
                for(ty=y+height-1;hbmp.bmiHeader.biHeight;ty--)
                {
                        pixcnt=0;
                         for(tx=x;pixcnt!=(bi4width/2);)
                        {
                                if(pixcnt<hbmp.bmiHeader.biWidth)databuf[pixcnt]=LCD_ReadPoint(tx,ty);//读取坐标点的值
                                else
                                        databuf[pixcnt]=0Xffff;//补充白 {MOD}的像素.  
                                pixcnt++;
                                tx++;
                        }
                        //send(databuf);
                        hbmp.bmiHeader.biHeight--;
                        res=f_write(f_bmp,(u8*)databuf,bi4width,&bw);//写入数据
                }
                f_close(f_bmp);
                led8=!led8;
        }         
else
{
        led5=!led5;
}  
#if BMP_USE_MALLOC == 1        //使用malloc        
        pic_memfree(databuf);         
        pic_memfree(f_bmp);                 
#endif        
        return res;
}

像上面这样写图片数据与bmp首部都写不进去sd卡,要是在res=f_write(f_bmp,(u8*)&hbmp,bmpheadsize,&bw);//写入BMP首部  这里改为res=f_write(f_bmp,(u8*)&hbmp,bmpheadsize-1,&bw);的话,bmp首部写不进去但是下面的写图片数据函数可以写进去。这是哪里的问题啊。求大家给点意见  
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。