|
调了2天了,终于将DS2438调通了,着这里说说经验。其实说白了就是个时序问题,但是要注意两点:1>1-wire总线的复位和读写时间问题(这个相信做过的人一般都没有问题);2>DS2438内部AD转换的时间问题(这个问题大家可能容易忽视)。在坛子里看过别人的程序,在其他网站上也找过程序,有很多人有这样的问题,就是采温度是准确的,采电压不正确,其实这就是忽视了DS2438的内部ADC转换时间的问题。其内部的电压采样用的是10bit的ADC,转换时间是10ms左右!!!电流采样的ADC是16bit的,采样时间是274.6ms左右(采样频率36.41HZ),所以启动AD转换之后一定等到转换完毕才去读取数据,这样才不会出错。我要采的电流范围是-60A~+60A,不知道这个芯片行不行,按计算用2m欧的电阻可以保证电压在其标称极限值-125mV~+125mV范围之内,晚上试试实际效果怎样。下面是在LPC2132上调试通过的代码:
#define PORTADDRESS 1<<14
#define MOVE 14
#define R 0.025
// Pause for exactly 'tick' number of ticks = 0.25us
void tickDelay(uint16 tick) // Implementation is platform specific
{
while(tick--)
{
_nop_();
}
}
// 'tick' values
int A,B,C,D,E,F,G,H,I,J;
#define MK 4
//-----------------------------------------------------------------------------
// Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0).
//
void SetSpeed(int standard)
{
// Standard Speed
A = 6 * MK; //6us
B = 64 * MK; //64us
C = 60 * MK; //60
D = 10 * MK; //10
E = 9 * MK; //9
F = 55 * MK; //55
G = 2; //0
H = 480 * MK;//480
I = 70 * MK; //70
J = 410 * MK;//410
/* A = 1.5 * MK;
B = 7.5 * MK;
C = 7.5 * MK;
D = 2.5 * MK;
E = 0.75 * MK;
F = 7 * MK;
G = 2.5 * MK;
H = 70 * MK;
I = 8.5 * MK;
J = 40 * MK;*/
}
// send 'databyte' to 'port'
void outp(unsigned port, int databyte)
{
//设置为输出
IO0DIR |= port;
//输出一个bit
if(databyte)
IO0SET |= port;
else
IO0CLR |= port;
}
// read byte from 'port'
int inp(unsigned port)
{
int i;
//设置为输入
IO0DIR &= ~port;
//读出一个bit
_nop_();
_nop_();
_nop_();
_nop_();
i = (IO0PIN & port)>>MOVE;
//设置为输出
IO0DIR |= port;
return i;
}
//-----------------------------------------------------------------------------
// Generate a 1-Wire reset, return 1 if no presence detect was found,
// return 0 otherwise.
// (NOTE: Does not handle alarm presence from DS2404/DS1994)
//
int OWTouchReset(void)
{
uint32 result;
tickDelay(G);
outp(PORTADDRESS,0x00); // Drives DQ low
tickDelay(H);
outp(PORTADDRESS,0x01); // Releases the bus
tickDelay(I);
result = inp(PORTADDRESS); // Sample for presence pulse from slave
tickDelay(J); // Complete the reset sequence recovery
if(result)
return 1;//失败
else
return 0;//成功 // Return sample presence pulse result
}
//-----------------------------------------------------------------------------
// Send a 1-Wire write bit. Provide 10us recovery time.
//
void OWWriteBit(int bit)
{
if (bit)
{
// Write '1' bit
outp(PORTADDRESS,0x00); // Drives DQ low
tickDelay(A);
outp(PORTADDRESS,0x01); // Releases the bus
tickDelay(B); // Complete the time slot and 10us recovery
}
else
{
// Write '0' bit
outp(PORTADDRESS,0x00); // Drives DQ low
tickDelay(C);
outp(PORTADDRESS,0x01); // Releases the bus
tickDelay(D);
}
}
//-----------------------------------------------------------------------------
// Read a bit from the 1-Wire bus and return it. Provide 10us recovery time.
//
int OWReadBit(void)
{
int result;
outp(PORTADDRESS,0x00); // Drives DQ low
tickDelay(A);
outp(PORTADDRESS,0x01); // Releases the bus
tickDelay(E);
result = inp(PORTADDRESS) & 0x01; // Sample the bit value from the slave
tickDelay(F); // Complete the time slot and 10us recovery
return result;
}
//-----------------------------------------------------------------------------
// Write 1-Wire data byte
//
void OWWriteByte(uint8 data)
{
uint8 loop,i;
// Loop to write each bit in the byte, LS-bit first
for (loop = 0; loop < 8; loop++)
{
//OWWriteBit(data & 0x01);
i = data&0x01;
if (i)
{
// Write '1' bit
outp(PORTADDRESS,0); // Drives DQ low
tickDelay(A);
outp(PORTADDRESS,1); // Releases the bus
tickDelay(B); // Complete the time slot and 10us recovery
}
else
{
// Write '0' bit
outp(PORTADDRESS,0); // Drives DQ low
tickDelay(C);
outp(PORTADDRESS,1); // Releases the bus
tickDelay(D);
} // shift the data byte for the next bit
data = data>>1;
}
}
//-----------------------------------------------------------------------------
// Read 1-Wire data byte and return it
//
uint8 OWReadByte(void)
{
uint8 loop, result=0,i;
for (loop = 0; loop < 8; loop++)
{
// shift the result to get it ready for the next bit
result >>= 1;
outp(PORTADDRESS,0x00); // Drives DQ low
tickDelay(A);
outp(PORTADDRESS,0x01); // Releases the bus
tickDelay(E);
i = (inp(PORTADDRESS) & 0x01); // Sample the bit value from the slave
if(i)
result |= 0x80;
tickDelay(F); // Complete the time slot and 10us recovery
}
return result;
}
//-----------------------------------------------------------------------------
// Write a 1-Wire data byte and return the sampled result.
//
int OWTouchByte(int data)
{
int loop, result=0;
for (loop = 0; loop < 8; loop++)
{
// shift the result to get it ready for the next bit
result >>= 1;
// If sending a '1' then read a bit else write a '0'
if (data & 0x01)
{
if (OWReadBit())
result |= 0x80;
}
else
OWWriteBit(0);
// shift the data byte for the next bit
data >>= 1;
}
return result;
}
//-----------------------------------------------------------------------------
// Write a block 1-Wire data bytes and return the sampled result in the same
// buffer.
//
void OWBlock(unsigned char *data, int data_len)
{
int loop;
for (loop = 0; loop < data_len; loop++)
{
data[loop] = OWTouchByte(data[loop]);
}
}
//-----------------------------------------------------------------------------
// Set all devices on 1-Wire to overdrive speed. Return '1' if at least one
// overdrive capable device is detected.
//
int OWOverdriveSkip(unsigned char *data, int data_len)
{
// set the speed to 'standard'
SetSpeed(1);
// reset all devices
if (OWTouchReset()) // Reset the 1-Wire bus
return 0; // Return if no devices found
// overdrive skip command
OWWriteByte(0x3C);
// set the speed to 'overdrive'
SetSpeed(0);
// do a 1-Wire reset in 'overdrive' and return presence result
return OWTouchReset();
}
//-----------------------------------------------------------------------------
// Read and return the page data and SHA-1 message authentication code (MAC)
// from a DS2432.
//
uint8 ReadPageMAC(uint8 page, uint8 *page_data, uint8 *mac)
{
uint8 i;
unsigned short data_crc16, mac_crc16;
// select the device
if (OWTouchReset()) // Reset the 1-Wire bus
return 0; // Return if no devices found
OWWriteByte(0xCC); // Send Skip ROM command to select single device
// read the page
OWWriteByte(0xA5); // Read Authentication command
OWWriteByte((page << 5) & 0xFF); // TA1
OWWriteByte(0); // TA2 (always zero for DS2432)
// read the page data
for (i = 0; i < 32; i++)
page_data = OWReadByte();
OWWriteByte(0xFF);
// read the CRC16 of command, address, and data
data_crc16 = (uint16)OWReadByte();
data_crc16 |= (uint16)(OWReadByte() << 8);
// delay 2ms for the device MAC computation
// read the MAC
for (i = 0; i < 20; i++)
mac = OWReadByte();
// read CRC16 of the MAC
mac_crc16 = (uint16)OWReadByte();
mac_crc16 |= (uint16)(OWReadByte() << 8);
// check CRC16...
return 1;
}
uint8 initcommand(void)
{
unsigned char i=1,cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0x4E); // Write Scratchpad
OWWriteByte(0x00); // Write Page
OWWriteByte(0x07); // Write Cortrol
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratchpad
OWWriteByte(0x00); // Read 0th Page
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0x48); // Read Scratch Pad to Memory
OWWriteByte(0x00); // Copy 0th Page
tickDelay(250);
tickDelay(250);
tickDelay(250);
tickDelay(250);
/*unsigned char i=1,cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0x4E); // Write Scratchpad
OWWriteByte(0x00); // Write Page
OWWriteByte(0x07); // Write Cortrol
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratchpad
OWWriteByte(0x00); // Read 0th Page
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0x48); // Read Scratch Pad to Memory
OWWriteByte(0x00); // Copy 0th Page
tickDelay(20);
return 1;*/
}
//读取当前电池温度
uint16 Read_Temperature(void)
{
unsigned char g[9];
unsigned char i=1,j,cnt=0;
uint16 u;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); //Skip ROM
OWWriteByte(0x44); // Start Conversion
tickDelay(10);
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); //READ SCRATCHPAD
OWWriteByte(0x00); //READ 0TH PAGE
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratch Pad
OWWriteByte(0x00);
for(j=0;j<9;j++)
{
g[j]=OWReadByte();
}
u=((g[2]&0x7f)*256+g[1]);
return (u);
}
//读取电压转换值
uint16 Read_Voltage(void)
{
uint8 b[9];
unsigned char i=1,j,cnt=0;
uint16 m;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB4); //WRITE VOLTAGE CORTROL
tickDelay(100);
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); //READ SCRATCHPAD
OWWriteByte(0x00); //READ 0TH PAGE
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); //READ SCRATCHPAD
OWWriteByte(0x00); //READ 0TH PAGE
for(j=0;j<9;j++)
{
b[j]=OWReadByte();
}
for(j=0;j<9;j++)
uart0_send_hex(b);
uart0_send_str(&quot;\r\n&quot;);
m=((b[4]&0x03)*256+b[3])*0.01;
return (m);
/*unsigned char g[9];
unsigned char i=1,j,cnt=0;
uint16 u;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); //Skip ROM
OWWriteByte(0xB4); // Start Conversion
tickDelay(90);
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
tickDelay(5);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); //READ SCRATCHPAD
OWWriteByte(0x00); //READ 0TH PAGE
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratch Pad
OWWriteByte(0x00);
for(j=0;j<9;j++)
{
g[j]=OWReadByte();
}
for(j=0;j<9;j++)
uart0_send_hex(g);
uart0_send_str(&quot;\r\n&quot;);
u=(uint16)((g[4]&0x03)<<8+g[3]);
return (u); */
}
//读当前电流
unsigned char Read_Current(void)
{
unsigned char c[9];
unsigned char i=1,j,cnt=0;
float n;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); // Read Scratchpad
OWWriteByte(0x00); // Read 0th Page
i=1;
cnt=0;
while(i)
{
i=OWTouchReset();
if(cnt++>10)
return 0;
}
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratchpad
OWWriteByte(0x00); // Read 0th Page
for(j=0;j<9;j++)
{
c[j]=OWReadByte();
}
n=((c[6]&0x03)*256+c[5])/(4096*R);
return (n);
}
uint8 ds2438_memory_recall(uint8 page)
{
uint8 result;
if(page > 7)
return 0;
result = OWTouchReset();
if(result)
{
OWWriteByte(0xCC); // Skip ROM
//recall该page中的内容到scratchpad
OWWriteByte(0xB8); // Read Scratchpad
}
return result;
}
uint8 ds2438_memory_readscratchpad(uint8 page,uint8 *data)
{
uint8 result;
if(page > 7)
return 0;
result = OWTouchReset();
if(result)
{
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratchpad
OWReadByte();
} |
|