发个18B20测温的程序,程序早都写好了,就是一直没时间发,18B20温度传感器的文档大叔的资料里有,而且有例程,我只是根据自己的硬件改了一下。温度值是通过12864液晶显示出来的。加入了报警功能,当温度超出按键设定的温度值之后会蜂鸣报警,当温度再次降低到报警之下时停止报警。
先上图
工程在这里
18B20测温_LCM.rar
(2.9 MB)
下面贴出代码
主函数
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvADC.h"
#include "DrvGPIO.h"
#include "DrvUART.h"
#include "DrvSYS.h"
#include "ds18b20.h"
unsigned char DS18B20_ID[8]={0,0,0,0,0,0,0,0,};
unsigned char NOW_TEMP[6]={0};
void bee (void)
{
int i=100;
for(i=100;i>0;i--)
{
DrvGPIO_SetBit(E_GPB, 10);
DrvSYS_Delay(500);
DrvGPIO_ClrBit(E_GPB, 10);
DrvSYS_Delay(500);
}
}
int main (void)
{
unsigned int temp=0;
unsigned int temp_H=0;
unsigned int temp_L=0;
unsigned char i=0;
unsigned int bv=30;
unsigned char flag ;
UNLOCKREG(); // 芯片注册解锁
SYSCLK->PWRCON.XTL12M_EN = 1; // 设定12M外部晶振
DrvSYS_Delay(5000); // 等待时钟就绪
LOCKREG(); //向“0x5000_0100”写入任何值,就可以重锁保护寄存器
//--------------------------------------------------------- // 系统初始化
DrvGPIO_Open(E_GPA, 9, E_IO_OUTPUT);
DrvGPIO_Open(E_GPA, 8, E_IO_OUTPUT);
DrvGPIO_Open(E_GPA, 7, E_IO_OUTPUT);
DrvGPIO_Open(E_GPA, 6, E_IO_OUTPUT);
DrvGPIO_Open(E_GPA, 5, E_IO_OUTPUT);
DrvGPIO_Open(E_GPB, 10, E_IO_OUTPUT); // 设置GPB10端口为输出模式
DrvGPIO_Open(E_GPA, 9, E_IO_OUTPUT);
DrvSYS_Delay(6000);
DrvGPIO_Open( E_GPB, 14, E_IO_INPUT ); //按键端口设置为输入
DrvGPIO_Open( E_GPB, 15, E_IO_INPUT );
DrvGPIO_ClrBit(E_GPB, 10);
DrvSYS_Delay(6000);
LCMInit();
Chn_disp_char("现在温度",1,1) ;
Chn_disp_char("报警设定值",2,1) ;
while(1)
{
temp = readTempDS18B20();
temp_H = temp/100;
temp_L = temp%100;
Digtal_disp(temp_H,1,5);
WriteLCM(1,0x2e) ;
Digtal_disp(temp_L,1,0);
Chn_disp_char("度",1,7) ;
Digtal_disp(bv,2,6);
if(temp_H>=bv)
bee();
if (DrvGPIO_GetBit(E_GPB,14) == 0) // 键按下检测
{
bv++;
DrvGPIO_SetBit(E_GPB, 10);
DrvSYS_Delay(100);
DrvGPIO_ClrBit(E_GPB, 10);
}
if (DrvGPIO_GetBit(E_GPB,15) == 0) // 键按下检测
{
bv--;
DrvGPIO_SetBit(E_GPB, 10);
DrvSYS_Delay(100);
DrvGPIO_ClrBit(E_GPB, 10);
DrvSYS_Delay(60000);
}
DrvSYS_Delay(60000);
}
}
18B20.c
/***************************************************/
/* 烈火狂龙 论坛ID:plc_avr QQ:16053729 */
/* 移值于其它MCU时,注意修改端口和延时函数 */
/* 2011、03、30 */
/*-------------------------------------------------*/
#include "ds18b20.h"
unsigned char DS18B20_sign_flag=0;
/**********************************************************************
延时
**********************************************************************/
void delay_nus(unsigned int t)
{
unsigned int i=0;
while(t--)
{
for(i=0;i<1;i++);
}
}
/**********************************************************************
functionName: unsigned char resetDS18B20(void)
description :DS18B20初始化
**********************************************************************/
unsigned char resetDS18B20(void)
{
unsigned char errTime=0;
HLD_DS18B20; //控制总线
CLR_DS18B20; //强制拉低
delay_nus(260); //以上延时大于480us
SET_DS18B20;
RLS_DS18B20; //释放总线,总线自动上拉 DDR
delay_nus(7); //15~60us
while (STU_DS18B20)
{
delay_nus(3); //5.15us
errTime++;
if (errTime>20)
return(0x00); //如果等带大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)
}
errTime=0;
while (!(STU_DS18B20))
{
delay_nus(3); //5.15us
errTime++;
if (errTime>50)
return(0x00); //如果等带大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)
}
HLD_DS18B20; //控制总线
SET_DS18B20; //强制拉高
return(0xff);
}
/**********************************************************************
functionName: unsigned char readByteDS18B20(void)
description :读DS18B20一个字节
**********************************************************************/
unsigned char readByteDS18B20(void)
{
unsigned char i;
unsigned char retVal=0;
//RLS_DS18B20; //释放总线
for (i=8;i>0;i--)
{
retVal>>=1;
HLD_DS18B20; //控制总线
CLR_DS18B20; //强制拉低
delay_nus(1); //延时大于1us
SET_DS18B20; //释放总线,DS18B20会将总线强制拉低
RLS_DS18B20; //释放总线
delay_nus(1);
if (STU_DS18B20)
retVal|=0x80;
delay_nus(15); //31us
}
HLD_DS18B20; //控制总线
SET_DS18B20; //强制拉高
return(retVal);
}
/**********************************************************************
functionName: unsigned char readByteDS18B20(void)
description :写DS18B20一个字节
**********************************************************************/
void writeByteDS18B20(unsigned char wb)
{
unsigned char i;
unsigned char temp;
//RLS_DS18B20; //释放总线
for (i=0;i<8;i++)
{
HLD_DS18B20; //控制总线
CLR_DS18B20; //强制拉低
delay_nus(1); //14.92us
temp=wb>>i;
if (temp&=0x01)
SET_DS18B20; //释放总线
else
CLR_DS18B20; //强制拉低
delay_nus(15); //30.38us
SET_DS18B20; //释放总线
delay_nus(1); //2.71us(大于1us就行了)
}
}
/**********************************************************************
functionName: get_rom(unsigned char* p)
description :读ROM
**********************************************************************/
void get_rom(unsigned char* p)
{
unsigned char i;
if (resetDS18B20()==0xff)
{
writeByteDS18B20(ds18b20_read_rom);
for (i=0;i<8;i++)
{
*p++ = readByteDS18B20();
}
}
}
/**********************************************************************
functionName: void set_ds18b20(char th,char tl,unsigned char config)
description :设定DS18B20模式
**********************************************************************/
void set_ds18b20(char th,char tl,unsigned char config)
{
if (resetDS18B20()==0xff)
{
writeByteDS18B20(ds18b20_skip_rom);
writeByteDS18B20(ds18b20_write_ram);
writeByteDS18B20(th);
writeByteDS18B20(tl);
writeByteDS18B20(config);
}
}
/**********************************************************************
functionName: convert_ds18b20(void)
description :写DS18B20一个字节
**********************************************************************/
void convert_ds18b20(void)
{
if (resetDS18B20()==0xff)
{
writeByteDS18B20(ds18b20_skip_rom); //跳过ROM
writeByteDS18B20(ds18b20_convert_tem); //启动温度转换
}
}
/**********************************************************************
functionName: unsigned int readTempDS18B20(void)
description :读DS18B20温度 有正负符号标志和两个小数点精度
**********************************************************************/
unsigned int readTempDS18B20(void)
{
unsigned char tempL,tempH,wm0,wm2;
unsigned int x;
if (resetDS18B20()==0)
return 0;
writeByteDS18B20(ds18b20_skip_rom); //跳过ROM
writeByteDS18B20(ds18b20_read_ram); //读数据
tempL=readByteDS18B20();
tempH=readByteDS18B20();
wm0=tempL;
wm0=wm0>>4;
tempH=tempH<<4;
wm2=wm0+tempH; //温度的整数值
if (wm2&0x80) //测试符号位
{
DS18B20_sign_flag=1;
wm2=256-wm2;
}
else
DS18B20_sign_flag=0;
x = wm2*100; //字符型赋给整形,扩大100倍
if (tempL&0x08) //提高测试精度
{
x=x+50;
}
if (tempL&0x04)
{
x=x+25;
}
if (tempL&0x02)
{
x=x+12;
}
if (tempL&0x01)
{
x=x+6;
}
convert_ds18b20();//启动温度转换
return(x);
}
18B20.h
#ifndef __DS18B20__H
#define __DS18B20__H
#include "NUC1xx.h"
#include "DrvGPIO.h"
#define CLR_DS18B20 DrvGPIO_ClrBit(E_GPB, 4) //数据线强制拉低
#define SET_DS18B20 DrvGPIO_SetBit(E_GPB, 4) //数据线强制拉高,上拉
#define HLD_DS18B20 DrvGPIO_Open(E_GPB, 4, E_IO_OUTPUT) //M0控制总线
#define RLS_DS18B20 DrvGPIO_Open(E_GPB, 4, E_IO_QUASI) //释放总线
#define STU_DS18B20 DrvGPIO_GetBit(E_GPB, 4) //数据线的状态
#define ds18b20_read_rom 0x33
#define ds18b20_match_rom 0x55
#define ds18b20_skip_rom 0xcc
#define ds18b20_search_rom 0xf0
#define ds18b20_alarm_search_rom 0xec
#define ds18b20_write_ram 0x4e
#define ds18b20_read_ram 0xbe
#define ds18b20_copy_ram 0x48
#define ds18b20_convert_tem 0x44
#define ds18b20_eecall_eeprom 0xb8
#define ds18b20_read_power_supply 0xb4
extern unsigned char DS18B20_sign_flag;
void delay_nus(unsigned int t);
unsigned char resetDS18B20(void);
void get_rom(unsigned char* p);
void set_ds18b20(char th,char tl,unsigned char config);
void convert_ds18b20(void);
unsigned int readTempDS18B20(void);
#endif
/////////////////////////////////////////////////////////////////////////////////////////////
//LCM显示程序
//2011.12.30 by xiaowei
/////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#include "lcm.h"
void WriteLCM(int32_t data_comm,int32_t in_com) //1 for data,0 for comm
{
int32_t com,i,j,std;
DrvSYS_Delay(100);
com = in_com;
DrvGPIO_SetBit( E_GPA,8 ); //LCD_CS = 1;
DrvGPIO_ClrBit( E_GPA,6); //LCD_EN = 0;
DrvGPIO_SetBit(E_GPA,7);//LCD_STD = 1;
for(i=5;i>0;i--)
{
DrvGPIO_SetBit( E_GPA,6); //LCD_EN = 1;
DrvGPIO_ClrBit( E_GPA,6); //LCD_EN = 0;
}
DrvGPIO_ClrBit(E_GPA,7);//LCD_STD = 0;
DrvGPIO_SetBit( E_GPA,6); //LCD_EN = 1;
DrvGPIO_ClrBit( E_GPA,6); //LCD_EN = 0;
if(data_comm==1)
DrvGPIO_SetBit(E_GPA,7);//LCD_STD = 1;
else
DrvGPIO_ClrBit(E_GPA,7);//LCD_STD = 0;
DrvGPIO_SetBit( E_GPA,6); //LCD_EN = 1;
DrvGPIO_ClrBit( E_GPA,6); //LCD_EN = 0;
DrvGPIO_ClrBit(E_GPA,7);//LCD_STD = 0;
DrvGPIO_SetBit( E_GPA,6); //LCD_EN = 1;
DrvGPIO_ClrBit( E_GPA,6); //LCD_EN = 0;
for(j=2;j>0;j--)
{
for(i=4;i>0;i--)
{
std=com&0x80;
if(std==0x80)
DrvGPIO_SetBit(E_GPA,7); //LCD_STD = 1;
else
DrvGPIO_ClrBit(E_GPA,7); //LCD_STD = 0;
com=com<<1;
DrvGPIO_SetBit( E_GPA,6); //LCD_EN = 1;
DrvGPIO_ClrBit( E_GPA,6); //LCD_EN = 0;
}
DrvGPIO_ClrBit(E_GPA,7); //LCD_STD = 0;
for(i=4;i>0;i--)
{
DrvGPIO_SetBit( E_GPA,6); //LCD_EN = 1;
DrvGPIO_ClrBit( E_GPA,6); //LCD_EN = 0;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void LCMInit(void) //LCM初始化
{
DrvGPIO_ClrBit(E_GPA,5 );
DrvSYS_Delay(6000);
DrvGPIO_SetBit(E_GPA,5 );
WriteLCM(0,0x30) ; //设接口数据位数(DL),显示行数(L),及字型(F)
DrvSYS_Delay(6000);
WriteLCM(0,0x01) ; //清屏指令
DrvSYS_Delay(6000);
WriteLCM(0,0x0c) ; //设整体显示开关(D),光标开关关(C),及光标位的字符不闪耀(B)
DrvSYS_Delay(6000);
WriteLCM(0,0x06) ; //7设光标移动方向并指定整体显示是否移动
DrvSYS_Delay(6000);
WriteLCM(0,0x01) ; //清屏指令
DrvSYS_Delay(6000);
WriteLCM(0,0x80) ; //设DDRAM地址,设置后DDRAM数据被发送和接收
}
/////////////////////////////////////////////////////////////////////////
//写汉字
//输入char[]={"显示的字"},行数,列数 显示数字时,如果列数为0,则接着显示
void Chn_disp_char( char *chn, int32_t line_pos, int32_t dis_pos)
{
char i=0,Start_pos;
WriteLCM (comm_flag,0x30);
switch(line_pos)
{
case 1:
Start_pos=FirstLine_Start;
break;
case 2:
Start_pos=SecondLine_Start;
break;
case 3:
Start_pos=ThirdLine_Start;
break;
case 4:
Start_pos=FourthLine_Start;
break;
}
if(dis_pos!=0)
WriteLCM (comm_flag,(Start_pos+dis_pos-1));
while(chn[i]!='\0')
{
WriteLCM (data_flag,chn[i]);
i++;
}
}
////////////////////////////////////////////////////////
//写数字
//输入 (数字,行数,列数)
void Digtal_disp( int32_t digt, int32_t line_pos, int32_t dis_pos)
{
char digt_ []={""};
sprintf(digt_,"%.2d",digt);
Chn_disp_char(digt_,line_pos,dis_pos);
}
/////////////////////////////////////////////////////////////////
lcm.h
//用于TG12864
//串口通信
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#define LCD_CS E_GPA,8 ;
#define LCD_STD E_GPA,7 ;
#define LCD_EN E_GPA,6 ;
#define LCD_RST E_GPA,5 ;
#define FirstLine_Start 0x80
#define SecondLine_Start 0x90
#define ThirdLine_Start 0x88
#define FourthLine_Start 0x98
#define comm_flag 0
#define data_flag 1
void WriteLCM(int32_t data_comm,int32_t in_com) ;
void LCMInit(void) ;
void Chn_disp_char( char *chn, int32_t line_pos, int32_t dis_pos) ;
void Digtal_disp( int32_t digt, int32_t line_pos, int32_t dis_pos) ;
|