打印
[STM8]

stm8控制18b20程序

[复制链接]
1318|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhenykun|  楼主 | 2021-9-12 13:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序执行后四位数码管全部显示为0,另外,程序中延时可保证完全正确,求高手找错,谢谢……
#include<stm8s103f3p.h>
#define ui unsigned int
#define uc unsigned char
#define DQ_HIGH() PD_DDR|=0x40; PD_CR1|=0x40;PD_ODR|=0x40
#define DQ_LOW() PD_DDR|=0x40; PD_CR1|=0x40;PD_ODR&=0xbf
#define DQ_IN() PD_DDR&=0xbf;PD_CR1|=0x40
uc const table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f};
uc const table0[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
uc temp1,temp2;
ui temp;
void delay(ui jx,ui jy)
{
ui x,y;
for(x=jx;x>0;x--);
for(y=jy;y>0;y--);
}
void init(void)
{
CLK_CKDIVR=0;
PA_DDR=0xff;
PA_CR1=0xff;
PA_ODR=0;

PC_DDR=0xff;
PC_CR1=0xff;
PC_ODR=0;

PD_DDR=0x4f;
PD_CR1=0x4f;
PD_ODR=0;

PA_CR2=0;
PC_CR2=0;
PD_CR2=0;
}
void pro(uc jp)
{
PC_ODR=jp;
PA_ODR=jp<<1;
}
void reset(void)
{
uc jf=1;
DQ_HIGH();
delay(1,1);
// while(jf)
//{
  DQ_LOW();
  delay(1000,150);//721us
  DQ_HIGH();
  delay(100,10);//71
  DQ_IN();
  if(PD_IDR&0x40==0x40)
  {
   jf=1;
  }
  else
   jf=0;
  delay(600,200);//502us///////////
//}
// DQ_HIGH();
}
void writebyte(uc dat)
{
uc i;
  DQ_HIGH();
  delay(1,1);
for(i=0;i<8;i++)
{
  DQ_LOW();
  delay(4,15);//14us
  if(dat&0x01)
  {
   DQ_HIGH();
  }
  delay(70,5);//49
  DQ_HIGH();
  delay(1,1);
  dat=dat>>1;
}
}
uc readbyte(void)
{
uc i,val;
for(i=0;i<8;i++)
{
  val=val>>1;
  DQ_HIGH();
  delay(1,1);//3
  DQ_LOW();
  delay(1,1);delay(1,1);
  DQ_HIGH();
  delay(1,1);//3
  DQ_IN();
  if(PD_IDR&0x40==0x40)
  {
   val=val|0x80;
  }
  delay(70,5);//49
}
return val;
}
void display(ui jd)
{
uc bai,shi,ge,dian;
bai=jd/1000;
shi=jd%1000/100;
ge=jd%100/10;
dian=jd%10;
PD_ODR&=0xf0;
pro(table[bai]);
   delay(25,15);
PD_ODR+=0x02;
pro(table0[shi]);
   delay(25,15);
PD_ODR+=0x02;
pro(table[ge]);
   delay(25,15);
PD_ODR+=0x02;
pro(table[dian]);
   delay(25,15);
}
void get(void)
{
ui jn;
reset();
delay(1,1);
writebyte(0xcc);
delay(1,0);
writebyte(0x44);
for(jn=6500;jn>0;jn--)
   display(temp);//
reset();
  delay(1,1);
writebyte(0xcc);
  delay(1,0);
writebyte(0xbe);
delay(1,1);
temp1=readbyte();
  delay(1,0);
temp2=readbyte();
delay(5,5);
temp=((temp2<<8)+temp1)*6.25;
}
main()
{
init();
while (1)
{
  get();
/*  delay(1000,150);//721us
  delay(100,10);//71
  delay(600,200);//502us///////////
  delay(4,15);//14us
  delay(70,5);//49
   for(jn=6500;jn>0;jn--)
   display(temp);//*/
}
}

使用特权

评论回复
沙发
yszong| | 2021-9-12 13:16 | 只看该作者
你的宏不用括号括起来?

使用特权

评论回复
板凳
zhenykun|  楼主 | 2021-9-12 13:19 | 只看该作者
宏定义语法没有错误,我也感觉是宏定义这里除了问题呢,不知道具体原因在哪……谢谢。……

使用特权

评论回复
地板
heweibig| | 2021-9-12 13:21 | 只看该作者
这个估计是显示没问题,你的18B20读写有问题

使用特权

评论回复
5
zhenykun|  楼主 | 2021-9-12 13:24 | 只看该作者
恩,显示早就测试过了,没问题,问题确实是出在读写上,但不知道出在哪……谢谢……

使用特权

评论回复
6
chuxh| | 2021-9-12 13:26 | 只看该作者
看代码找错,纯属事倍功半的工作

使用特权

评论回复
7
supernan| | 2021-9-12 13:28 | 只看该作者
建议LZ用示波器抓波形,检查一下波形问题在哪

使用特权

评论回复
8
shimx| | 2021-9-12 13:30 | 只看该作者
这属于事半功倍的事情

使用特权

评论回复
9
jiaxw| | 2021-9-12 13:33 | 只看该作者
需要这个程序

使用特权

评论回复
10
juventus9554| | 2021-9-12 13:40 | 只看该作者
时,序,不对,吧,示波,器,逻,辑,分,析仪观,察一下。

使用特权

评论回复
11
renyaq| | 2021-9-12 13:42 | 只看该作者
本帖最后由 renyaq 于 2021-9-12 13:45 编辑

这么多逗号

使用特权

评论回复
12
jiajs| | 2021-9-12 13:45 | 只看该作者
void _delay_us(u8 us)

{

        while(--us);

}



//-----复位-----

void resetOnewire(void)

{

        OUT_DQ();

        CLR_DQ();

        _delay_us(750);

        SET_DQ();

        _delay_us(100);

        IN_DQ();

        //while(GET_DQ());

        while(!(GET_DQ()));

        SET_DQ();

}



//-----读数据-----

u8 rOnewire(void)

{

        u8 data=0,i=0;

         for(i=0;i<8;i++)

        {

                data=data>>1;

                OUT_DQ();

                CLR_DQ();

                IN_DQ();

                if(GET_DQ()) data|=0x80;

                else while(!(GET_DQ()));

                _delay_us(60);

        }

        return(data);

}

//-----写数据-----

void wOnewire(u8 data)

{

        u8 i=0;

        OUT_DQ();

        for(i=0;i<8;i++)

        {

                CLR_DQ();

                if(data&0x01)

                {

                SET_DQ();

                }

                else

                {

                CLR_DQ();

                }

                data=data>>1;

                _delay_us(60);  //65

                SET_DQ();

        }

}



//-----DS18B20转换温度-----

void convertDs18b20(void)

{

        resetOnewire();

        wOnewire(0xcc);

        wOnewire(0x44);

}

//------------DS18BB0读温度----------

u8 readTemp(void)

{

        u8 temp1,temp2;

        convertDs18b20();

        resetOnewire();

        wOnewire(0xcc);

        wOnewire(0xbe);         

        temp1=rOnewire();

        temp2=rOnewire();

        temp2=temp2<<4;

        temp1=temp1>>4;

        temp2|=temp1;

        return (temp2&0x7F);

}

使用特权

评论回复
13
juventus9554| | 2021-9-12 13:47 | 只看该作者
以下转载

这个18b20的STM8s的调试可是破费周折。我是在51的基础上改的,本来很简单的程序,改好了却不知道问题出在哪里,要不是初始化不成功,就是读取的温度值是0xFFFF。
从51改过来要注意以下几个问题。
1、首先是IO口的问题。
51的IO口是双向的,而STM8的IO口要不断的配置成输入或输出,比较麻烦。另外,注意用库函数时IO口方切换时会占用很多时间,最好用寄存器的配置方法。
2、关于三个时序的问题,包括初始化、读和写。这个最好严格按照芯片说明的时序来写。
3、最最重要的是IO口的是输出配置一定要配置成低速(即2MHz),也是这个问题一直困扰我了很久。本来以为IO口越快越好的,可是就是这个问题大大浪费了我几天的时间,应该是速度快了,对18b20的干扰也大了,所以芯片工作不正常。因此并不是速度越快越好。
4、测量和调试时序时,一个很重要的调试方法就是用定时器测指令或者延时所用的时间,这样我们可以在没有示波器的条件下知道自己的芯片时序是否符合要求。
5、要善用宏定义,这样可以使程序看起来更简洁,调试起来更方便。有时为了插入一段很长的调试程序(像定时器测量程序)时,用宏定义可以大大简化调试程序的编写。

使用特权

评论回复
14
zhenykun|  楼主 | 2021-9-12 13:50 | 只看该作者

明白了,多谢大家讨论这么多哈

使用特权

评论回复
15
wowu| | 2021-10-9 09:18 | 只看该作者
这个是二总线的吗

使用特权

评论回复
16
paotangsan| | 2021-10-9 09:27 | 只看该作者
我当时调试这个老费劲了

使用特权

评论回复
17
renzheshengui| | 2021-10-9 09:28 | 只看该作者
感觉用自带的那个iic接口不好用

使用特权

评论回复
18
wakayi| | 2021-10-9 09:30 | 只看该作者
不是二总线 是iic总线

使用特权

评论回复
19
xiaoqizi| | 2021-10-9 09:32 | 只看该作者
每一个应答的时序都不可有错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

868

主题

11535

帖子

3

粉丝