搜索
bottom↓
回复: 3

利用hhrfjz 的程序,在winavr-20050214下加入串口部分,采集18B20的温度程序(感谢原作者)

[复制链接]

出0入0汤圆

发表于 2007-10-12 16:27:39 | 显示全部楼层 |阅读模式
/*********************************************************************
*文件名:main.c
*功能:DS18B20温度采集
*硬件环境:atmega128L ,8M
*********************************************************************/
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#define CL_DQ PORTE&=~(1<<PE0)
#define SET_DQ PORTE|=(1<<PE0)
#define SET_OUT DDRE|=(1<<PE0)
#define SET_IN  DDRE&=~(1<<PE0)
#define IN_DQ  PINE&(1<<PE0)

#define uchar unsigned char
//#definde uint unsigned int

const unsigned char buffer[]="wellcome";

void Delay_1us(void)                 //1us延时函数
  {
   asm("nop");
  }

void Delay_nus(unsigned int n)       //N us延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   Delay_1us();
  }


void write_1820(uchar x)
{  uchar m;   
    cli();
    for(m=0;m<8;m++)
    {
      CL_DQ;
       if(x&(1<<m))    //写数据,从低位开始
       {Delay_nus(2);SET_DQ; }
       else
      CL_DQ;
       Delay_nus(60);   //15~60us
      SET_DQ;
           Delay_nus(10);
    }
    SET_DQ;
        sei();
}
uchar read_1820()
{   uchar temp,k,n;  
    cli();
  temp=0;
    for(n=0;n<8;n++)
       {
      CL_DQ;
     //Delay_nus(2);      
      SET_DQ;
      //delay(3);     
      SET_IN;
          Delay_nus(1);
      k=IN_DQ;    //读数据,从低位开始
      if(k)
      temp|=(1<<n);
      else
      temp&=~(1<<n);
      Delay_nus(70); //60~120us     
      SET_OUT;
   }
   sei();
   return (temp);
}


void init_1820(void)
{cli();
SET_OUT;
  SET_DQ;//输出1
  CL_DQ;
  Delay_nus(550);//拉低一段时间
  SET_DQ;//释放
  SET_IN;//输入
  Delay_nus(60);
  while(IN_DQ)  {;}//等待回复
  Delay_nus(240);//回复的低电平在60到240US
  SET_OUT;
  SET_DQ;//回到初始DQ=1;
  sei();
}

void USART_Init( void)
{
/* 设置波特率*/
UBRR1H = 0x00;
UBRR1L = 51;
/* 接收器与发送器使能*/
UCSR1B = (1<<RXEN1)|(1<<TXEN1);
/* 初始化后,默认设置帧格式: 8 个数据位, 1个停止位*/
}

void USART_Transmit( unsigned char data )
{
/* 等待发送缓冲器为空 */
while ( !( UCSR1A & (1<<UDRE1)) )
;
/* 将数据放入缓冲器,发送数据 */
UDR1 = data;
}

// 数据接收【以5 到8 个数据位的方式接收数 据帧】
unsigned char USART_Receive( void )
{
/* 等待接收数据*/
while ( !(UCSR1A & (1<<RXC1)) )
;
/* 从缓冲器中获取并返回数据*/
return UDR1;
}


int main(void) //主函数
{
  unsigned int j,tem;
unsigned char a,b,c;


unsigned char i=0;
        uchar temh,teml;
  


USART_Init(); //波特率9600 初始化串口

for(i=0;i<8;i++) //发送数组里面的字符串
{
USART_Transmit(buffer);
}

USART_Transmit(0x0d); //发送一个回车
USART_Transmit(0x0a); //发送一个换行
while(1)
{                
    init_1820();  //复位18b20
    write_1820(0xcc);   // 发出转换命令 搜索器件
    write_1820(0x44);     //启动
    for(j=1000;j>1;j--)
        Delay_nus(1000);//转换一次12位的 最多750MS
    init_1820();
    write_1820(0xcc);  //发出读命令
    write_1820(0xbe);
       
    teml=read_1820();  //读数据
    temh=read_1820();
        tem=(teml>>4)+(temh<<4);
        Delay_nus(1000);
   //tmp=96;
        a=tem/100+0x30;
        b=tem%100/10+0x30;
        c=tem%10+0x30;
        //for(i=0;i<200;i++);
        USART_Transmit(a);
        USART_Transmit(b);
        USART_Transmit(c);
    USART_Transmit(0x0d);
    USART_Transmit(0x0a);       
}
}
头像被屏蔽

出0入0汤圆

发表于 2007-10-12 19:19:21 | 显示全部楼层
非常感谢。如果能提供一下电路图或电路的连接描述就更好。

出0入0汤圆

 楼主| 发表于 2007-10-12 21:46:15 | 显示全部楼层
串口和温度传感器电路图如下:
其中串口使用的是串口1,18B20接PE0
该程序非常好,对温度的采集可以精确到0.0625 摄氏度

出0入0汤圆

发表于 2008-3-15 17:22:44 | 显示全部楼层
.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-2 22:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表