unsigned char ReadOneChar(void)
{
uchar i=0 //定义i用于循环
uchar dat = 0 //读取的8位数据
for (i=8i>0i--) //8次循环
{
DQ = 0 //拉低DQ总线开始读时序
dat>>=1 //dat左移一位
DQ = 1 //释放DQ总线
if(DQ)//如果DQ=1,执dat|=0x80;(0x80即第7位为1,如果DQ为1,即读取的数据为1,将dat的第7为置1,然后dat>>=1,循环8次结束,dat即为读取的数据)
//DQ=0,就跳过
dat|=0x80
delay_18B20(4) // 延时以完成此次读时 序,之后再读下一数据
}
return(dat) //返回读取的dat
}
DQ = dat&0x01这句语句是错误的。DQ为位变量,而dat为 unsigned char
如果真要这么写的话,应该是这样 :DQ = (bit)dat&0x01;
把我写的给你做个参考吧:
extern uchar8 sig //sig判定温度符号
/*延时函数*/
void delay (int us) //DELAY-11.0592MHZ 调用程序大约为24us,每次循环为16us
{
int s
for(s=0s<uss++)
}
void delayms(int z) //z为毫秒数
{
int x,y
for(x=zx>0x--)
for(y=125y>0y--)
}
/*复位程序*/
unsigned char reset(void)
{
uchar8 presence
DQ=0 //拉低总线。当总线停留在旁颂低电平480us-960us ,总线上所以器件都将被复位
delay(30) //保持低电平504us
DQ=1 //释放总线,让其恢复高电平
delay(3) //等待芯片应答信号
presence=DQ //获取应答信号
delay(25) //延时以完成整个时序
return(presence)//返回应答信号。有芯片应答返回0,否则返回1。
}
/*写一位数据*/
void write_bit(char bitval)
{
DQ=0 //拉低DQ总线,开始时序
if(bitval==1) //如果写运厅郑入的为1,则返回高伏物电平
DQ=1
delay(5) //延时104us,以完成整个时序
DQ=1
}
/*写一字节数据*/
void write_byte(char val)
{
uchar8 i,temp
for (i=0i<8i++) //写入一个字节的数据,一个时序中写一次
{
temp=val>>i //右移i位
temp&=0x01 //复制那位数据到temp
write_bit(temp) //调用write_bit()
}
delay(5) //延时104us以完成此次时序,之后再写下一数据
}
/*读一位数据*/
uchar8 read_bit(void)
{
uchar8 i
DQ=0 //拉低DQ,开始读时序
DQ=1 //释放DQ总线
for(i=0i<3i++)//从时序开始延时15us
return(DQ) //返回DQ值
}
/*读一字节数据*/
uchar8 read_byte(void)
{
uchar8 i,value=0
for(i=0i<8i++)
{
if(read_bit()) //读一字节数据,一个时序中读一次,并作移位处理
value|=0x01<<i
delay(6)//延时以完成此次读时序,之后再读下一数据
}
return(value)
}
/*温度转化*/
void tmconvert(void)
{
reset() //复位
delay(1)
write_byte(0xcc) //仅一个DS18b20 ,跳过ROM
write_byte(0x44)//温度变换
}
/*读取温度*/
long gettm(void)
{
uchar8 LSB=0,MSB=0 //用于存储读取的温度
long temp
reset() //复位
write_byte(0xcc)//写指令,跳过ROM,仅一个DS18b20
write_byte(0xbe)//写指令,读暂存存储器
LSB = read_byte() //读LSB
MSB = read_byte()//读MSB
sig=(MSB>>4==0X0F)
if(sig) //判断符号位是否为负值,是负值了,转去处理
{
LSB=~LSB//温度处理
MSB=~MSB
LSB=LSB+1
}
temp=MSB*256+LSB//十六进制转换为10进制
temp=temp*100/16//12位精度,最小分辨率为0.0625°C
return temp //获得0.01°C 的精度并返回
}
#include<reg52.h>#include<Star1602.h>
#define CIRCLE 1.8 //宏定义 车轮的周长(这个要根据实际的车轮进行设置)
sbit Signal = P1^0 //这里的Signal表示的是霍尔传感器的信号引脚
int m_second=0; //定义变量m_second,用来记录时间(以毫秒为单位)
float speed=0.0 //定义速度变量
float length=0.0 ;//定义路程变量
void main()
{
lcd_init()//初始化液晶函数
TMOD = 0x01//打开定时器0,并设定其工作方式为16位定时模式。
TH0=(65536-10000)/ 256
TL0=(65536-10000)% 256 //设定定时器的初值,使得没10ms中断一次
EA = 1 //允许总中断
ET0 = 1 //允许定时器0终端
TR0 = 1; //启动定时器0
while(1) //大循环
{
while(Signal); //等待霍尔传感器信号线拉低;
speed = CIRCLE *1000 / m_second //计算速度。
m_second = 0 //计时清零
length += CIRCLE //路程加一个车轮周期
//第一行,显示速度
lcd_pos(0x0) //设定液晶的写入位置为第一行第一格
lcd_wdat(‘S’)
lcd_wdat(‘p’)
lcd_wdat(‘e’)
lcd_wdat(‘e’)
lcd_wdat(‘d’)
lcd_wdat(‘:’)
lcd_wdat( (int)speed%10 ) //显示速度的整数部分
lcd_wdat( (int)(speed*10)%10 ) //显示速度的小数第一位
lcd_wdat( (int)(speed*100)%10 ) //显示速度的小数第二位
lcd_wdat(‘m’)
lcd_wdat(‘/’)
lcd_wdat(‘s’)
//第二李拦行,显示里程
lcd_pos(0x80) //设定液晶的写入位置为第二行第一格
lcd_wdat(‘L’和咐)
lcd_wdat(‘e’)
lcd_wdat(‘n’)
lcd_wdat(‘g’)
lcd_wdat(‘t’)
lcd_wdat(‘h’)
lcd_wdat(‘:’)
lcd_wdat(length /10000+0x30) //显示里程的万位;
lcd_wdat(length %10000/1000+0x30) //显示里程的千位;
lcd_wdat(length %1000/100+0x30) //显示里程的百位;
lcd_wdat(length %100/10+0x30) //显示里程的十位;
lcd_wdat(length %10+0x30) //显示里程的个位;
lcd_wdat(‘m’哪棚胡)
}
}
void timer0_intt() interrupt 1 //
{
TH0=(65536-10000)/ 256
TL0=(65536-10000)% 256 //设定定时器的初值,使得没10ms中断一次
m_second += 10 //因为中断每10毫秒一次,所以这里每次加10;
}
附件1 Star1602.h
#ifndef __STAR1602_H__
#define __STAR1602_H__
sbit rs= P2^0 //
sbit rw = P2^1 //
sbit ep = P2^2 //
void lcd_init() //液晶初始化函数
void lcd_pos(unsigned char pos) //设定液晶的显示位置函数
void lcd_wdat(unsigned char dat) //液晶写入字符
void lcd_write_int(unsigned int x)//液晶显示一个整形变量
#endif
附件2 Star1602.c
#include <reg52.h>
#include "1602.h"
/*****************************************************************************
函数功能:LCD延时子程序
入口参数:ms
出口参数:
*****************************************************************************/
static void delay(unsigned char ms)
{
unsigned char i
while(ms--)
{
for(i = 0i<5i++)
}
}
/*****************************************************************************
函数功能:测试LCD忙碌状态
入口参数:
出口参数:result
*****************************************************************************/
static bit lcd_bz()
{
bit result
rs = 0
rw = 1
ep = 1
delay(5)
result = (bit)(P0 &0x80)
ep = 0
return result
}
/*****************************************************************************
函数功能:写指令数据到LCD子程序
入口参数:cmd
出口参数:
*****************************************************************************/
static void lcd_wcmd(unsigned char cmd)
{
while(lcd_bz())//判断LCD是否忙碌
rs = 0
rw = 0
ep = 0
delay(5)
P0 = cmd
delay(5)
ep = 1
delay(5)
ep = 0
}
/*****************************************************************************
函数功能:设定显示位置子程序
入口参数:pos
出口参数:
*****************************************************************************/
void lcd_pos(unsigned char pos)
{
lcd_wcmd(pos | 0x80)
}
/*****************************************************************************
函数功能:写入显示数据到LCD子程序
入口参数:dat
出口参数:
*****************************************************************************/
void lcd_wdat(unsigned char dat)
{
while(lcd_bz())//判断LCD是否忙碌
rs = 1
rw = 0
ep = 0
P0 = dat
delay(5)
ep = 1
delay(5)
ep = 0
}
/*****************************************************************************
函数功能:LCD初始化子程序
入口参数:
出口参数:
*****************************************************************************/
void lcd_init()
{
lcd_wcmd(0x38)
delay(100)
lcd_wcmd(0x0c)
delay(100)
lcd_wcmd(0x06)
delay(100)
lcd_wcmd(0x01)
delay(100)
}
/*****************************************************************************
函数功能:LCD写入一个整形数据
入口参数:int x
*****************************************************************************/
void lcd_write_int(unsigned int x)
{
unsigned char x1,x2,x3,x4,x5;
x1 = x/10000
x2=x%10000/1000
x3=x%1000/100
x4=x%100/10
x5=x%10
lcd_wdat(x1+0x30)
lcd_wdat(x2+0x30)
lcd_wdat(x3+0x30)
lcd_wdat(x4+0x30)
lcd_wdat(x5+0x30)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)