我用DS18B20和继电器做的一个温度控制系统。一开始设置18B20的数据口为P1.0 焊板子的时候焊错了,所以我改成了P1.1,然而改了后就不好使了,求解答。
/*************************************************************************
DS18B20 温度采集
LCD型号:LG128645
1脚:GND
2脚:5V
4脚(CS信号)接高电平选通3.3V也可以
P2.4模拟SID(接第5脚)
P2.5模拟SCLK(接第6脚)
15脚(PSB信号)接地选择串行方式->和GND焊盘相接
17脚(RST信号)根据注释提示悬空
19脚20脚,液晶背光,可以不接
DS18B20接口
2脚模拟DQ:接P1.1
继电器接P1.0
*************************************************************************/
#include
#define uchar unsigned char
#define uint unsigned int
#define DS_OUT P1DIR|=BIT0
#define DS_IN P1DIR&=~BIT0
#define DS_H P1OUT|=BIT0
#define DS_L P1OUT&=~BIT0
#define DS_DATE (P1IN&BIT0)
#define RELAY_OUT P1DIR |= BIT1
#define RELAY_H P1OUT |= BIT1
#define RELAY_L P1OUT &= ~BIT1
void int_port(void) //管脚初始化
{
P2SEL&=~BIT4; //P2.4模拟SID,设置为i/o口输出方向
P2DIR|=BIT4;
P2OUT&=~BIT4;
P2SEL&=~BIT5; //P2.5模拟SCLK,设置为i/o口输出方向
P2DIR|=BIT5;
P2OUT&=~BIT5;
}
/********************************************************************
* 名称 : delay()
*
* 输入 : t
* 输出 : 无
***********************************************************************/
void delay(uint t) //延时函数
{
//粗略延时,满足时序要求
uint i,j;
for(i=0; i
for(j=0; j<10; j++);
}
/********************************************************************
* 名称 : sendbyte()
* 功能 : 按照液晶的串口通信协议,发送数据
* 输入 : zdata
* 输出 : 无
***********************************************************************/
void sendbyte(uchar zdata) //数据传送函数
{
uchar code_seg7;
uchar serial_clk;
uchar serial_shift;
code_seg7=zdata;
serial_shift=0x80;
for(serial_clk=0; serial_clk<8; serial_clk++)
{
if(code_seg7&serial_shift)
{
P2OUT|=BIT4; //SID为1
}
else
{
P2OUT&=~BIT4; //SID为0
}
P2OUT&=~BIT5; //产生时钟信号下沿
P2OUT|=BIT5; //产生时钟信号上沿
serial_shift=serial_shift>>1; //准备发送下一位数据
}
}
/********************************************************************
* 名称 : write_com()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_com(unsigned char cmdcode) //写命令函数
{
//串口控制格式(11111AB0)
//A数据方向控制,A=H时读,A=L时写
//B数据类型选择,B=H时为显示数据,B=L时为命令
sendbyte(0xf8); //MCU向LCD发命令
sendbyte(cmdcode & 0xf0); //发高四位数据(数据格式D7D6D5D4_0000)
sendbyte((cmdcode << 4) & 0xf0);//发低四位数据(数据格式D3D2D1D0_0000)
delay(2); //延时等待
}
/********************************************************************
* 名称 : write_data()
* 功能 : 写串口数据
* 输入 : Dispdata
* 输出 : 无
***********************************************************************/
void write_data(uchar Dispdata)//写数据函数
{
sendbyte(0xfa); //MCU向LCD发数据
sendbyte(Dispdata & 0xf0); //发高四位数据
sendbyte((Dispdata << 4) & 0xf0);//发低四位数据
delay(2);
}
/********************************************************************
* 名称 : lcdinit()
* 功能 : 初始化函数
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void lcdinit() //LCD初始化
{
delay(20000); //复位等待(内部自带上电复位电路),时间较长
write_com(0x30); //功能设定:基本指令集操作
delay(50); //延时等待
write_com(0x0c); //整体显示,关游标
delay(50);
write_com(0x01); //清屏
delay(50);
write_com(0x06); //入口设置
delay(50);
}
/********************************************************************
* 名称 : print_string()
* 功能 : 显示字符串
* 输入 : *s
* 输出 : 无
***********************************************************************/
void print_string(uchar *p) //发送字符串
{
while( *p) //C语言里字符串末尾自动加“\0”(ASCII码值为0)
{
write_data(*p); //发送字符对应的ASCII码,12864指针可设置自动指向下一个显示地址
p++;
delay(50);
}
}
/********************************************************************
* 函数名称 : LCD_12864_address_set( uchar x, y )
* 函数功能 : 12864地址坐标设置
* 函数参数 : X坐标,Y坐标
* 函数返回值: 无
*********************************************************************/
void LCD_12864_address_set( uchar x,uchar y )
{
uchar Address ;
switch( y )
{
case 1 : Address = 0x80 + (x - 1); break;
case 2 : Address = 0x90 + (x - 1); break;
case 3 : Address = 0x88 + (x - 1); break;
case 4 : Address = 0x98 + (x - 1); break;
default : break;
}
write_com(Address);
}
/*************************延时函数***********************/
void Delay(uint z)
{
uint x;
x = z;
while(x--);
}
/*************************1Ms延时函数***********************/
void Delay_Ms(uint z)
{
uchar x,y;
for(x = z;x > 0;x--)
for(y = 110;y > 0;y--);
}
/*****************************************************************************************
* DS18B20驱动函数
*
*
*****************************************************************************************/
/*************************DS18B20初始化***********************/
uchar DS_Init()
{
uchar result;
DS_OUT;
DS_L;
Delay(70);
DS_H;
result=DS_DATE; //读取18b20应答信号
Delay(500); //等待480us以上,保证总线释放
return(result); //返回0则初始化成功
}
void DS_Write(uchar dat) //写数据操作
{
uint i,j;
for(j = 0; j < 8; j++)
{
DS_OUT;
DS_L;
i++;
if(dat & 0x01 == 0x01)
DS_H;
else
DS_L;
dat = dat >> 1;
Delay(9);
DS_H;
}
}
uchar DS_Read() //读数据操作
{
uint i,j;
uchar byte,bi;
for(i = 8;i > 0;i--)
{
DS_OUT;
DS_L;
j++;
DS_H;
j++;
j++;
DS_IN;
bi = DS_DATE;
byte = (byte >> 1)|(bi << 7);
Delay(4);
}
return byte;
}
void DS_Change() //温度转换
{
DS_Init();
Delay_Ms(1);
DS_Write(0xcc);
DS_Write(0x44);
}
void DS_ReadTempCom() //读取温度命令
{
DS_Init();
Delay_Ms(1);
DS_Write(0xcc);
DS_Write(0xbe);
}
int DS_ReadTemp() //读取温度操作
{
int temp = 0;
uint tmh,tml;
DS_Change();
DS_ReadTempCom();
tml = DS_Read();
tmh = DS_Read();
temp = tmh;
temp <<= 8;
temp |= tml;
return temp;
}
void LCD_DisPlay(int temp)
{
uchar datas[] = {0,0,0,0,0};
float tp;
LCD_12864_address_set(1,2);
print_string("温度:");
if(temp < 0)
{
print_string("-") ;
temp = temp - 1;
temp = ~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
}
else
{
print_string("+") ; //显示正
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
}
datas[0] = temp / 10000;
datas[1] = temp % 10000 / 1000;
datas[2] = temp % 1000 / 100;
datas[3] = temp % 100 / 10;
datas[4] = temp % 10;
if(datas[1] >= 3)
{
LCD_12864_address_set(7,4);
print_string("关");
RELAY_OUT;
RELAY_L;
}
else
{
LCD_12864_address_set(7,4);
print_string("开");
RELAY_OUT;
RELAY_H;
}
LCD_12864_address_set(4,2);
write_data('0'+datas[0]); //百位
write_data('0'+datas[1]); //十位
write_data('0'+datas[2]); //个位
write_data('.'); //显示 ‘.’
write_data('0'+datas[3]); //十分位
write_data('0'+datas[4]); //百分位
print_string("℃");
}
int main()
{
WDTCTL=WDTPW+WDTHOLD;
int_port();
lcdinit();
LCD_12864_address_set(1,1);
print_string("**温度控制系统**");
LCD_12864_address_set(1,3);
print_string("温度上限: 30℃");
LCD_12864_address_set(1,4);
print_string("开关状态:");
while(1)
{
LCD_DisPlay(DS_ReadTemp());
}
}
#define DS_OUT P1DIR|=BIT0
#define DS_IN P1DIR&=~BIT0
#define DS_H P1OUT|=BIT0
#define DS_L P1OUT&=~BIT0
#define DS_DATE (P1IN&BIT0)
#define RELAY_OUT P1DIR |= BIT1
#define RELAY_H P1OUT |= BIT1
#define RELAY_L P1OUT &= ~BIT1
这几行是你重点要改的,你没改,而且从这定义来看,还有冲突
对,这几行确实是需要改的,但是,我注释掉所有的继电器的控制代码后,18B20还是驱动不起来。
是因为P1.0和P1.1有差别么,我看手册貌似也没差别啊
对,这几行确实是需要改的,但是,我注释掉所有的继电器的控制代码后,18B20还是驱动不起来。
是因为P1.0和P1.1有差别么,我看手册貌似也没差别啊
没差别的,可能还有别的地方需要改,你好好找找吧,这俩IO口几乎没什么差别