9935|11

77

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

关于精华贴<DS18B20源程序>的问题 [复制链接]

最近在测试MSP430上读写DS18B20。有幸得到lsdfae04的代码。发现问题多多~

第一:正如后面的跟贴,硬件不详。见"uutjf1"的跟贴。
第二:一个错误,
unsigned int read_data(void)
{

//unsigned char data=0,i;
unsigned int data=0,i;
//data = 0;
for(i=0;i<8;i++)
//for(i=0;i<16;i++)
{
P1OUT &= ~BIT4;
_NOP();
_NOP();
_NOP();
P1DIR &= ~BIT4;
_NOP();
if(P1IN&BIT4)
//{data |= 0x80;}
{data |= 0x0001;}
data = data<<1;
delay(23);
P1OUT |= BIT4;
P1DIR |= BIT4;
}
return data;
}
此程序中,先读再移位是很不妥的,也是个很基本的错误。正确的应该是先移位再读。修改回正确方式后,读出的结果仍然不对*_*,估计是读写的时间问题。现在看来还不能直接就用啦。

最新回复

  详情 回复 发表于 2015-7-18 11:26
 
点赞 关注

回复
举报

75

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
谢谢
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

更新DS18B20程序

经过比较,终于发现了问题。现在的结果是正确的了。
现把修改后的测试通过了的程序贴在下面,敬请继续讨论。
有问题的是两个地方,一个是先移位再读取;二是先得到的是LSB,所以应该是右移,再判断|0X80。

#include <msp430x14x.h>
//#define DELTA 256 // target DCO = DELTA*(4096) = 1048576
#define DELTA 244 // target DCO = DELTA*(4096) = 1048576

unsigned char err_flag=0;
//unsigned char result=0;
//unsigned char result1=0;
volatile unsigned int result[9];
volatile unsigned char crc8;
void Set_DCO (void);
void delay(unsigned int dd);
void delay1(unsigned char dd1);
void reset(void);
void write_command(unsigned char command);
//unsigned char read_data(void);
unsigned int read_data(void);
// TEST BUILD
static unsigned char dscrc_ta××e[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
//--------------------------------------------------------------------------
// Calculate the CRC8 of the byte value provided with the current
// global 'crc8' value.
// Returns current global crc8 value
//
unsigned char docrc8(unsigned char value)
{
// See Application Note 27
// TEST BUILD
crc8 = dscrc_ta××e[crc8 ^ value];
return crc8;
}

void main(void)
{
unsigned int lpmain;
crc8 = 0;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
Set_DCO(); // Set DCO
/*P1DIR |= 0x01; // Set P1.0 to output direction

for (;;)
{
P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR
delay(250000);
}*/

P1OUT |= BIT3;
P1DIR |= BIT3;
while(1)
{

reset();
write_command(0xcc);
write_command(0x44);
delay1(6);
crc8 = 0;
reset();
//write_command(0xcc);
//write_command(0xBE);
write_command(0x33);
for(lpmain=0;lpmain<8;lpmain++)
{
result[lpmain] = read_data();
if(lpmain<7)docrc8(result[lpmain]);
}



_NOP();
crc8 = 0;
reset();
write_command(0xcc);
write_command(0xBE);
for(lpmain=0;lpmain<9;lpmain++)
{
result[lpmain] = read_data();
if(lpmain!=8)docrc8(result[lpmain]);
}
_NOP();
result[1] = 0;
}
}

void reset(void)
{
P1OUT &= ~BIT3;
delay(150);
P1DIR &= ~BIT3;
//************************
/*delay(3);
delay(15);
if(P1IN&BIT3)
{err_flag = 1;}
else err_flag =0;*/
//*****************************

delay(9);
if(P1IN&BIT3)
{err_flag = 1;}
else err_flag =0;
delay(125);
P1OUT |= BIT3;
P1DIR |= BIT3;
}

void write_command(unsigned char command)
{
unsigned char i;
for(i=0;i<8;i++)
{
P1OUT &= ~BIT3;
if(command&0x01)
{
//delay(2);
_NOP();
_NOP();
_NOP();
_NOP();
//P1OUT |= BIT3;
P1DIR &= ~BIT3;
}
command=command>>1;
//delay(15);
delay(20);
//P1OUT |= BIT3;
P1DIR &= ~BIT3;
delay(3);
P1OUT |= BIT3;
P1DIR |= BIT3;
}
}

unsigned int read_data(void)
//unsigned int read_data(void)
{

//unsigned char data=0,i;
unsigned int data=0;
unsigned int i;
//data = 0;
for(i=0;i<8;i++)
//for(i=0;i<16;i++)
{
P1OUT &= ~BIT3;
_NOP();
_NOP();
_NOP();
P1DIR &= ~BIT3;
_NOP();
data = data>>1;
if(P1IN&BIT3)
{data |= 0x80;}
//{data |= 0x01;}

delay(23);
P1OUT |= BIT3;
P1DIR |= BIT3;
}
return data;
}




void delay(unsigned int dd)
{
unsigned int i;
for(i=0;i<dd;i++);
}




void delay1(unsigned char dd1)
{
unsigned char i;
for(i=0;i<dd1;i++)
{
delay(50000);
}
}



void delay_60us(void)
{
register unsigned int i=20;
do{
i=i-1;}while(i);


}



//------------------------------------------------------------------------------
void Set_DCO (void) // Set DCO to selected frequency
//------------------------------------------------------------------------------
{
//#define DELTA 900 // target DCO = DELTA*(4096) = 3686400
//#define DELTA 256 // target DCO = DELTA*(4096) = 1048576
//#define DELTA 64 // target DCO = DELTA*(4096) = 262144
unsigned int Compare, Oldcapture = 0;

BCSCTL1 |= DIVA_3; // ACLK= LFXT1CLK/8
CCTL2 = CM_1 + CCIS_1 + CAP; // CAP, ACLK
TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear

while (1)
{
while (!(CCIFG & CCTL2)); // Wait until capture occured
CCTL2 &= ~CCIFG; // Capture occured, clear flag
Compare = CCR2; // Get current captured SMCLK
Compare = Compare - Oldcapture; // SMCLK difference
Oldcapture = CCR2; // S××e current captured SMCLK

if (DELTA == Compare) break; // If equal, le××e "while(1)"
else if (DELTA < Compare) // DCO is too fast, slow it down
{
DCOCTL--;
if (DCOCTL == 0xFF) BCSCTL1--; // Did DCO role under?, Sel lower RSEL
}
else
{
DCOCTL++;
if (DCOCTL == 0x00) BCSCTL1++; // Did DCO role over? Sel higher RSEL
}
}
delay_60us();
CCTL2 = 0; // Stop CCR2
TACTL = 0; // Stop Timer_A
BCSCTL1 &= ~DIVA_3;
}
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

4
 

 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

5
 
的确是这样~我找到原贴后,一直苦于下载不了,尹先生马上给我用邮件发过来了,所以我得到结果后把结果告诉大家,和大家一起分享。此代码我刚才又增加了CRC8的检验部分。从网上COPY下来的一部分直接用上了。呵呵~~
现在的新主意是,不想用DCO。直接用32.768K晶振。正在考虑中……
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

6
 
32k的晶振?怎么能跟上18b20的时序速度啊?
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

7
 
的确是不行的。我看到一个汇编程序,其实他仍然是用的默认的DCO。
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

8
 
请教就太严重了呵呵~大家一起讨论讨论吧
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

9
 
顶!

问一下,这个修正后的代码能正常工作吗?是否实验通过?有谁正常使用,请给个实验报告,谢谢
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

10
 
恩 复制下来回去看看 学习学习

我用51的片子用C做过这个这个程序 LED 动态显示 正好可以比较一下

非常感谢!
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

11
 
楼主的程序我改了!去掉了CRC校验也成功了!我的时钟可是快多了啊!不解?为什么18B20的时序这么不严格啊?
#include <msp430x14x.h>
unsigned char err_flag=0; //18b20错误标志
volatile unsigned int result;
void delay(unsigned int dd);
void delay1(unsigned char dd1);
void reset(void);
void write_command(unsigned char command);
unsigned int read_data(void);
void main(void)
{
unsigned int lpmain;

WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1&=~0x80; //启动XT2(4mhz),ACLK为LTXT1(32khz)工作在低频模式,不分频
BCSCTL2|=0x88; //MCLK和SMCLK时钟源为XT2,不分频
P1OUT |= BIT2;
P1DIR |= BIT2;
while(1)
{

reset();
write_command(0xcc);
write_command(0x44);
delay(50000);
_NOP();
reset();
write_command(0xcc);
write_command(0xBE);
lpmain = read_data();
result= read_data();
result=result*256;
result=result+lpmain;
_NOP();
result = 0;
}
}

void reset(void)
{
P1OUT &= ~BIT2;
delay(150);
P1DIR &= ~BIT2;


delay(9);
if(P1IN&BIT2)
{err_flag = 1;}
else err_flag =0;
delay(125);
P1OUT |= BIT2;
P1DIR |= BIT2;
}

void write_command(unsigned char command)
{
unsigned char i;
for(i=0;i<8;i++)
{
P1OUT &= ~BIT2;
if(command&0x01)
{
_NOP();
_NOP();
_NOP();
_NOP();

P1DIR &= ~BIT2;
}
command=command>>1;
delay(20);
P1DIR &= ~BIT2;
delay(3);
P1OUT |= BIT2;
P1DIR |= BIT2;
}
}

unsigned int read_data(void)
{


unsigned int data=0;
unsigned int i;

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

{
P1OUT &= ~BIT2;
_NOP();
_NOP();
_NOP();
P1DIR &= ~BIT2;
_NOP();
data = data>>1;
if(P1IN&BIT2)
{data |= 0x80;}

delay(23);
P1OUT |= BIT2;
P1DIR |= BIT2;
}
return data;
}

void delay(unsigned int dd)
{
unsigned int i;
for(i=0;i<dd;i++);
}
 
 
 

回复

143

帖子

2

TA的资源

一粒金砂(中级)

12
 
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表