查看: 2078|回复: 0
打印 上一主题 下一主题

EasyARM1138调试18B20的成功例程与问题

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-14 21:48:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
EasyARM1138调18B20参考了例程,18B20的DQ端用1138的0口的话可以调通,改成其他口就不行了。
例程用的是PF0,可以调通,改成PF1~7或PA1~7就不行,而PA0可以调通。
总是显示: 16.1C,温度升高后变成16.2C,室温23C。
DEBUG看就是读口值时老是高电平,用的5.1K上拉。
都说是延时问题,但是我只改和口有关的值,其他语句没改怎么不行呢?

原参考网址:
http://mcublog.com/home/space.ph ... o=blog&id=18863
我的程序:

/***************************************************
为方便插线我用段位串口液晶LCD0801显示18B20
PA0-DQ(18B20),PF0\PA0口都能调通
****************************************************/


/***************************************************
用PA2口的语句用星号注释出来了,大家看看有什么问题,调不通
****************************************************/


#include  "systemInit.h"
#include  <hw_types.h>
#include  <hw_memmap.h>
#include  <hw_sysctl.h>
#include  <hw_gpio.h>
#include  <sysctl.h>
#include  <gpio.h>
#define uchar unsigned char
#define uint unsigned int

uchar display[5]={0,0,0,0,0};
uchar ditab[16]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};    //温度的小数值
uchar tplsb,tpmsb;


//宏定义LCD,CLK,DIN占PD2,PD3
#define LCD_PERIPH      SYSCTL_PERIPH_GPIOD
#define LCD_PORT        GPIO_PORTD_BASE
#define LCD_PIN_CLK     GPIO_PIN_2
#define LCD_PIN_DIN     GPIO_PIN_3
//用于位操作
#define LCD_CLK         HWREG(LCD_PORT+(GPIO_O_DATA+(LCD_PIN_CLK << 2)))
#define LCD_DIN         HWREG(LCD_PORT+(GPIO_O_DATA+(LCD_PIN_DIN << 2)))

void LCD0801(unsigned char bufdian[7],unsigned char buf[8]);


//定义18B20
#define  DQ                    GPIO_PORTA_BASE , GPIO_PIN_0

/***************************************************
#define  DQ                    GPIO_PORTA_BASE , GPIO_PIN_2
****************************************************/


void  Delay(unsigned int  ulVal);
void  Delay1(unsigned int  ulVal);
void TxReset(void);
void RxWait(void);
uchar RdBit(void);
uchar RdByte(void);
void WrByte(uchar b);
void convert(void);
void RdTemp(void);
void work_temp(void);

//  主函数(程序入口)
int main(void)
{
    jtagWait();                                             //  防止JTAG失效,重要!
    clockInit();                                            //  时钟初始化:晶振,6MHz
   
    SysCtlPeriEnable(LCD_PERIPH);                  //  使能LCD所在的GPIO端口
    GPIOPinTypeOut(LCD_PORT,LCD_PIN_CLK);          //  设置LCD所在管脚为输出
    GPIOPinTypeOut(LCD_PORT,LCD_PIN_DIN);
   
    SysCtlPeriEnable(SYSCTL_PERIPH_GPIOA);    //使能GPIOA口外设
    GPIOPinTypeOut(GPIO_PORTA_BASE ,0xff);    //GPIOA为输出
  
    uchar bai=0; //LCD百位
    uchar shi=0; //LCD十位
    uchar ge=0;  //LCD十位
    uchar xiao=0;//LCD小数
         
    //LCD需显示内容
    unsigned char lcdbufzhi[8]={0x15,0x15,1,1,3,8,0x15,0x15}; //LCD数值
                  //显示:"--1138--"
    unsigned char lcdbufdian[7]={0,0,0,0,0,0,0};              //LCD小数点
                  //显示:"--1138--"
    LCD0801(lcdbufzhi,lcdbufdian);

    for (;;)
    {
      
      convert();               //启动温度转换
      Delay1(800);             //延时800ms
      RdTemp();              //读取转换结果
      work_temp();           //温度数据处理
      GPIOPinTypeOut(GPIO_PORTA_BASE ,0xff);    //GPIO A为输出
      bai=display[3]; //百位
      shi=display[2];
      ge=display[1];
      xiao=display[0];
   
      //LCD需显示内容
      unsigned char lcdbufzhi[8]={0x15,bai,shi,ge,xiao,0x0c,0x15,0x15}; //LCD数值
                  //显示:"-XXXXC--"
      unsigned char lcdbufdian[7]={0,0,0,1,0,0,0};              //LCD小数点
                  //显示:"-XXX.XC--"
      LCD0801(lcdbufzhi,lcdbufdian);
      
    }
}


//  延时1us
void  Delay(unsigned int  ulVal)
{

  unsigned int i,j=0;
  for(i=0;i<ulval;i++)
  j++;  

}


//  延时1ms
void  Delay1(unsigned int="int"   ulVal)
{

  unsigned="unsigned"  int="int"  i,j;
  for(i=0;i<ulval;i++)
  {
    for(j=0;j<1000;j++)
    Delay(1);
  }
}

/* 产生复位脉冲初始化DS18B20 */
void TxReset(void)
{
  uint="uint"  i;
  HWREGB(0x40004400)|=0x01;          //设置DQ为输出

/***************************************************
  HWREGB(0x40004400)|=0x04;          //设置DQ为输出
****************************************************/

  GPIOPinWrite(DQ, 0);
  i= 1000;
  while="while"  (i>0)   i--;   
  GPIOPinWrite(DQ, 1);              // 产生上升沿
  i = 36;
  while (i>0)   i--;
}



/* 等待应答脉冲 */
void RxWait(void)
{
  uint i,data;
  HWREGB(0x40004400)&=~0x01;            //设置DQ为输入

/***************************************************
  HWREGB(0x40004400)&=~0x04;          //设置DQ为输入
****************************************************/

  do
  {
    data=GPIOPinRead(DQ);
    data=((data)&0x01)>>0;

/***************************************************
     data=((data)&0x04)>>2;
****************************************************/

  }
  while(data);

  do
  {
    data=GPIOPinRead(DQ);
    data=((data)&0x01)>>0;

/***************************************************
     data=((data)&0x04)>>2;
****************************************************/

  }

  while(!data);        // 检测到应答脉冲

  i = 15;
  while (i>0)   i--;

}


/* 读取数据的一位,满足读时隙要求 */
uchar RdBit(void)
{

  uint i,b;
  HWREGB(0x40004400)|=0x01;     //设置DQ为输出

/***************************************************
  HWREGB(0x40004400)|=0x04;          //设置DQ为输出
****************************************************/

  GPIOPinWrite(DQ, 0);
  i =1;
  while (i>0)   i--;
  HWREGB(0x40004400)&=~0x01;          //设置DQ为输入

/***************************************************
  HWREGB(0x40004400)&=~0x04;          //设置DQ为输入
****************************************************/

  GPIOPinWrite(DQ, 1);
  i = 15;
  while (i>0)   i--;
  b = GPIOPinRead(DQ);
  b=((b)&0x01)>>0;

/***************************************************
     b=((b)&0x04)>>2;
****************************************************/

  i = 110;
  while(i>0) i--;
  return (b);

}

/* 读取数据的一个字节 */
uchar RdByte(void)
{

  uchar i,j,b;
  b = 0;
  for (i=1;i<=8;i++)
  {
    j = RdBit();
    b = (j<<7)|(b>>1);
   // b=0xff;
  }

  return(b);
}

/* 写数据的一个字节,满足写1和写0的时隙要求 */
void WrByte(uchar b)
{

  uint i;
  uchar j,btmp;
  HWREGB(0x40004400)|=0x01;       //设置DQ为输出

/***************************************************
  HWREGB(0x40004400)|=0x04;          //设置DQ为输出
****************************************************/

  for(j=1;j<=8;j++)
  {
    btmp = b&1;
    b = b>>1;       // 取下一位(由低位向高位)
    if (btmp)
    {       /* 写1 */
      GPIOPinWrite(DQ, 0);
      i = 15;
      while(i>0) i--;   // 延时,使得15us以内拉高
      GPIOPinWrite(DQ, 1);
      i = 100;
      while(i>0) i--;   // 整个写1时隙不低于60us
    }

    else
    {       /* 写0 */
      GPIOPinWrite(DQ, 0);         
      i = 110;
      while(i>0) i--;   // 保持低在60us到120us之间
      GPIOPinWrite(DQ, 1);
      i = 15;
      while(i>0) i--;
     }
  }
}



/* 启动温度转换 */
void convert(void)
{

  TxReset();            // 产生复位脉冲,初始化DS18B20
  RxWait();         // 等待DS18B20给出应答脉冲
  Delay1(1);            // 延时
  WrByte(0xcc);     //跳过rom命令
  WrByte(0x44);     //启动温度转换命令

}



/* 读取转换结果 */
void RdTemp(void)
{

  TxReset();            // 产生复位脉冲,初始化DS18B20
  RxWait();         // 等待DS18B20给出应答脉冲
  Delay1(1);            // 延时
  WrByte(0xcc);     //跳过rom命令
  WrByte(0xbe);     //读取暂存器命令
  tplsb = RdByte(); // 温度值低位字节(其中低4位为二进制的“小数”部分)
  tpmsb = RdByte(); // 高位值高位字节(其中高5位为符号位)     
}



//温度数据处理函数
void work_temp(void)
{

  unsigned char n=0;
  if(tpmsb>127)
  {
    tpmsb=(256-tpmsb);        //负温度求补码
    tplsb=(256-tplsb);
    n=1;
  }

  display[4]=tplsb&0x0f;
  display[0]=ditab[display[4]];                     //温度的小数
  display[4]=((tplsb&0xf0)>>4)|((tpmsb&0x0f)<<4);
  display[3]=display[4]/100;                        //温度的百位
  display[1]=display[4]%100;
  display[2]=display[1]/10;                         //温度的十位
  display[1]=display[1]%10;                         //温度的个位

  if(n)
  Delay(1);             //延时10us

}   


//LCD0801驱动子程序,buf[]为数值,bufdian[]为小数点位置
void LCD0801(unsigned char buf[8],unsigned char bufdian[7])
{
...
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

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