DS18B20各程序功能(急求!)

2024-12-19 01:55:40
推荐回答(2个)
回答1:

要键盘干什么

#include

#define CPU_F ((double)1048500)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))

#define SEGE 0X80
#define SEGH 0X40
#define SEGF 0X20
#define SEGC 0X10
#define SEGG 0X08
#define SEGD 0X04
#define SEGB 0X02
#define SEGA 0X01
const unsigned char digit[10] = {
SEGA|SEGB|SEGC|SEGD|SEGE|SEGF, /* "0" LCD segments a+b+c+d+e+f */
0x12, /* "1" */
0x8F, /* "2" */
0x1F, /* "3" */
0x3A, /* "4" */
0x3D, /* "5" */
0xBD, /* "6" */
0x13, /* "7" */
0xBF, /* "8" */
0x3F /* "9" */

};

#define DQ1 P3OUT|=BIT4
#define DQ0 P3OUT&=~BIT4

float Temper=0.0;
int temperature=0;
unsigned char Error = 0;
//----------------------------------
//功能:us 级别延时
// n=10,则延时10*5+6=56uS
//----------------------------------
void DelayNus(unsigned int n)
{
while(n--){};
}
//-----------------------------------
//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
unsigned char i;

for(i=0;i<8;i++)
{ P3DIR |= BIT4;
DQ0;
delay_us(13);//延时13us 左右
if((n&0X01)==0X01) DQ1;
else DQ0;
n=n>>1;
delay_us(50);//延时50us 以上
DQ1;
}
}
//------------------------------------
//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void)
{
unsigned char i;
unsigned char temp;
for(i=0;i<8;i++)
{
temp=temp>>1;
DQ0;
_NOP();//延时1us
DQ1;
_NOP();_NOP();//延时5us
_NOP();_NOP();_NOP();
P3DIR&=~BIT4;
if((P3IN&BIT4)==0)
{
temp=temp&0x7F;
}else
{
temp=temp|0x80;
}
delay_us(40);//延时40us
P3DIR|=BIT4;
DQ1;
}
return temp;
}
//-----------------------------------
void Init (void)
{
DQ0;
delay_us(600);//延时500us
DQ1;
delay_us(100);//延时90us
P3DIR&=~BIT4;
if((P3IN&BIT4)==BIT4) //0001 1111b=1f
{
Error =1; //失败1
P4DIR|=BIT4;
}else
{
Error = 0;//初始化成功
P4DIR|=BIT4;
DQ1;
}
}
//----------------------------------
void Skip(void)
{
Write_18B20(0xcc);
}
//----------------------------------
void Convert (void)
{
Write_18B20(0x44);
}

//----------------------------------
void ReadDo (void)
{
Write_18B20(0xbe);
}
//----------------------------------

void ReadTemp (void)
{
char temp_low,temp_high; //温度值
temp_low=Read_18B20(); //读低位
temp_high=Read_18B20(); //读高位
temperature=(temp_high&0x0f);
temperature<<=8;
temperature|=temp_low;
Temper=temperature*0.0625;
}

void GetTemp(void){
Init();
Skip();
Convert();
delay_ms(500);
delay_ms(500);
delay_ms(500);//延时1s以上
Init();
Skip();
ReadDo();
ReadTemp();
}

void InitLcd(void){
LCDCTL = LCDON + LCD4MUX + LCDSG0_1; // LCD on, 4-Mux, segments S0-S15
BTCTL = BT_fLCD_DIV128; // LCD clock freq is ACLK/128
P5SEL = 0xFC; // Select P5.2-7 as Com and Rxx
}
void display_number(unsigned long value, int start, int width)
{
int i;
for (i = 0; i < width; i++)
{
LCDMEM[7 + i - start] = digit[value%10]; // remainder = character in table to display
value /= 10;
}
}
void Lcd_Clr(void)
{
volatile unsigned char i;
for (i=0; i<7; i++)
{
LCDMEM[i] = 0;
}
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 停狗
P3DIR |=BIT4;
DQ1;
InitLcd();
Lcd_Clr();

while(1)
{
GetTemp();
display_number((unsigned long int)(Temper*1000),7,5);
LCDMEM[3] |= SEGH;
}
}

回答2:

(1)主程序:程序的执行从主程序开始,首先调用初始化子程序,用于对中断配置等必要的初始赋值,然后进入主循环,不断重复的执行或调用主循环中的程序,实现数码管的动态扫描、按键的识别和键值处理、温度转换等功能。

(2)显示子程序:显示若用数码管,要显示完整的温度值,一般会选用4位一体数码管,在显示子程序中,对数码管的段、位以动态扫描的方式根据当前需要显示的内容不断对其进行更新和配置,利用人眼的惰性效应达到动态显示的目的。

(3)中断子程序:一般温度不需要实时测量,因为温度是不会突变的,没有必要实时,另一方面实时太占用系统资源,所以可以隔一段时间测量一次,用定时器中断来定时使能测温标志,供温度转换程序在主程序中查询。

(4)延时子程序:单总线时序是建立在延时操做基础上的。

(5)DS18B20初始化子程序:相当于给18B20数据头的作用,18B20检测到初使化电平,准备开始接收或发送数据,另一方面,可根据DS18B20是否作出应答来检测它是否在总线上。

(6)读/写一个字节子程序:在单总线上按照标准单总线的读/写时序,产生一个读/写单字节数据的操作事件,什么时候读/写,读/写些什么,由18B20这个单总线器件内部的数据协议和数据结构来决定(单总线的器件有很多种,操作协议和数据结构不尽相同,但读写时序都是一样的)。

(7)读出温度子程序:基于对单总线的读/写子程序,按照18B20器件的读写协议,将温度转换指令,温度读取指令先后通过单总线送入18B20,18B20收到指令作出响应,将转换得到的温度数据送到单总线上。

(8)键盘扫描子程序keyscan:如果是做温控器或者温度报警器,一般需要用一些按键来设置报警温度或控制温度的上限和下限值,键盘扫描子程序用于识别哪个按键被触发,然后作出相应的键值更新,供键值处理程序响应以改变设置参数。