📄 main_onefile._c
字号:
#include <iom16v.h>
#include <macros.h>
#define F_CPU 7372800
//数据类型的定义
#define uint8 unsigned char
#define uint16 unsigned int
//位变量操作宏定义
#define BIT_SET(a,b) a|=BIT(b)
#define BIT_CLR(a,b) a&=~BIT(b)
#define BIT_INV(a,b) a^=BIT(b)
#define BIT_STATUS(a,b) a&BIT(b)
//DS18B20操作定义
#define CLR_DS18B20 BIT_CLR(PORTD,PD3) //数据线强制拉低
#define SET_DS18B20 BIT_SET(PORTD,PD3) //数据线强制拉高,上拉
#define HLD_DS18B20 BIT_SET(DDRD,PD3) //Mega16控制总线
#define RLS_DS18B20 BIT_CLR(DDRD,PD3) //释放总线
#define STU_DS18B20 BIT_STATUS(PIND,PD3) //数据线的状态
void port_init(void)
{
PORTA = 0xFF;
DDRA = 0x00;
PORTB = 0xFF;
DDRB = 0xFF; //输出
PORTC = 0xFF; //m103 output only
DDRC = 0xFF; //输出
DDRD = 0xFF;
PORTD = 0xFF;
}
/**********************************************************************
functionName: void delayUs(BYTE temp)
description :延时函数 晶振频率:7.3728MHZ
delayUs(1); //2.71us
delayUs(2); //3.53us
delayUs(4); //5.15us
delayUs(8); //8.41us
delayUs(16); //14.92us
delayUs(32); //27.94us
delayUs(64); //53.98us
delayUs(128); //106.07us
delayUs(255); //209.42us
delayUs(18); //16.55us
delayUs(34); //29.57us
delayUs(35); //30.38us
delayUs(100); //83.28
_NOP(); //0.14us
**********************************************************************/
void delayUs(BYTE temp)
{
while(temp--);
}
//延时约1s
void longdelay(void)
{
unsigned int i;
for(i=4761;i!=0;i--)
delayUs(255);
}
/*******************************************************************************
functionName: uint8 resetDS18B20(void)
description :DS18B20初始化
********************************************************************************/
uint8 resetDS18B20(void)
{
uint8 errTime=0;
RLS_DS18B20; //释放总线
_NOP();
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
delayUs(255); //209.42us
delayUs(255); //209.42us
delayUs(255); //83.28us
//以上的三个延时大于480us
RLS_DS18B20; //释放总线,总线自动上拉
_NOP();
while(STU_DS18B20)
{
delayUs(4); //5.15us
errTime++;
if(errTime>20)
return(0x00); //如果等带大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)
}
errTime=0;
while(!(STU_DS18B20))
{
delayUs(4); //5.15us
errTime++;
if(errTime>50)
return(0x00); //如果等带大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)
}
return(0xff);
}
/**********************************************************************
functionName: uint8 readuint8DS18B20(void)
description :读DS18B20一个字节
**********************************************************************/
uint8 readuint8DS18B20(void)
{
uint8 i;
uint8 retVal=0;
RLS_DS18B20; //释放总线
for(i=8;i>0;i--)
{
retVal>>=1;
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP(); //延时大于1us
RLS_DS18B20; //释放总线,DS18B20会将总线强制拉低
NOP();
NOP();
NOP();
if(STU_DS18B20)
retVal|=0x80;
delayUs(16); //14.92us
delayUs(16); //14.92us
RLS_DS18B20; //释放总线
delayUs(35); //30.38us
}
delayUs(1); //2.71us(大于1us就行了)
return(retVal);
}
/*******************************************************************************
functionName: uint8 readuint8DS18B20(void)
description :写DS18B20一个字节
********************************************************************************/
void writeuint8DS18B20(uint8 wb)
{
uint8 i;
uint8 temp;
RLS_DS18B20; //释放总线
for(i=0;i<8;i++)
{
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
delayUs(16); //14.92us
temp=wb>>i;
temp&=0x01;
if(temp)
RLS_DS18B20; //释放总线
else
CLR_DS18B20; //强制拉低
delayUs(16); //14.92us
delayUs(35); //30.38us
RLS_DS18B20; //释放总线
delayUs(1); //2.71us(大于1us就行了)
}
}
/*******************************************************************************
functionName: unsigned int readTempDS18B20(void)
description :读DS18B20温度
********************************************************************************/
unsigned int readTempDS18B20(void)
{
uint8 tempL,tempH;
uint16 x;
resetDS18B20();
writeuint8DS18B20(0xcc); //跳过ROM
writeuint8DS18B20(0x44); //启动温度转换
delayUs(1);
resetDS18B20();
writeuint8DS18B20(0xcc); //跳过ROM
writeuint8DS18B20(0xbe); //读数据
tempL=readuint8DS18B20();
tempH=readuint8DS18B20();
x=(tempH<<8)|tempL;
return(x);
}
void main()
{
unsigned char temp=0;
port_init();
USART_Init(9600); //波特率9600 初始化串口
USART_Transmit('O');
USART_Transmit('K');
while(1)
{
i=resetDS18B20();
i=readTempDS18B20();
//下面开始对读到的数进行处理
if(i&(1<<3)) //判断倒数第四位是1还是0
{
temp=i>>4+1;
}
else
{
temp=i>>4;
}
USART_Transmit(temp); //结果发到串口中
delay();
}
}
/*
假设你只要精确到1度
换算温度用很简单的方法就可以处理:
首先判断是正温度还是负温度
然后判断倒数第四位是1还是0
如果是1且温度为正,那么 温度=x>>4+1;
如果是1且温度为负,那么 温度=x>>4-1;
如果是0,温度=x>>4;
这样的操作可以节省很多的flah空间。
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -