Build target 'Target 1'
compiling bian.c...
linking...
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
SYMBOL: T
MODULE: bian.obj (BIAN)
Program Size: data=63.0 xdata=0 code=2022
Target not created
编译完总出现以上错误,无法生成hex文件
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^0; //DS18B20通信端口
//sbit dula=P2^4; //数码管段选线
//sbit wela=P2^5; //数码管位选线
sbit BEE=P2^0; //蜂鸣器
char clear = 0xff;
sbit wela1=P2^7;
sbit wela2=P2^6;
sbit wela3=P2^5;
sbit wela4=P2^4;
sbit key2=P1^4; //DS18B20选择按键
sbit P11=P1^5; //报警上下限温度设置键
sbit P12=P1^6; //温度设置加1键
sbit P13=P1^7; //温度设置减1键
uchar code table[]={
0x3f,0x06,0x5b,0x4f, //共阴极数码管字型码
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x00};
uchar code table1[]={
0xbf,0x86,0xdb,0xcf, //共阴极数码管字型码,带小数点
0xe6,0xed,0xfd,0x87,
0xff,0xef,0x00};
uchar ba,sh,ge,aa;
uchar SN[3][8]; //3个DS18B20的序列号,先读出单个序列号填上才可以读取温度
uint temp1,T,t,xs,ID,keycon,max,min;
void display(uchar ba,uchar sh,uchar ge,uchar aa); //数码管温度显示子程序,PO口输出
void alarm(); //上下限蜂鸣器报警
void delayms(int z); //1ms延时子程序,延时时间以12MHz晶振为准1ms×z
void delay(unsigned int time); //20 延时子程序, 延时时间以12MHz晶振为准
//用于DS18B20初始化
void change_start(); //发送18b20开始转换命令
void readtemp(); //读取温度,判断键值j,0,1,2分别发送三个DS18B20的序列号.
void increase(); //加1子函数,进入上限或者下限温度设定,max,min加1会有不同的限制,由环境要求灵活设定。
void decrease(); //减1子函数
void rom(); //读取器件序列号的子程序,调用时确保总线中只有一只器件
void key(void); //上下限报警温度设置按键
void key_select(void); //选择要发送的DS18B20序列号,选择不同点的的传感器显示温度
void display1(int T); //上下限报警温度设定显示子程序,显示范围0℃~70℃,均为整数 */
/****************************************************************
函数名:delayms()
描述:1ms延时子程序,延时时间以12MHz晶振为准1ms×z
******************************************************************/
void delayms(int z)
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/****************************************************************
函数名:delay()
描述:20 延时子程序, 延时时间以12MHz晶振为准20 ×time
******************************************************************/
void delay(unsigned int time)
{
unsigned int n=2;
unsigned char m=2;
for (n=0;n<time;n++)
for(m=0;m<2;m++);
}
/****************************************************************
函数名:reset()
描述:用于DS18B20初始化
******************************************************************/
unsigned char reset(void)
{
uchar tdq;
DQ=1;
_nop_();
_nop_();
DQ=0; //拉低DQ总线开始复位
delay(24); //保持低电平480
DQ=1; //释放总线
delay(4); //等待芯片应答信号80
tdq=DQ; //获取应答信号
delay(24); //完成整个时序
return tdq;
}
/****************************************************************
函数名:read_bit()
描述:读一位数据子程序******************************************************************/
unsigned char read_bit(void)
{
unsigned char tdq;
_nop_();
DQ=0; //拉低DQ,开始读时序
_nop_();
DQ=1;
_nop_(); //释放总线
tdq=DQ;
delay(3); //延时60 ,等待读操作结束
return tdq;
}
/****************************************************************
函数名:read_byte()
描述:读一字节数据子程序******************************************************************/
unsigned char read_byte(void)
{
unsigned char i,tmp,dat=0;
for(i=0;i<8;i++)
{
tmp=read_bit();
//读一字节数据,一个时序中读一次,并作移位处理
dat|=tmp<<i;
}
delay(4); //延时80 以完成此次时序,之后再读下一数据
return dat;
}
/****************************************************************
函数名:write_bit()
描述:写一位数据子程序******************************************************************/
void write_bit(unsigned char bitval)
{
_nop_();
DQ=0;
_nop_(); //拉低DQ以开始一个写时序
if(bitval)
{
DQ=1;
delay(4);
}
else
{
delay(4);
DQ=1;
} //延时80 供DS18B20采样
//释放DQ总线
}
/****************************************************************
函数名:write_byte()
描述:写一字节数据子程序******************************************************************/
void write_byte(unsigned char dat)
{
unsigned int i;
unsigned char j;
for(i=0;i<8;i++) //写一字节数据,一次写一位
{
j=dat>>i; //移位操作,将本次要写的位移到最低位
j=j&0x01;
write_bit(j);
}
delay(6);
}
/****************************************************************
函数名:alarm()
描述:上下限蜂鸣器报警
******************************************************************/
void alarm()
{
BEE=1;
if(t>=max) //温度大于设定最大值进入报警循环
{
BEE=0; //打开蜂鸣器
delayms(500); //延时
BEE=1; //关闭蜂鸣器
delayms(500); //延时
}
if(t<=min) //温度小于设定最小值进入报警循环
{
BEE=0;
delayms(500);
BEE=1;
delayms(500);
}
}
/****************************************************************
函数名:change_start()
描述:发送18b20开始转换命令
******************************************************************/
void change_start(void)
{
reset();
delayms(1000);
write_byte(0xcc); //跳过序列号命令,对所有器件有效
write_byte(0x44); //发送转换命令44H 所有器件转换
}
/****************************************************************
函数名:readtemp()
描述:读取温度,判断键值j,0,1,2分别发送三个DS18B20的序列号.
******************************************************************/
void readtemp()
{
uchar i,j;
uchar a,b,t;
i=0;
if(keycon==0) //按键寻址,选择要显示的检测器件
{
j=1;
}
if(keycon==1)
{
j=2;
}
if(keycon==2)
{
j=3;
}
reset(); //复位
delayms(1000); //延时
write_byte(0x55); //发送ROM匹配命令
for(i=0;i<8;i++)
{
write_byte(SN[j][i]); //发送64位序列号
}
write_byte(0xbe); //发送读取命令
a=read_byte(); //读取温度值低位
b=read_byte(); //度取温度值高位
b=(i<<4)&0x7f; //屏蔽最高位(一位符号位)
a=a>>4; //低位右移,舍弃小数位。
t=b|a; //实际温度整数部分
temp1=a&0x0f;
xs=temp1*0.0625*10; //小数部分,若为0.5则算为了5来显示
}
/****************************************************************
函数名:rom()
描述:读取器件序列号的子程序,调用时确保总线中只有一只器件 ,
若多个器件时则读取出来的序列号号码无效
使用时先调用"ROM()"子程序读出每个器件的序列号
再将各个序列号填入SN数组中才能读出各个温度
******************************************************************/
void rom()
{
uchar sn1; //以下是定义8个序列号变量
uchar sn2;
uchar sn3;
uchar sn4;
uchar sn5;
uchar sn6;
uchar sn7;
uchar sn8;
reset(); //复位
delayms(1000); //延时1S
write_byte(0x33); //发送读序列号子程序
sn1=read_byte(); //读取第一个序列号,
sn2=read_byte(); //读取第二个序列号
sn3=read_byte();
sn4=read_byte();
sn5=read_byte();
sn6=read_byte();
sn7=read_byte();
sn8=read_byte();
}
/****************************************************************
函数名:key()
描述:上下限报警温度设置按键
******************************************************************/
void key(void)
{
do
{
if(P11==0) //判断SET键是否按下
{
delayms(20); //延时去抖
if(P11==0)
{
ID++;
if(ID>=3)
{
ID=0;
}
while(P11==0);
}
}
if(ID==1) //ID=1进入报警温度上限值设定
{
display1(max); //显示报警温度上限值
if(P12==0)
{
delayms(20);
if(P12==0) //判断加1键是否按下
{
increase(); //加"1"
display1(max); //重新显示报警温度上限值
}
while(P12==0);
}
if(P13==0)
{
delayms(20);
if(P13==0) //判断减1键是否按下
{
decrease(); //减"1"
display1(max); //重新显示报警温度上限值
}
while(P13==0); //知道释放按键,退出循环
}
}
if(ID==2) //ID=2进入报警温度下限值设定
{
display1(min); //重新显示报警温度下限值
if(P12==0)
{
delayms(20);
if(P12==0) //判断加1键是否按下
{
increase(); //加"1"
display1(min);
}
while(P12==0);
}
if(P13==0)
{
delayms(20);
if(P13==0) //判断减1键是否按下
{
decrease(); //减"1"
display1(min); //重新显示报警温度下限值
}
while(P13==0);
}
}
}while(ID==0); //进入循环,知直到D=0,即SET按键要按第三下才能退出该温度设定程序
}
/****************************************************************
函数名:key_select ()
描述:选择要发送的DS18B20序列号,选择不同点的的传感器显示温度
******************************************************************/
void key_select(void)
{
keycon=0; //器件选择标志位
if(key2==0)
{
delayms(20);
if(key2==0)
{
keycon++; //通过器件选择按键自加,标志位值代表三个不同器件
if(keycon>=3)
{
keycon=0;
}
while(key2==0);
}
}
}
/****************************************************************
函数名:increase()
描述:加1子函数,进入上限或者下限温度设定,max,min加1会有不同的限 制,由环境要求灵活设定。
******************************************************************/
void increase()
{
if(ID==1)
{
max++;
if(max>=70) //设定上限温度不得超过70,超过就默认为70
{
max=70;
}
}
if(ID==2)
{
if(min<max-10)
{
min++;
}
else
{
min=max-10;
}
}
}
/****************************************************************
函数名:decrease()
描述:减1子函数,进入上限或者下限温度设定,max,min减1会有不同的限 制,由环境要求灵活设定。
******************************************************************/
void decrease()
{
if(ID==1)
{
if(max<min+10)
{
max--;
}
else
{
max=min+10;
}
}
if(ID==2)
{
min--;
if(min<=0) //下限设定不得低于0,若低于就默认为0
{
min=0;
}
}
}
/****************************************************************
函数名:display()
描述:数码管温度显示子程序,PO口输出,P2.4、P2.5分别为段选、位选口
采用共阴极4-LED动态扫描显示。显示段为0.0℃~125.0℃。
******************************************************************/
void display(uchar ba,uchar sh,uchar ge,uchar aa)
{
wela1 = wela2 = wela3 = wela4 = 1;
P0 = clear;
P0 = table[ba];
wela1 = 0;
delayms(5);
wela1 = 1;
P0 = clear;
P0 = table[sh];
wela2 = 0;
delayms(5);
wela2 = 1;
P0 = clear;
P0 = table[ge];
wela3 = 0;
delayms(5);
wela3 = 1;
P0 = clear;
P0 = table[aa];
wela4 =0;
delayms(5);
wela4 =1;
}
/****************************************************************
函数名:display1(int T)
描述:上下限报警温度设定显示子程序,显示范围0℃~70℃,均为整数,不显 示小数部分,这个范围可由作者自定设置, ******************************************************************/
void display1(int T)
{
wela1 = wela2 = wela3 = wela4 = 1;
P0 = clear;
P0 = table[11];
wela1 =0;
delayms(1);
P0 = clear;
wela1 =1;
P0=0xfe;
wela1 =0;
delayms(2);
P0 = clear;
P0 = table[T/10];
wela2 =0;
delayms(1);
P0 = clear;
wela2 =1;
P0=0xfd;
wela2 =0;
delayms(2);
/*dula=1; //段选打开,让十位要显示字符的代码传到所有位中
P0=table[T/10];
//dula=0;
delayms(1);
P0=0xff;
//wela=1; //位选打开,选择第二个数码管,即十位显示
P0=0xfd;
//wela=0;
delayms(2); */
P0 = clear;
P0 = table[T%10];
wela3 =0;
delayms(1);
P0 = clear;
wela3 =1;
P0=0xfb;
wela3 =0;
delayms(2);
/*/dula=1; //段选打开,让个位要显示字符的代码传到所有位中
P0=table1[T%10];
//dula=0;
delayms(1) ;
P0=0xff;
//wela=1; //位选打开,选择第三个数码管,即个位显示
P0=0xfb;
//wela=0;
delayms(2); */
P0 = clear;
P0 = table[1];
wela4 =0;
delayms(1);
P0 = clear;
wela4 =1;
P0=0xf7;
wela4 =0;
delayms(2);
/*/dula=1; //段选打开,让小数位要显示字符的代码传到所有位中
P0=table[1]; //小数位一直显示0
//dula=0;
delayms(1);
P0=0xff;
//wela=1; //位选打开,选择第四个数码管,即小数位显示
P0=0xf7;
//wela=0;
delayms(2); */
}
/****************************************************************
函数名:main()
描述: 主函数 ******************************************************************/
void main(void)
{
max=40; //上下限初始化
min=20;
ID=0;
keycon=0;
rom(); //调用读序列号子程序
while(1)
{
key(); //判断是否上下限温度报警设置键是否有按下。有就进入温度设置程序
key_select(); //DS18B20选择按键,在三个测温点切换
change_start(); //所有器件开始温度度转换
delayms(5); //延时,如果是不断的读取的话可以不延时
readtemp(); //读取程序,执行完毕温度进入报警程序
alarm(); //进行检测是否越限程序,
ba=t/100;
sh=t%100/10;
ge=t%10;
aa=xs%10;
if(ID==0) //没有任何设定按键按下,显示温度
{
display(ba,sh,ge,aa);
}
}
}
求高手指导 |
|