ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU

[STM8] 求解stm8控制18b20程序~

[复制链接]
3133|11
 楼主 | 2012-7-9 20:53 | 显示全部楼层 |阅读模式
程序执行后四位数码管全部显示为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);//*/
}
}
| 2012-7-9 21:07 | 显示全部楼层
你的宏不用括号括起来?
 楼主 | 2012-7-9 21:18 | 显示全部楼层
宏定义语法没有错误,我也感觉是宏定义这里除了问题呢,不知道具体原因在哪……谢谢。……
| 2012-7-9 21:33 | 显示全部楼层
这个估计是显示没问题,你的18B20读写有问题
 楼主 | 2012-7-9 21:54 | 显示全部楼层
恩,显示早就测试过了,没问题,问题确实是出在读写上,但不知道出在哪……谢谢……
| 2012-7-10 09:51 | 显示全部楼层
看代码找错,纯属事倍功半的工作。建议LZ用示波器抓波形,检查一下波形问题在哪,这属于事半功倍的事情。
 楼主 | 2012-7-11 20:24 | 显示全部楼层
本帖最后由 zhixiaoyuhong 于 2014-4-22 11:11 编辑

嗯嗯嗯,谢谢……
| 2018-1-11 17:23 | 显示全部楼层
需要这个程序
| 2018-1-12 21:14 | 显示全部楼层
时,序,不对,吧,示波,器,逻,辑,分,析仪观,察一下。
| 2018-1-12 21:14 | 显示全部楼层
我上面的话,怎么说有违禁词汇。。。。
| 2018-1-14 15:59 | 显示全部楼层
  1. void _delay_us(u8 us)
  2. {
  3.         while(--us);
  4. }

  5. //-----复位-----
  6. void resetOnewire(void)
  7. {
  8.         OUT_DQ();
  9.         CLR_DQ();
  10.         _delay_us(750);
  11.         SET_DQ();
  12.         _delay_us(100);
  13.         IN_DQ();
  14.         //while(GET_DQ());
  15.         while(!(GET_DQ()));
  16.         SET_DQ();
  17. }

  18. //-----读数据-----
  19. u8 rOnewire(void)
  20. {
  21.         u8 data=0,i=0;
  22.          for(i=0;i<8;i++)
  23.         {
  24.                 data=data>>1;
  25.                 OUT_DQ();
  26.                 CLR_DQ();
  27.                 IN_DQ();
  28.                 if(GET_DQ()) data|=0x80;
  29.                 else while(!(GET_DQ()));
  30.                 _delay_us(60);
  31.         }
  32.         return(data);
  33. }
  34. //-----写数据-----
  35. void wOnewire(u8 data)
  36. {
  37.         u8 i=0;
  38.         OUT_DQ();
  39.         for(i=0;i<8;i++)
  40.         {
  41.                 CLR_DQ();
  42.                 if(data&0x01)
  43.                 {
  44.                 SET_DQ();
  45.                 }
  46.                 else
  47.                 {
  48.                 CLR_DQ();
  49.                 }
  50.                 data=data>>1;
  51.                 _delay_us(60);  //65
  52.                 SET_DQ();
  53.         }
  54. }

  55. //-----DS18B20转换温度-----
  56. void convertDs18b20(void)
  57. {
  58.         resetOnewire();
  59.         wOnewire(0xcc);
  60.         wOnewire(0x44);
  61. }
  62. //------------DS18BB0读温度----------
  63. u8 readTemp(void)
  64. {
  65.         u8 temp1,temp2;
  66.         convertDs18b20();
  67.         resetOnewire();
  68.         wOnewire(0xcc);
  69.         wOnewire(0xbe);        
  70.         temp1=rOnewire();
  71.         temp2=rOnewire();
  72.         temp2=temp2<<4;
  73.         temp1=temp1>>4;
  74.         temp2|=temp1;
  75.         return (temp2&0x7F);
  76. }
复制代码
| 2018-1-14 15:59 | 显示全部楼层
以下转载

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

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

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