|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 木子 于 2020-5-26 23:35 编辑
.\Objects\TEST.axf: Error: L6200E: Symbol fs multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol fileinfo multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol dir multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol FILE_TYPE_TBL multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol file multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol ftemp multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol br multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol bw multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol fatbuf multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol char_upper multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol exf_getfree multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol exfuns_init multiply defined (by exfuns.o and user.o).
.\Objects\TEST.axf: Error: L6200E: Symbol f_typetell multiply defined (by exfuns.o and user.o).
Not enough information to list image symbols.
上面是错误信息。
说在exfuns 和 user里面重复定义了。但是没有在user里面定义,只是包含了exfuns的头文件这是怎么回事呢?
/*************************************************************************************************/
exfuns.c内容
#include "string.h"
#include "exfuns.h"
#include "fattester.h"
#include "malloc.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////
//FATFS 扩展代码
//STM32F4工程模板-库函数版本
//淘宝店铺:http://mcudev.taobao.com
//////////////////////////////////////////////////////////////////////////////////
#define FILE_MAX_TYPE_NUM 7 //最多FILE_MAX_TYPE_NUM个大类
#define FILE_MAX_SUBT_NUM 4 //最多FILE_MAX_SUBT_NUM个小类
//文件类型列表
u8*const FILE_TYPE_TBL[FILE_MAX_TYPE_NUM][FILE_MAX_SUBT_NUM]=
{
{"BIN"}, //BIN文件
{"LRC"}, //LRC文件
{"NES"}, //NES文件
{"TXT","C","H"}, //文本文件
{"WAV","MP3","APE","FLAC"},//支持的音乐文件
{"BMP","JPG","JPEG","GIF"},//图片文件
{"AVI"}, //视频文件
};
///////////////////////////////公共文件区,使用malloc的时候////////////////////////////////////////////
FATFS *fs[_VOLUMES];//逻辑磁盘工作区.
FIL *file; //文件1
FIL *ftemp; //文件2.
UINT br,bw; //读写变量
FILINFO fileinfo; //文件信息
DIR dir; //目录
u8 *fatbuf; //SD卡数据缓存区
///////////////////////////////////////////////////////////////////////////////////////
//为exfuns申请内存
//返回值:0,成功
//1,失败
u8 exfuns_init(void)
{
u8 i;
for(i=0;i<_VOLUMES;i++)
{
fs=(FATFS*)mymalloc(SRAMIN,sizeof(FATFS)); //为磁盘i工作区申请内存
if(!fs)break;
}
file=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //为file申请内存
ftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //为ftemp申请内存
fatbuf=(u8*)mymalloc(SRAMIN,512); //为fatbuf申请内存
if(i==_VOLUMES&&file&&ftemp&&fatbuf)return 0; //申请有一个失败,即失败.
else return 1;
}
//将小写字母转为大写字母,如果是数字,则保持不变.
u8 char_upper(u8 c)
{
if(c<'A')return c;//数字,保持不变.
if(c>='a')return c-0x20;//变为大写.
else return c;//大写,保持不变
}
//报告文件的类型
//fname:文件名
//返回值:0XFF,表示无法识别的文件类型编号.
// 其他,高四位表示所属大类,低四位表示所属小类.
u8 f_typetell(u8 *fname)
{
u8 tbuf[5];
u8 *attr='\0';//后缀名
u8 i=0,j;
while(i<250)
{
i++;
if(*fname=='\0')break;//偏移到了最后了.
fname++;
}
if(i==250)return 0XFF;//错误的字符串.
for(i=0;i<5;i++)//得到后缀名
{
fname--;
if(*fname=='.')
{
fname++;
attr=fname;
break;
}
}
strcpy((char *)tbuf,(const char*)attr);//copy
for(i=0;i<4;i++)tbuf=char_upper(tbuf);//全部变为大写
for(i=0;i<FILE_MAX_TYPE_NUM;i++) //大类对比
{
for(j=0;j<FILE_MAX_SUBT_NUM;j++)//子类对比
{
if(*FILE_TYPE_TBL[j]==0)break;//此组已经没有可对比的成员了.
if(strcmp((const char *)FILE_TYPE_TBL[j],(const char *)tbuf)==0)//找到了
{
return (i<<4)|j;
}
}
}
return 0XFF;//没找到
}
//得到磁盘剩余容量
//drv:磁盘编号("0:"/"1:")
//total:总容量 (单位KB)
//free:剩余容量 (单位KB)
//返回值:0,正常.其他,错误代码
u8 exf_getfree(u8 *drv,u32 *total,u32 *free)
{
FATFS *fs1;
u8 res;
u32 fre_clust=0, fre_sect=0, tot_sect=0;
//得到磁盘信息及空闲簇数量
res =(u32)f_getfree((const TCHAR*)drv, (DWORD*)&fre_clust, &fs1);
if(res==0)
{
tot_sect=(fs1->n_fatent-2)*fs1->csize; //得到总扇区数
fre_sect=fre_clust*fs1->csize; //得到空闲扇区数
#if _MAX_SS!=512 //扇区大小不是512字节,则转换为512字节
tot_sect*=fs1->ssize/512;
fre_sect*=fs1->ssize/512;
#endif
*total=tot_sect>>1; //单位为KB
*free=fre_sect>>1; //单位为KB
}
return res;
}
/**********************************************************************************************/
exfuns.h里的内容
#ifndef _EXFUNS_H
#define _EXFUNS_H
#include <stm32f4xx.h>
#include "ff.h"
//////////////////////////////////////////////////////////////////////////////////
//FATFS 扩展代码
//STM32F4工程模板-库函数版本
//淘宝店铺:http://mcudev.taobao.com
//////////////////////////////////////////////////////////////////////////////////
extern FATFS *fs[_VOLUMES];
extern FIL *file;
extern FIL *ftemp;
extern UINT br,bw;
extern FILINFO fileinfo;
extern DIR dir;
extern u8 *fatbuf;//SD卡数据缓存区
//f_typetell返回的类型定义
//根据表FILE_TYPE_TBL获得.在exfuns.c里面定义
#define T_BIN 0X00 //bin文件
#define T_LRC 0X10 //lrc文件
#define T_NES 0X20 //nes文件
#define T_TEXT 0X30 //.txt文件
#define T_C 0X31 //.c文件
#define T_H 0X32 //.h文件
#define T_WAV 0X40 //WAV文件
#define T_MP3 0X41 //MP3文件
#define T_APE 0X42 //APE文件
#define T_FLAC 0X43 //FLAC文件
#define T_BMP 0X50 //bmp文件
#define T_JPG 0X51 //jpg文件
#define T_JPEG 0X52 //jpeg文件
#define T_GIF 0X53 //gif文件
#define T_AVI 0X60 //avi文件
u8 exfuns_init(void); //申请内存
u8 f_typetell(u8 *fname); //识别文件类型
u8 exf_getfree(u8 *drv,u32 *total,u32 *free); //得到磁盘总容量和剩余容量
u32 exf_fdsize(u8 *fdname); //得到文件夹大小
#endif
/************************************************************************************************/
user.c里的内容
#include "exfuns.c"
#include "user.h"
#include "lcd.h"
#include "DS1302.h"
#include "gui.h"
#include "usart.h"
#include "DS18B20.h"
#include "sdio_sdcard.h"
#include "ff.h"
#include "malloc.h"
#include "w25qxx.h"
#include "delay.h"
#include "diskio.h"
/*****************************************************************************
* @name :void lcd_time(int x,int y)
* @date :2020-05-18
* @function :时间显示函数
* @parameters :int x x方向坐标
int y y方向坐标
* @retvalue :None
******************************************************************************/
void lcd_time(int x,int y)
{ DS1302_GetTime();
// LCD_direction(1);//调整屏方向
LCD_ShowNum2 (x,y,BLUE,WHITE,TimeData .year ,4,16);
Show_Str (x+=32,y,BLUE,YELLOW,"--",32,1);
LCD_Show2Num (x+=16,y,BLUE,WHITE,TimeData .month ,2,16);
Show_Str (x+=16,y,BLUE,WHITE,"--",16,0);
LCD_Show2Num (x+=16,y,BLUE,WHITE,TimeData .day ,2,16);
Show_Str (x+=16,y,BLUE,WHITE," ",16,0);
LCD_Show2Num (x+=8,y,BLUE,WHITE,TimeData .hour ,2,16);
Show_Str (x+=16,y,BLUE,WHITE,":",16,1);
LCD_Show2Num (x+=8,y,BLUE,WHITE,TimeData .minute ,2,16);
Show_Str (x+=16,y,BLUE,YELLOW,":",16,1);
LCD_Show2Num (x+=8,y,BLUE,WHITE,TimeData .second ,2,16);
Show_Str (x+=16,y,BLUE,YELLOW," ",16,1);
LCD_ShowNum2 (x+=8,y,BLUE,WHITE,TimeData .week ,2,16);
}
/*****************************************************************************
* @name :void usart_ds1302(void)
* @date :2020-05-18
* @function :串口调整时间
* @parameters :串口数据发送格式,2020051813140003t以回车结尾
* @retvalue :None
******************************************************************************/
void usart_ds1302()
{ u8 time_buf[8],time_buf1[8];
u8 len, i,t,times;
if(USART_RX_STA&0x8000)//判断是否有信息发送
{
len=USART_RX_STA&0x3fff;//发送信息的长度
//printf("\r\n你发送的为:\r\n\r\n");
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART_RX_BUF[t]);//接收串口信息并发回
time_buf[t]=USART_RX_BUF[t];
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
//下面为数组分拆合并如0x32,0x30分拆并组合为0x20
for(i=0;i<len/2;)
{
time_buf1=time_buf[i*2]<<4;//取8位中的低4位,如0x32变为0x20,
time_buf1=time_buf1|(time_buf [i*2+1]&0x0f);//将上面取的低4为和这里的低4位合,如0x20和0x01变为0x21
//(time_buf [i*2+1]&0x0f)此公式为将高4位置0,低4位不变,如0x31变为0x01;
USART_SendData(USART1 ,time_buf1);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
i++;
}
if(time_buf[len-1]==0X74)//如果到数第二位为t则调整时间
DS1302_WriteTime(time_buf1);
USART_RX_STA=0;
}
else
{
times++;
if(times%5000==0)
{
printf("\r\n??STM32??? ????\r\n");
printf("????@ALIENTEK\r\n\r\n");
}
}
delay_ms(800);
}
/*****************************************************************************
* @name :void lcd_ds18b20(int x,int y)
* @date :2020-05-18
* @function :时间显示函数
* @parameters :int x x方向坐标
int y y方向坐标
* @retvalue :None
******************************************************************************/
void lcd_ds18b20(int x,int y)
{ float go_num=0;
float temp1[2];
DS18B20_Get_Temp(temp1,go_num,1);//取温度还没有弄明白
LCD_ShowNumF(x,y,RED,WHITE,temp1[1],temp1[0],3,16);
}
/*****************************************************************************
* @name :void get_sdfree(void)
* @date :2020-05-18
* @function :获取SD卡容量
* @parameters :None
* @retvalue :None
******************************************************************************/
void get_sdfree()
{
u8 res=0;
u32 total,sdfree;
while(exf_getfree("0",&total,&sdfree)) //得到SD卡的总容量和剩余容量
{
LCD_ShowString(30,150,16,"SD Card Fatfs Error!",0);
printf("sd card fatfs error\r\n");
delay_ms(200);
LCD_Fill(30,150,240,150+16,WHITE); //清除显示
delay_ms(200);
// LED0=!LED0;//DS0闪烁
}
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(30,150,16,"FATFS OK!",0);
LCD_ShowString(30,170,16,"SD Total Size: MB",0);
LCD_ShowString(30,190,16,"SD Free Size: MB",0);
printf ("fatfs ok\r\n");
LCD_ShowNum(30+8*14,170,total>>10,5,16); //显示SD卡总容量 MB
LCD_ShowNum(30+8*14,190,sdfree>>10,5,16); //显示SD卡剩余容量 MB
printf("sd total size %d MB\r\n",total>>10);
printf("sd free size %d MB\r\n",sdfree>>10);
}
/*****************************************************************************
* @name :void write_sd(int x,int y)
* @date :2020-05-18
* @function :写数据到SD卡
* @parameters :int x x方向坐标
int y y方向坐标
* @retvalue :None
******************************************************************************/
//BYTE READBUFFER[1024]={0};
void write_sd(u8 first,BYTE *WRITEBUFFER)
{
u8 res;
UINT fnum;
FIL fsrc;//文件对象
FIL fsrcend;
//FATFS fs;
res=f_mount(fs[0],"0:",1); //挂载SD卡
if(first==0)//如果没有被格式过则将SD卡格式化
{res=f_mkfs("0:",1,4096);//格式化FLASH,1,盘符;1,不需要引导区,8个扇区为1个簇
if(res==0)
{
f_setlabel((const TCHAR *)"0:mcudev"); //设置Flash磁盘的名字为:ALIENTEK
LCD_ShowString(30,150,16,"Flash Disk Format Finish",0); //格式化完成
printf("sd disk format finish\r\n");
}else
{
LCD_ShowString(30,150,16,"Flash Disk Format Error ",0); //格式化失败
printf("sd disk format error\r\n");
delay_ms(1000);
}
}
res=f_open (&fsrc,"0:/你好.txt",FA_OPEN_EXISTING|FA_WRITE );//创建一个文件,如果存在就打开
if(res==0x00)
{
f_lseek(&fsrc,fsrc.fptr+fsrc.fsize);
f_write(&fsrc, WRITEBUFFER, sizeof(WRITEBUFFER), &fnum);
}
else
{
res=f_open (&fsrc,"0:/你好.txt",FA_CREATE_ALWAYS|FA_WRITE );
if(res==FR_OK)
{ LCD_ShowString (30,210,16,"OPEN WORD OK!",0);
printf("open word ok\r\n");
res=f_write(&fsrc ,WRITEBUFFER ,sizeof(WRITEBUFFER ),&fnum);
if(res==FR_OK)
{
printf("文件写入成攻,写入字节数据:%d\r\n",fnum);
printf("写入的数据为:\r\n%s\r\n",WRITEBUFFER);
LCD_ShowString (30,230,16,WRITEBUFFER,0);
}
}
}
f_close (&fsrc);//关闭文件
f_mount(NULL,"0:",1);//卸载SD卡
}
/*********************************************************************************************************************/
user.h里的内容
#ifndef _USER_H
#define _USER_H
//#include "sys.h"
void lcd_ds1302(int x,int y);
void lcd_ds18b20(int x,int y);
void usart_ds1302(void);
#endif
请大神指教。。。。。
|
|