最近在做一个DS18B20测室温的程序,单片机是AVR的,也在网上查了很多资料,自己写了很多程序,然而一个也没调出来,感觉挺受挫的 ,又不想搁置,特来此寻找大神帮我看看我的程序,找到错误之处。新人没有多少芯币,还望不要嫌弃。下面是我的程序:/*******************************头文件**************************************/
#include<iom128v.h>
#include<macros.h>
/*******************************宏定义*************************************/
#define TEM_PORT PORTG
#define TEM_DDR DDRG
#define TEM_PIN PING
#define TEM_SDT 3
#define SET_TEM_SDT (TEM_PORT|=(1<<TEM_SDT))
#define CLR_TEM_SDT (TEM_PORT&=~(1<<TEM_SDT))
#define SET_TEM_DDR (TEM_DDR|=(1<<TEM_SDT))
#define CLR_TEM_DDR (TEM_DDR&=~(1<<TEM_SDT))
#define CHECK_TEM_SDT (TEM_PIN&(1<<TEM_SDT))
/*************************************************************
**
**
**串口和液晶屏
**
**
*************************************************************/
/******************************uart0初始化*********************************/
void uart0_init(void)
{
UCSR0B=0x00; //关闭UART00
UCSR0A=0x00; //不使用倍速发送(异步)
UCSR0C=0x06; //数据位为8位
UBRR0L=103; //波特率9600
UBRR0H=0x00; //误差率0.156%
UCSR0B=0x98; //发送接收使能,接收结束使能
}
/***************************uart0发送单字节数据****************************/
void putchar0(unsigned char c)
{
while (!(UCSR0A&(1<<UDRE0)));//表明发送器已经准备就绪
UDR0=c; //将要发送的数据装入UDR0寄存器
}
/*****************************LCD显示函数***********************************/
void LCD_display(unsigned char i,unsigned char j)
{
putchar0(0x5A);
putchar0(0xA5);
putchar0(0x05);
putchar0(0x82);
putchar0(0x00); //地址高位
putchar0(i); //地址低位
putchar0(0x00); //数据高位
putchar0(j); //数据低位
WDR();
}
/*************************************************************
**
**
**延时函数
**
**
**************************************************************/
void delay2_1us(void)//延时1us
{
NOP();
NOP();
NOP();
NOP();
}
void delay1_1us(void) //940ns
{
NOP();
}
void delay1_nus(unsigned int n) //N us延时函数
{
unsigned int i=0;
for(i=0;i<n;i++)
{
delay1_1us();
}
}
void delay10us(unsigned int n) //n=10 ,10us延时函数
{
unsigned int i=0;
for(i=0;i<n;i++)
{
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
}
}
void delay(unsigned int k)
{
unsigned int n;
n = 0;
while(n<k)
{
n++;
}
return;
}
void delay6(unsigned char x,unsigned char y)
{
unsigned char z;
do{
z = y;
do
{
;
}
while(--z);
}
while(--x);
}
void delay5(unsigned int count) //count=13,1ms延时子函数
{
unsigned int i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void delay1(void) //延时大约1秒(较精确)
{
unsigned int x;
unsigned int y;
for(x=0;x<1000;x++)
{
for(y=0;y<2286;y++)
{
WDR();
}
WDR();
}
}
/**************************************************************
** 函数名称: void init_1820(void)
** 功能描述: 18b20初始化
** 输 入: 无
** 全局变量: 无
** 调用模块: 无
** 说明:
** 注意:
**************************************************************/
void init_1820(void)
{
TEM_DDR &=~ (1<<TEM_SDT);
SET_TEM_DDR; //设置数据端口为输出
SET_TEM_SDT;
CLR_TEM_SDT;
delay1_nus(600); //480us以上(530us)
SET_TEM_SDT;
CLR_TEM_DDR;
delay10us(10);
delay10us(10); //15~60us (20us)
while(CHECK_TEM_SDT);
SET_TEM_DDR;
SET_TEM_SDT;
delay6(5,50); //60~240us (97us)
}
/**************************************************************
** 函数名称: void write_1820(unsigned char data)
** 功能描述: 向18b20写入1B的数据
** 输 入: unsigned char data 要写入的数据
** 全局变量: 无
** 调用模块: 无
** 说明:
** 注意:
**************************************************************/
void write_1820(unsigned char data)
{
unsigned char i;
for(i=0;i<8;i++)
{
//SET_TEM_SDT;
CLR_TEM_SDT; //从高到低,产生写间隙
if(data&(1<<i)) //写数据,先写低位
SET_TEM_SDT;
else
CLR_TEM_SDT;
delay6(2,60); //15~60us (46us)
SET_TEM_SDT;
data>>=1;
}
SET_TEM_SDT;
}
/**************************************************************
** 函数名称: unsigned char read_1820(void)
** 功能描述: 从18b20读出1B的数据
** 输 入: 无
** 全局变量: 无
** 调用模块: 无
** 说明:
** 注意:
**************************************************************/
unsigned char read_1820(void)
{
unsigned char temp,k,n;
temp=0;
for(n=0;n<8;n++)
{
//SET_TEM_DDR; //设为输出
CLR_TEM_SDT;
temp>>=1;
SET_TEM_SDT; //从高到低再到高,产生读间隙
CLR_TEM_DDR; //设为输入
k=CHECK_TEM_SDT; //读数据,从低位开始
if(k)
temp|=(1<<n);
else
temp&=~(1<<n);
delay1_nus(100); //60~120us(82us)
SET_TEM_DDR; //设为输出
}
return (temp);
}
/**************************************************************
** 函数名称: unsigned char gettemp(void)
** 功能描述: 返回温度值
** 输 入: 无
** 全局变量:
** 调用模块: 无
** 说明:wmh为温度的高位,wml为温度的低位,返回值为温度值,范围0~99摄氏度,字符型
** 注意:
**************************************************************/
unsigned char gettemp(void) //读取温度值
{
unsigned char temh,teml,wm0,wm1,wm2,wm3,wmh,wml,temp;
init_1820(); //复位18b20
write_1820(0xCC); // 跳过ROM
write_1820(0x44); // 温度变换
init_1820();
write_1820(0xCC); // 跳过ROM
write_1820(0xbe); // 写暂存存储器
teml=read_1820(); //读数据
temh=read_1820();
wm0=teml>>4; //只要高8位的低四位和低8位的高四位,温度范围0~99
wm1=temh<<4;
wm2=wm1+wm0; //16进制转10进制
wm3=wm2/100;
wmh=(wm2%100)/10; //wmh是显示的高位,wml是显示的低位
wml=(wm2%100)%10;
temp=wmh*10+wml;
return temp;
}
/**************************************************************
**
**
**主函数
**
**
***************************************************************/
void main(void)
{
unsigned char temp1=0;
init_1820();
while(1)
{
temp1=gettemp();
LCD_display(0x0A,temp1);
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
我的程序其实是有中断的 ,但是我现在只想测试18B20,所以我只写了这一部分,其他部分都去掉了,所以没有中断存在,我用的ICCAVR,延时都是自己写的,也通过高低电平变化测过时间。
一周热门 更多>