hola amigos, como estare estancado por tiempo en el trabajo para hacer la placa, entonces empezare a poner el software, lo primero creo yo, es poner mi primera libreria, esta sera para poder leer los sensores de temperatura DS18S20, en esta version, se pueden leer n numeros de sensores dependiendo del tamaño del array, para estas librerias cree dos archivos, el de cabera 1wire.h y las funciones 1wire.c, todavia no tengo definido mis variables por typef como me recomendo anteriormente richi777, estas librerias trabajan perfectamente para un micro con un busclock de 8Mhz, ahora, como el micro que voy a trabajar estara a 48Mhz, entonces hay que cambiar el delay que tengo en ensamblador
*****************************************************************************/
static void delay_1us(unsigned int n);
/*****************************************************************************
** principal functions
*****************************************************************************/
/* ow_reset function return 0 if there any sensor*/
static char ow_reset(void);
/* read bit functions*/
static char read_bit(void);
/* write bit*/
static void write_bit(char);
/*read byte*/
static void write_byte(unsigned char);
/* read byte */
static unsigned char read_byte(void);
/* read crc configuration */
static unsigned char ow_crc( unsigned char);
/*****************************************************************************
** secundary functions
*****************************************************************************/
/*First*/
static unsigned char First(void);
/*next*/
static unsigned char Next(void);
/******************************************************************************
**
** definitions delay_us functions
******************************************************************************/
void delay_1us(unsigned int n)
{
asm {
LDHX (n)
LOOP1: AIX #-1 ;[2]
CPHX #0 ;[3]
BNE LOOP1 ;[3]
}
}
/*****************************************************************************
**
** unsigned char ow_reset(void) fundamentals for communications sensor
*****************************************************************************/
char ow_reset(void)
{
unsigned char presence;
DQ_TX=0; //reset sensor
delay_1us(470); //delay 470 us
DQ_TX=1; //high again
delay_1us(60);//delay 60 us
presence= DQ_RX;
delay_1us(460); //delay ~_ 470 us
return presence;
}
/*****************************************************************************
**
** unsigned char read_bit(void)
** reads a bit from the one-wire bus. The delay
** required for a read is 15us
*****************************************************************************/
char read_bit(void){
char i;
DQ_TX=0; //
delay_1us(1);
DQ_TX=1;
delay_1us(16);//delay for 16 us
i=DQ_RX;
return i;
}
/*****************************************************************************
**
** unsigned char write_bit(void)
** writes a bit to the one-wire bus, passed in bitval.
*****************************************************************************/
void write_bit(char bit){
if(bit){
DQ_TX=0;
delay_1us(2); //delay for 2 us
DQ_TX=1;
delay_1us(30);
}else{
DQ_TX=0;
delay_1us(30);//delay for 30us
DQ_TX=1;
delay_1us(2);
}
}
/*****************************************************************************
**
** unsigned char read_byte(void)
**
*****************************************************************************/
unsigned char read_byte(void){
unsigned char i;
unsigned char value = 0;
for (i=0;i<8;i++)
{
if(read_bit()) value|=0x01<<i; // reads byte in, one byte at a time and then
// shifts it left
delay_1us(96); // wait for rest of timeslot
}
return(value);
}
/*****************************************************************************
**
** void write_byte(unsigned char);
**
*****************************************************************************/
void write_byte(unsigned char val){
unsigned char i;
unsigned char temp;
for (i=0; i<8; i++) // writes byte, one bit at a time
{
temp = val>>i; // shifts val right 'i' spaces
temp &= 0x01; // copy that bit to temp
write_bit(temp); // write bit in temp into
}
delay_1us(80);
}
/*****************************************************************************
**
** ONE WIRE CRC
PERFORMING A CYCLIC REDUNDANCY CHECK
A cyclic redundancy check (CRC) can be
accomplished using the functions shown below and
should be included when performing the Search
ROM function.
**
*****************************************************************************/
unsigned char ow_crc( unsigned char x)
{
dowcrc = dscrc_table[dowcrc^x];
return dowcrc;
}
/*****************************************************************************
**
** second layer of functions
** FIRST NEXT AND OW_SEARCH
**
*****************************************************************************/
/*****************************************************************************
**
** FIRST
// The First function resets the current state of a ROM search and calls
// Next to find the first device on the 1-wire bus.
**
*****************************************************************************/
unsigned char First(void)
{
lastDiscrep = 0; // reset the rom search last discrepancy global
doneFlag = FALSE;
return Next(); // call Next and return its return value
}
/*****************************************************************************
**
** Next
The Next function searches for the next device on the 1-wire bus. If
// there are no more devices on the 1-wire then false is returned.
**
*****************************************************************************/
unsigned char Next(void)
{
unsigned char m = 1; // ROM Bit index
unsigned char n = 0; // ROM Byte index
unsigned char k = 1; // bit mask
unsigned char x = 0;
unsigned char discrepMarker = 0; // discrepancy marker
unsigned char g; // Output bit
unsigned char nxt; // return value
int flag;
nxt = FALSE; // set the next flag to false
dowcrc = 0; // reset the dowcrc
flag = ow_reset(); // reset the 1-wire
if(flag||doneFlag) // no parts -> return false
{
lastDiscrep = 0; // reset the search
return FALSE;
}
write_byte(0xF0); // send SearchROM command
do
// for all eight bytes
{
x = 0;
if(read_bit()==1) x = 2;
delay_1us(96);
if(read_bit()==1) x |= 1; // and its complement
if(x ==3) // there are no devices on the 1-wire
break;
else
{
if(x>0) // all devices coupled have 0 or 1
g = x>>1; // bit write value for search
else
{
// if this discrepancy is before the last
// discrepancy on a previous Next then pick
// the same as last time
if(m<lastDiscrep)
g = ((ROM[n]&k)>0);
else // if equal to last pick 1
g = (m==lastDiscrep); // if not then pick 0
// if 0 was picked then record
// position with mask k
if (g==0) discrepMarker = m;
}
if(g==1) // isolate bit in ROM[n] with mask k
ROM[n] |= k;
else
ROM[n] &= ~k;
write_bit(g); // ROM search write
m++; // increment bit counter m
k = k<<1; // and shift the bit mask k
if(k==0) // if the mask is 0 then go to new ROM
{ // byte n and reset mask
ow_crc(ROM[n]); // accumulate the CRC
n++; k++;
}
}
}while(n<8); //loop until through all ROM bytes 0-7
if(m<65||dowcrc) // if search was unsuccessful then
lastDiscrep=0; // reset the last discrepancy to 0
else
{
// search was successful, so set lastDiscrep,
// lastOne, nxt
lastDiscrep = discrepMarker;
doneFlag = (lastDiscrep==0);
nxt = TRUE; // indicates search is not complete yet, more
// parts remain
}
return nxt;
}
/*****************************************************************************
The “Match ROM” function must provide the 64-bit
ROM-ID to select an individual device on the net.
*****************************************************************************/
unsigned char Send_MatchRom(void)
{
unsigned char i;
if(ow_reset()) return FALSE;
write_byte(0x55); // match ROM
for(i=0;i<8;i++)
{
write_byte(FoundROM[numROMs][i]); //send ROM code
}
return TRUE;
}
/*************************************************************************************
SEARCH ROM CODE EXAMPLES
As shown in the prototype function below, the “Find
Devices” function begins with a 1-Wire reset to
determine if any devices are on the net, and if so, to
wake them up. The “First” function is then called
(see the next page), to keep track of the
discrepancy bits and return to “Next”, which finds
each unique device on the net.
The “Next” function is quite extensive and does
most of the work in finding each unique 64-bit ROM
code identifier for each device on the net.
**************************************************************************************/
void FindDevices(void)
{
unsigned char m;
if(!ow_reset()) //Begins when a presence is detected
{
if(First()) //Begins when at least one part is found
{
numROMs=0;
do
{
numROMs++;
for(m=0;m<8;m++)
{
FoundROM[numROMs][m]=ROM[m]; //Identifies ROM
//number on found device
}
}while (Next()&&(numROMs<10)); //Continues until no additional devices are found
}
}
}
/*****************************************************************
**
** Select the component
**
*****************************************************************/
void ow_select(char index_component){
char i;
if(!ow_reset()){ //reset pour réactiver tous les composants
write_byte(0x55); //commande MATCH ROM
for(i=0;i<8;i++) write_byte(FoundROM[index_component][i]); //on envoi les 64 bits du composant cible
}
}
/*****************************************************************
**
** function for only one devices ds18s20
**
*****************************************************************/
char ds1820_temperature(char index_component){
char k;
unsigned char get[9];
char temp_msb=0;
char temp_lsb=0;
if(FoundROM[index_component][0]!=0x10){
temp_lsb=0xFF;
return temp_lsb;
}
write_byte(0x44); //demand of conversion
delay_1us(8);
ow_select(index_component);
write_byte(0xBE); //demand the lecture of memory ds1820
for (k=0;k<9;k++){get[k]=read_byte();} //lecture scratchpad
temp_msb = get[1]; // Sign byte + lsbit
temp_lsb = get[0]; // Temp data plus lsb
if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degree
temp_msb = temp_msb & 0x80; // mask all but the sign bit
if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complement
if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degree
if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bit
return temp_lsb;
}
/***********************************************************
The “Read ROM” command is used to find the 64-
bit ROM code when only a single device is on the
net. Multiple devices require the use of the “Search
ROM” functions.
************************************************************/
void read_ROM_code(void)
{
int n;
char dat[9];
SCI1_send_string("\nReading ROM Code\n\r");
ow_reset();
write_byte(0x33);
for (n=0;n<8;n++){dat[n]=read_byte();}
SCI1_send_string(dat);
}
/***********************************************************
READING DEVICE TEMPERATURE
If there is a single device on the net, then the “Read
Temperature” function can be used directly as
shown below. However, if multiple devices are on
the net, in order to avoid data collisions, the “Match
ROM” function must be used to select a specific
device.
************************************************************/
void Read_Temperature(void)
{
char get[10];
char temp_lsb,temp_msb;
char temperature [4];
int k;
//char temp_f,temp_c;
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0x44); // Start Conversion
delay_1us(4);
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0xBE); // Read Scratch Pad
for (k=0;k<9;k++){get[k]=read_byte();}
temp_msb = get[1]; // Sign byte + lsbit
temp_lsb = get[0]; // Temp data plus lsb
if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degree
temp_msb = temp_msb & 0x80; // mask all but the sign bit
if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complement
if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degree
if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bit
SCI1_send_string( "\nTempC=\n"); // print temp. C
SCI1_send_string("\r");
SCI1_send_string("\r");
SCI1_send_string("\r");
SCI1_send_string("\r");
bin_to_string(temp_lsb,temperature);
SCI1_send_string(temperature);
SCI1_send_string("\r");
/*
temp_c = temp_lsb; // ready for conversion to Fahrenheit
temp_f = (((int)temp_c)* 9)/5 + 32;
printf( "\nTempF= %d degrees F\n", (int)temp_f ); // print temp. F
*/
}
y el archivo de cabecera
/*****************************************************************************
** BRAULIO ELIAS CHI SALAVARRIA
** 1_wire.h
** functions of 1wire sensors
**
*****************************************************************************/
#define TRUE 1
#define FALSE 0
#ifndef PORTS_DQ
#define PORTS_DQ 1
#define DQ_RX PTAD_PTAD0
#define DQ_TX PTAD_PTAD1
#define DIR_DQRX 0
#define DIR_DQTX 1
#endif
/*****************************************************************************
** principal functions
** DS18S20
**
*****************************************************************************/
void FindDevices(void);
/*****************************************************************************
** principal functions
** DS18S20
**
*****************************************************************************/
void ow_select(char);
/*****************************************************************************
** principal functions
** DS18S20
**
*****************************************************************************/
char ds1820_temperature(char);
/*****************************************************************************
** principal functions
** DS18S20
**
*****************************************************************************/
void Read_Temperature(void);
void read_ROM_code(void);
ahora las funciones que vamos a utilizar para leer son la de read_temperature, que sirve si solo tenemos un sensor conectado, pero si tenemos conectado mas sensores conectados, entonces tenemos que llamar primero a find_devices, y de ahi seleccionar que sensor queremos leer, con ow_select, entonces ya para terminar, ahora mi chamba es hacer este pequeño cambio en la funcion delay
/******************************************************************************
**
** definitions delay_us functions
******************************************************************************/
void delay_1us(unsigned int n)
{
asm {
LDHX (n)
LOOP1: AIX #-1 ;[2]
CPHX #0 ;[3]
BNE LOOP1 ;[3]
}
}
saludos