Microchip Technology
Welcome to www.microchip.com
Search: Click here to Search Microchip.com
Forums Home Register LoginLog Out Inbox Address Book My Subscription Member List Search My Profile FAQ
PLACEHOLDER FOR Code Module Library

PLACEHOLDER FOR Code Module Library

 
View related threads: (in this forum | in all forums)

Logged in as: Guest
Users viewing this topic: none
  Printable Version
All Forums >> [Development Tools] >> CML >> PLACEHOLDER FOR Code Module Library Page: [1] 2   next >   >>
Login
Message << Older Topic   Newer Topic >>
PLACEHOLDER FOR Code Module Library - Nov. 16, 2007 8:19:08 AM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline


_____________________________

Dario Greggio
Post #: 1
Code for sending int/floats as raw binary data (chars) ... - Nov. 16, 2007 8:19:57 AM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
  char i,*p;
  float f;			// same goes for int or alike

  p=(char *)&f;
  for(i=0; i<sizeof(float); i++) {
    putcUSART(*p++);
    }
 

Keep in mind that this value, i.e. the sequence of bytes sent, is "Machine Dependant" (i.e. little endian/big endian sensitive) so the other end of the communication must agree on that.

_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 2
USB WAV Player (with schematic and code) - Nov. 16, 2007 3:34:41 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
Repost here for visibility:
http://forum.microchip.com/tm.aspx?m=189919
 
Schematic

http://cyberdyne.homeip.net/files/wavplayer_peluchemetallaro.pdf

and code

http://cyberdyne.homeip.net/files/pelucheusb18.zip

< Message edited by DarioG -- Aug. 8, 2009 3:56:31 AM >


_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 3
FAT16 (Memory Disk Drive File System Library) - Nov. 16, 2007 3:36:40 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
Hi,
Microchip released the first version of their Memory Disk Drive File System Library. It's compatible with FAT16.
You can find the documentation and the source files on Microchip website, application note  AN1045.
I tested the source and sample files with my older hardware design (compact flash card, with bit-transaction), with success.
This is exactly what I've been looking and waiting for.....


Thx to Microchip

della

< Message edited by DarioG -- Nov. 16, 2007 3:40:32 PM >


_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 4
sprintf() using float, for C18 - Nov. 16, 2007 3:37:28 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
  char buf[8];  
  sprintf(buf,"%d.%02u", (int)f , ((int) ((f)-(int)f) * 100) );

You can choose how many figures you wish, changing the "02u" and "*100" accordingly, and the "buf" size.


ADDED by Ren:
quote:

All of the other limitations aside, I tried this method and noticed that it fails to handle negative numbers.  Adding fabs() to the calculation for the decimal part solves that issue, and only added 3 bytes to the program.

sprintf(buf,"%d.%02u", (int) d, (int) fabs(((d - (int) d ) * 100))); 


< Message edited by DarioG -- Nov. 27, 2007 1:12:06 AM >


_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 5
A Class to do RS232 (Serial Port) Communications in C++... - Nov. 16, 2007 3:38:46 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
Attached code (rename it to ".ZIP")

PS: Usage example:
  //begin
     myComm=new CSerCommObject(comPortString);		// such as "COM1:9600,N,8,1
     myComm->Open();
 
 
 //use
         if(i=myComm->Send((BYTE *)"test",4)) {
             // do something
             }
 
          char myBuf[16];
       if(i=myComm->Receive((BYTE*)myBuf,8,2000)) {      // 2secs time allowed forreceive
             // do something
           }
 
 
 
 
 //end
     myComm->Close();
     delete myComm;
  


Attachment (1)

_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 6
Software I2C routines for PIC18F - Nov. 16, 2007 3:42:40 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
 /**************************************************************
        Start Bit Subroutine
        this routine generates a start bit
        (Low going data line while clock is high)          
 **************************************************************/
 void I2CSTART(void) {
 
 //    SWStartI2C();
     m_I2CClkBit=0;                    // make sure clock is low
     m_I2CDataBit=1;                    // make sure data is high
     I2CDataTris=0;                    // set data and clock lines for output
     I2CDelay();
     setClockHigh();                    // CLK=1
     I2CDelay();
     m_I2CDataBit=0;                    // data line goes low during high clock for start bit
     I2CDelay();
     m_I2CClkBit=0;                    // start clock train
     I2CDelay();
     }
 
 /************************************************************
        Stop Bit Subroutine
        This routine generates a stop bit
        (High going data line while clock is high)
 ************************************************************/
 void I2CSTOP(void) {
 
 //    SWStopI2C();
     m_I2CDataBit=0;                        // make sure data line is low
     m_I2CClkBit=0;                        // make sure clock is low
     I2CDataTris=0;                        // set data/clock lines as outputs
     m_I2CClkBit=1;                        // set clock high
     I2CDelay();
     m_I2CDataBit=1;                        // data goes high while clock high for stop bit
     I2CDelay();
     m_I2CClkBit=0;                        // set clock low again
     I2CDelay();
     I2CDataTris=1;                        // set data line as input
 //    m_I2CClkBit=1;                        // set clock idle
 
     setClockHigh();                        // CLK=1
     // questa e' un'altra attesa, per i dispos. (tipo PICBELL, PICWDI2C) che il WAIT lo fanno DOPO lo STOP! 
 
 //    m_I2CClkBit=0;
     I2CDelay();
 
     }
 
 /*************************************************************
        BITOUT routine takes the bit of data in C and
        transmits it to the serial EE device
 *************************************************************/
 void I2CBITOUT(byte n) {
 
     I2CDataTris=0;                    // set data,clock as outputs
     if(n)                                        // check for state of data bit to xmit
         m_I2CDataBit=1;                    // output a low bit     
     else
         m_I2CDataBit=0;                    // high? set data line high 
     Nop();                                        // dev'esserci un min. ritardo tra il cambio in DATA e la salita di CLK
     Nop();
     m_I2CClkBit=1;                            // set clock line high
     I2CDelay();
     m_I2CClkBit=0;                            // return clock line low
     I2CDelay();
 //    retlw   0
     }
                                                              
 /**************************************************************
        BITIN routine reads one bit of data from the 
        serial EE device and stores it in C
 **************************************************************/
 byte I2CBITIN(void) {
     /*overlay*/ byte i;
 
     I2CDataTris=1;                        // make sdata an input line
     I2CDelay();
     m_I2CClkBit=1;                            // set clock line high
     I2CDelay();                    // just sit here a sec
     i = m_I2CDataBit ? 1 : 0;          // read the data bit
     m_I2CClkBit=0;                        // set clock line low
     return i;
     }
 
 void setClockHigh(void) {
 // Gestisce WAIT_STATE dello slave (CLK basso)... che puo' succedere SEMPRE!
     
     m_I2CClkBit=1;
 
     I2CClkTris=1;                        // CLK e' input
 
     I2CDelay();
 
     do {
         ClrWdt();
         } while(!m_I2CClkBit);
 
     I2CClkTris=0;                // CLK e' output
 
     }
 
 /****************************************************************
        Transmit Data Subroutine
        This routine takes the byte of data stored in the
        'temp' register and transmits it to the serial EE device.
        It will then send 1 more clock to the serial EE for the
        acknowledge bit.  If the ack bit from the part was low
        then the transmission was sucessful.  If it is high, then
        the device did not send a proper ack bit and the ack
        fail LED will be turned on.
 ****************************************************************/
 #define I2CTXSlaveAddrW() I2CTXByte(0xA0)
 #define I2CTXSlaveAddrR() I2CTXByte(0xA1)
 
 
 byte I2CTXByte(byte n) {
     /*overlay*/    static byte I2CData,I2CCnt;
 
     I2CData=n;
 
     for(I2CCnt=0; I2CCnt<8; I2CCnt++) {        // set the #bits to 8
         I2CBITOUT(I2CData & 0x80);              // send the bit to serial EE
         I2CData <<= 1;                                            // rotate I2CData/txbuf left, bit in CARRY
         }                                                                        // 8 bits done?
                                                 // no - go again
 
     // read ack bit
     I2CDataTris=1;
     I2CDelay();
     setClockHigh();                    // aspetto ACK
 //        Per WAIT_STATE dello slave (CLK basso)... NON e' chiaro se PRIMA o DOPO ACK... (PicBell lo fa dopo!)
 //            questo lo controlla SEMPRE!
     I2CDelay();
 
     // dopo Delay, qua arrivo con W=0 e Z=1
     I2CCnt=m_I2CDataBit;                        // Z=1 se ACK=OK (basso), altrimenti Z=0 e W!=0
 
     m_I2CClkBit=0;
 
     if(I2CCnt) {                        // check ack bit
         m_MemCardLedBit=1;                // spegne! set acknowledge fail LED if the device did not pull data low
         return 0;                                // 0=ERR
         }
     return 1;                                // 1=OK
     }
                    
                     
 /****************************************************************
        Receive data routine
        This routine reads one byte of data from the part
        into the 'I2CData' register.
 ****************************************************************/
 byte I2CRXByte(void) {
     static /*overlay*/    byte I2CData,I2CCnt;
 
 //    SWReadI2C();
 
 //    I2CData=0;                            // clear input buffer  non serve!
           
     for(I2CCnt=0; I2CCnt<8; I2CCnt++) {        // set the #bits to 8
         I2CData <<= 1;                // rotate I2CData 1 bit left
         I2CData |= I2CBITIN();                            // read a bit
 //        STATUSbits.C = 1;            // la presenza di ASM disabilita l'ottimizzazione, quindi PEGGIORA!
 //        Rlcf(input);            // Rotate the carry into the data byte
         }                                           // 8 bits done?
                                                     // no, do another
 
     return I2CData;
     }
 
 /****************************************************************
        Receive data routine
        This routine reads one byte of data from the part
        into the 'I2CData' register.  It then sends a high 
        ACK bit to indicate that no more data is to be read
 ****************************************************************/
 byte I2CRX1Byte(void) {
     static /*overlay*/ byte I2CData,I2CCnt;
 
 //    I2CData=0;                            // clear input buffer  non serve!
           
     for(I2CCnt=0; I2CCnt<8; I2CCnt++) {        // set the #bits to 8
 //        STATUSbits.C = 1;            // la presenza di ASM disabilita l'ottimizzazione, quindi PEGGIORA!
 //        Rlcf(input);            // Rotate the carry into the data byte
         I2CData <<= 1;               // rotate I2CData 1 bit left
         I2CData |= I2CBITIN();                        // read a bit
         }                                      // 8 bits done?
                                                     // no, do another
     // set ack bit = 1
     I2CBITOUT(1);                        // to finish transmission
 
     return I2CData;
     }
 
 /**************************************************************
        READ (read routine)
        This routine reads 8 consecutive addresses of the
        serial EE device starting at address 00 in the
        random access mode (non-sequential read). Reading 
        the device using the random access mode
        requires that the address pointer be set for every 
        byte before the read takes place. The address pointer
        is set by sending a 'write mode' control byte with the
        address of the location to read.  
 ***************************************************************/
 byte I2CReadRandom(byte n) {
     static /*overlay*/ byte I2CData;
 
 //    bcf     port_a,ackf        ; clear the ack fail LED if on
 
   I2CSTART();                        // generate start bit
                                                 //
                                                 // now send the write control byte and
                                                 // address to set the pointer
                                                 //
     I2CTXSlaveAddrW();        // get slave address and write mode
 //    movfw   I2CAddr                ; get word address
     I2CTXByte(n);        // and send it
                                              
                                              // now read one byte from the part
                                              
     I2CSTART();                            // generate start bit
     I2CTXSlaveAddrR();            // get slave address and read mode
     I2CData=I2CRX1Byte();        // read 1 byte from serial EE
     I2CSTOP();                            // send stop bit to end transmission
 
     return I2CData;
     }
 
 byte I2CReadRandom16(word n) {
     byte I2CData;
 
 //    bcf     port_a,ackf        ; clear the ack fail LED if on
 
   I2CSTART();                        // generate start bit
                                                 //
                                                 // now send the write control byte and
                                                 // address to set the pointer
                                                 //
     I2CTXSlaveAddrW();        // get slave address and write mode
                             //    move word address (HIGH)
     I2CTXByte(*(((byte *)&n)+1));                        // and send it        
                             // move word address (LOW)
     I2CTXByte(*((byte *)(&n)));                        // and send it        
                                              
                                              // now read one byte from the part
                                              
     I2CSTART();                            // generate start bit
     I2CTXSlaveAddrR();            // get slave address and read mode
     I2CData=I2CRX1Byte();        // read 1 byte from serial EE
     I2CSTOP();                            // send stop bit to end transmission
 
     return I2CData;
     }
 
 /**************************************************************
        READ (sequential read routine)
 
        This routine reads 8 consecutive addresses of the
        serial EE device starting at address 00 in the
        sequential read mode. Reading in this mode is more
        efficient than the random read mode as the control byte
        and address have to be sent only once at the beginning
        of the sequence.  As many consecutive addresses as
        needed can then be read from the part until a stop bit is
        sent.  In the read mode, the PIC 16C54 must send the acknowledge
        bit after every 8 data bits from the device.  When the
        last byte needed has been read, then the controller will
        send a high acknowledge bit and then a stop bit to halt
        transmission from the device. 
 ***************************************************************/
 byte I2CRead8Seq(byte n,byte I2CCntB) {            // entra W=indirizzo part. lettura, FSR punta al buffer
     static /*overlay*/    byte *p;
 
     //    bcf     port_a,ackf        ; clear the ack fail LED if on
     p=I2CBuffer;                        // bank1, ISP=0!
 
     I2CSTART();                        // generate start bit
     I2CTXSlaveAddrW();        // send slave address and write mode
                                                     // get word address
     I2CTXByte(n);            // and send it        
     I2CSTART();                        // generate start bit
     I2CTXSlaveAddrR();        // send slave address and read mode
 
 I2CRead8Seq2:
     *p++=I2CRXByte();                // read 1 byte from device
     if(!--I2CCntB) {                // are all 8 bytes read?
                                                 // no, send low ack and do another
     // yes, send high ack bit 
         I2CBITOUT(1);                    // to stop tranxmission
         I2CSTOP();                        // and send a stop bit 
         return 8;
         }
 
     //  send low ack bit 
     I2CBITOUT(0);                // to continue transmission
     goto I2CRead8Seq2;        //and read another byte
     }
 
 /**************************************************************
        READ16 (sequential read routine)
 
        This routine reads 8 consecutive addresses of the
        serial EE device starting at given 16bit address in the
        sequential read mode. Reading in this mode is more
        efficient than the random read mode as the control byte
        and address have to be sent only once at the beginning
        of the sequence.  As many consecutive addresses as
        needed can then be read from the part until a stop bit is
        sent.  In the read mode, the PIC 16C54 must send the acknowledge
        bit after every 8 data bits from the device.  When the
        last byte needed has been read, then the controller will
        send a high acknowledge bit and then a stop bit to halt
        transmission from the device. 
 ***************************************************************/
 byte I2CRead16Seq(word n,byte I2CCntB) {            // entra indirizzo part. lettura, FSR punta al buffer
     static /*overlay*/    byte *p;
 
 //    bcf     port_a,ackf        ; clear the ack fail LED if on
     
     I2CSTART();                        // generate start bit
     I2CTXSlaveAddrW();        // send slave address and write mode
 
                             //    move word address (HIGH)
     I2CTXByte(*(((byte *)&n)+1));                        // and send it        
                             // move word address (LOW)
     I2CTXByte(*((byte *)(&n)));                        // and send it        
 
     I2CSTART();                            // generate start bit
     I2CTXSlaveAddrR();            // send slave address and read mode
 
     p=I2CBuffer;
     
 I2CRead16Seq2:
     *p++=I2CRXByte();                // read 1 byte from device
     if(!--I2CCntB) {                    // are all n bytes read?
                                                     // no, send low ack and do another
         // yes, send high ack bit 
         I2CBITOUT(1);                    // to stop tranxmission
         I2CSTOP();                        // and send a stop bit 
         return 16;
         }
 
   // send low ack bit 
     I2CBITOUT(0);              // to continue transmission
     goto I2CRead16Seq2;        // and read another byte
     }
 
 byte I2CReadRTC(byte I2CCntB) {            // entra num. byte da leggere, buffer
     static /*overlay*/ byte *p;
 
     //    bcf     port_a,ackf        ; clear the ack fail LED if on
     p=I2CBuffer;                        // bank1, ISP=0!
 
     I2CSTART();                        // generate start bit
     I2CTXByte(0xD0);            // DS1337C
                                                 // send slave address and read mode
     I2CTXByte(0);                    // send register address
     I2CSTART();                            // generate start bit
     I2CTXByte(0xD1);            // DS1337C
 
 I2CRead8Seq2:
     *p++=I2CRXByte();                // read 1 byte from device
     if(!--I2CCntB) {                // are all 8 bytes read?
                                                 // no, send low ack and do another
     // yes, send high ack bit 
         I2CBITOUT(1);                    // to stop tranxmission
         I2CSTOP();                        // and send a stop bit 
         return 1;
         }
 
     //  send low ack bit 
     I2CBITOUT(0);                // to continue transmission
     goto I2CRead8Seq2;        //and read another byte
     }
 
 /****************************************************************
        Byte Write Routine
        This routine writes the data in "temp" to 
        8 consecutive bytes in the serial EE device starting
        at address 00.  This routine waits 10mS after every
        byte to give the device time to do the write.  This 
        program repeats forever. 
 *****************************************************************/
 
 void I2CWriteByte(byte n, byte b) {
     static /*overlay*/    byte I2CAddr,I2CCnt;
 
 //    SWWriteI2C();
 
 //    clrf    port_a                ; clear all LEDs
     I2CAddr=n;                        // set starting address to W
 //    temp=0x55;                        // set data to write as 55h
 
     // set number of bytes
     for(I2CCnt=0; I2CCnt<8; I2CCnt++) {        // set the #bits to 8
 
       I2CSTART();                        // generate start bit
         I2CTXSlaveAddrW();        // send slave address and write mode
         // move word address
         I2CTXByte(I2CAddr);        // and send it        
         I2CTXByte(b);                    // move data byte and transmit it
         I2CSTOP();                        // generate stop bit
     
     //    movlw   10
     //    movwf   loops                    ; set delay time to give
     //    call    WAIT                    ; 10 ms wait after every byte
         I2CWritePagePoll();
     
         I2CAddr++;                        // add 1 to address counter
         }                                            // all 8 bytes written?
                                                     // no, do another byte
     }
 
 /****************************************************************
        Page Write Routine
 
        This routine uses page mode to write the data in "temp" to 
        8 consecutive bytes in the serial EE device starting
        at address 00. This routine waits 10mS after every
        page to give the device time to do the write.  This
        routine executes forever 
 *****************************************************************/
 
 void I2CWritePage(byte n,byte I2CCntB) {                    // entra W=indirizzo part. lettura, (FSR usato per buffer)
     static /*overlay*/ byte *p;
 
 //    clrf    port_a                    ; clear all LEDs
     p=I2CBuffer;
 
     I2CSTART();                            // generate start bit
     I2CTXSlaveAddrW();            // send slave address and write mode
 
     // move word address
     I2CTXByte(n);                        // and send it        
 
     do {
         I2CTXByte(*p++);                        // and transmit it
         } while(--I2CCntB);                        // all n bytes written?
                                                                 // no, do another
     I2CSTOP();                            // yes,generate stop bit
 
 //    movlw   10
 //    movwf   loops                        ; set delay time to give
 //    call    WAIT                        ; 10 ms wait after every byte
     Delay_mS(20);                            // 50mS
     }
 
 void I2CWriteRTC(byte n,byte I2CCntB) {                    // entra W=indirizzo part. lettura, (FSR usato per buffer)
     static /*overlay*/ byte *p;
 
 //    clrf    port_a                    ; clear all LEDs
     p=I2CBuffer;
 
     I2CSTART();                            // generate start bit
                                                 // send slave address and write mode
     I2CTXByte(0xD0);            // DS1337C
 
                                                     // move register address
     I2CTXByte(n);                        // and send it        
 
     do {
         I2CTXByte(*p++);                        // and transmit it
         } while(--I2CCntB);                        // all n bytes written?
                                                                 // no, do another
     I2CSTOP();                            // yes,generate stop bit
 
 //    movlw   10
 //    movwf   loops                        ; set delay time to give
 //    call    WAIT                        ; 10 ms wait after every byte
     }
 
 /****************************************************************
        Page Write 16 Routine (8 bytes, address a 16 bit)
 
        This routine uses page mode to write the data in "temp" to 
        8 consecutive bytes in the serial EE device starting
        at given address . This routine waits 10mS after every
        page to give the device time to do the write.  This
        routine executes forever 
 *****************************************************************/
 #define I2CWritePage16Default() I2CWritePage16((word)&I2CAddr)
 
 
 byte I2CWritePage16(word n,byte I2CCntB) {        // entra W=puntat. all'indirizzo part. lettura, (FSR usato per buffer)
     static /*overlay*/    byte *p;
 
 // clrf    port_a                    ; clear all LEDs
 
     I2CSTART();                            // generate start bit
     I2CTXSlaveAddrW();            // send slave address and write mode
 
                             //    move word address (HIGH)
     I2CTXByte(*(((byte *)&n)+1));                        // and send it        
                             // move word address (LOW)
     I2CTXByte(*((byte *)(&n)));                        // and send it        
 
     p=I2CBuffer;
 
     do {
         I2CTXByte(*p++);                // and transmit it
         } while(--I2CCntB);                    // move data byte 
                                                         // all n bytes written?
                                                         // no, do another
     I2CSTOP();                            // yes,generate stop bit
 
 //    movlw   10
 //    movwf   loops                        ; set delay time to give
 //    call    WAIT                        ; 10 ms wait after every byte
     Delay_mS(20);                            // 20mS
     return 16;
     }
 
 
 byte I2CWritePagePoll(void) {
     byte I2Cpollcnt,i;
 
     I2Cpollcnt=100;                        // set max number of times to poll as 100
     do {
         I2CSTART();                                // generate start bit
         i=I2CTXSlaveAddrW();                // send slave address and write mode
         if(i)                                        // was the ack bit low?
             goto exitpoll;                // yes, do another byte
         } while(--I2Cpollcnt);         // is poll counter down to zero?
                                                              // no, poll again.  Otherwise the part is
 //    bsf     port_a,timeout    ; not responding in time so set timeout LED and continue on 
 
 exitpoll:
         ;
     }
 
 
 void I2CDelay(void) {            // circa 2,5uSec (400KHz operation)
     /*overlay*/ static byte uSec;            // 1.25 ca.
 
     uSec=1;
     do {
         ClrWdt();                            // Clear the WDT
         Delay1TCY();            // TARARE!! @48MHz??
         Delay1TCY();
         Delay1TCY();
 //        Delay1TCY();
         } while(--uSec);
     }
 
 


(unfortunately this can't be retrieved from cache...
will try reposting it.)

< Message edited by DarioG -- Dec. 4, 2007 1:59:10 AM >


_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 7
Working CONFIG settings for 18F2550/4550 - Nov. 17, 2007 6:56:55 AM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
 #pragma config WDT = OFF, WDTPS = 1024, MCLRE=ON, STVREN=ON, LVP=OFF
 // either watchdog disabled...
 
 //#pragma config WDT = ON, WDTPS = 1024, MCLRE=ON, STVREN=ON, LVP=OFF
 // ..or watchdog enabled
 
 
 #pragma config PLLDIV=2, CPUDIV=OSC1_PLL2, USBDIV=2, FOSC=HSPLL_HS, IESO=OFF, PWRT=OFF, BOR=ON, BORV=2
 // 8MHz Crystal, 48MHz Core, 48MHz SIE engine (USB2, full speed)
 
 #ifndef __EXTENDED18__
 #pragma config VREGEN=ON, LPT1OSC=OFF, PBADEN=OFF, CCP2MX=ON, XINST=OFF, DEBUG=OFF
 // for Extended Mode...
 
 #else
 #pragma config VREGEN=ON, LPT1OSC=OFF, PBADEN=OFF, CCP2MX=ON, XINST=ON, DEBUG=OFF
 // ...or normal Mode
 
 #endif
 


ADD: also take a look at
http://users.edpnet.be/rosseel01/DRO/PIC/18F2455_2550_4455_4550_Usb_Clock.htm

< Message edited by DarioG -- Nov. 25, 2008 2:16:22 PM >


_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 8
TEMPLATE for interrupts on 18F parts with C18 - Nov. 21, 2007 2:58:11 AM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
  /** I N T E R R U P T  V E C T O R S *****************************************/
  
  #pragma code high_vector=0x08
  #define SILICON_REV_A3
  
  void interrupt_at_high_vector(void) {
    _asm 
  #ifdef SILICON_REV_A3
     CALL Foo, 1               // store current value of WREG,BSR, STATUS for a second time
      RETFIE 1                   // FAST
  Foo:
      POP     // clears return address of Foo call
      goto high_isr
  
  #else
      goto high_isr
  #endif
      _endasm
      }
  #pragma code
  
  #pragma code low_vector=0x18
  void interrupt_at_low_vector(void) {
    _asm goto low_isr _endasm
      }
  #pragma code
  
  /** D E C L A R A T I O N S **************************************************/
  /******************************************************************************
   * Function:        void high_isr(void)
   * PreCondition:    None
   * Input:
   * Output:
   * Side Effects:
   * Overview:
   *****************************************************************************/
  #pragma interrupt high_isr     // nosave=section("MATH_DATA"),section(".tmpdata")     // OPTIONAL
  void high_isr(void) {
     if(INTCONbits.TMR0IF) {               // Timer 0..  EXAMPLE
        INTCONbits.TMR0IF=0;                   // clear bitIRQ
        }
  
      }
  
  /******************************************************************************
   * Function:        void low_isr(void)
   * PreCondition:    None
   * Input:
   * Output:
   * Side Effects:
   * Overview:
   *****************************************************************************/
 #pragma interruptlow low_isr         //nosave=section("MATH_DATA"),section(".tmpdata")    //OPTIONAL
  void low_isr(void) {
  
  
      }
  #pragma code
  


_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 9
Several ways to calculate parity - Nov. 24, 2007 1:09:06 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
 // calcola la parita': entra W, esce 0 se E e 1 se O
 BOOL GetParita(byte n) {
     static byte p;
 
 #ifdef DARIO
     p=n >> 1;            // Microchip AN774
     p ^= n;
     n= p >> 2;
     p ^= n;
     n= p >> 4;
     p ^= n;
     return (p & 1);
 #endif
 
 #ifdef OLDPARITA
     if(n & 0x1)
         p++;
     if(n & 0x2)
         p++;
     if(n & 0x4)
         p++;
     if(n & 0x8)
         p++;
     if(n & 0x10)
         p++;
     if(n & 0x20)
         p++;
     if(n & 0x40)
         p++;
     if(n & 0x80)
         p++;
 #endif
 
 //From: John Payson
 //comments from Andrew Warren of Fast Forward Engineering
 
 //8-bit parity
 //This routine will leave the parity of X in X.0 
 // while blenderizing most of the rest of X 
     p=n;
 
     _asm 
         movlb   p
     swapf   p, 0, 1    //x=     abcdefgh  w =    efghabcd
     xorwf   p, 1, 1    //x=     abcdefgh  w =    efghabcd
         //    xor efghabcd
     rrncf   p, 0, 1     //x=     abcdefgh  w =    -abcdefg
         //    xor efghabcd      xor -efghabc
     xorwf   p, 1, 1     //x=     abcdefgh  w =    -abcdefg
         //    xor efghabcd      xor -efghabc
         //    xor -abcdefg
         //    xor -efghabc
 
     // at this point, the parity for half the bits
     // (a, b, e, and f) is in bit 2 of X, and the
     // parity for the other half (bits c, d, g, and h)
     // is in bit 0 of X.
 
     btfsc   p, 2, 1     // if the parity of (a,b,e,f) is 0,
                  // then the parity of (a,b,c,d,e,f,g,h)
                  // is equal to the parity of (c,d,g,h)...
                  // which is already in bit 0, so skip ahead.
 
     incf    p, 1, 1     // otherwise, the parity of (a,b,e,f) is 1,
         // so the parity of (a,b,c,d,e,f,g,h) is
         // NOT equal to the parity of (c,d,g,h).
         // invert bit 0.
 
     // at this point, bit 0 contains the parity of
     // (a,b,c,d,e,f,g,h).
 
     _endasm
 
 
 #ifdef RIC
 CheckParity:              
     swapf    X, w    ; John's idea: reducing byte to nibble
     xorwf    X, w
     addlw    41H    ; bit 1 becomes B0^B1 and bit 7 becomes B6^B7
     iorlw    7CH    ; for carry propagation from bit 1 to bit 7
     addlw    2    ; Done! the parity bit is bit 7 of W
     andlw    80H    ; set NZ if odd parity, and leave 00 or 80 in W
     return
 #endif
 
     #define PARITY(b)   ((((((b)^(((b)<<4)|((b)>>4))) + 0x41) | 0x7C ) +2 ) & 0x80)
 
 
   return p & 1;
     }
 
 


_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 10
Write/Read to/from EEprom in C18 - Dec. 4, 2007 1:56:05 AM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
 // -------------------------------------------------------------------------------------
 void EEscrivi_(SHORTPTR addr,byte n) {
 
     EEADR = (byte)addr;
     EEDATA=n;
 
     EECON1bits.EEPGD=0;        // Point to Data Memory
     EECON1bits.CFGS=0;        // Access EEPROM
     EECON1bits.WREN=1;
 
 //    INTCONbits.GIE = 0;            // disattiva interrupt globali... e USB?
     EECON2=0x55;         // Write 55h
     EECON2=0xAA;         // Write AAh
     EECON1bits.WR=1;                                    // abilita write.
     do {
         ClrWdt();
         } while(EECON1bits.WR);                            // occupato ? 
 
 //    INTCONbits.GIE = 1;            // attiva interrupt globali
 
     EECON1bits.WREN=0;                                // disabilita write.
   }
 
 byte EEleggi(SHORTPTR addr) {
 
     EEADR=(byte)addr;            // Address to read
     EECON1bits.EEPGD=0;        // Point to Data Memory
     EECON1bits.CFGS=0;        // Access EEPROM
     EECON1bits.RD=1;        // EE Read
     return EEDATA;                // W = EEDATA
     }
 


SHORTPTR is actually an unsigned char, in this implementation. Typedef'd for future extensions.

_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 11
working circular buffer - Dec. 13, 2007 9:37:22 AM   
corvette321
5+ years with MCHP products

 

Posts: 723
Joined: Oct. 31, 2006
From: Florida
Status: offline
guys here is my finished and tested circular buffa code if anyone wants it!!! feel free to copy it.

this one is well suited for USART becuase it works with null terminated strings... and returns a null if empty...

this one handles empty and full also.




unsigned int head, tail = 0;
unsigned int length = 127;
unsigned char buffer_full=0;
unsigned char buffer_empty=1;
char rcv_buffa[128];


//write a byte to receive buffa
//this process assumes tail is always an empty spot
//if tail=head then empty , if (tail= head -1) then full
//
void write_rcvbuffa(unsigned char blah123)
{
//check for a full buffer
if ((buffer_full) | ((tail+1)==head) | ((tail==length) & (head==0)))
{
      xbee_rts=1; //inhibit unit from sending more data
      buffer_full=1;
}
//if buffer not full
else
{
     //write the byte and inc to next empty slot
     rcv_buffa[tail] = blah123;
      if (tail >= length)
     { 
          tail = 0;
      }
      else 
      {
             tail++; 
      }

      //update flags
      buffer_empty=0;
      if (((tail+1)==head) | ((tail==length) & (head==0)))
     {
              buffer_full=1;
              xbee_rts=1; //inhibit more stuff from comming until buffer is not empty 
      }
  }
}
//end write a byte to receive buffa

// read a byte from receive buffer
unsigned char read_rcvbuffa(void)
{

//return a null if buffer is empty, otherwise read 1 from head and increment
// then returns the value at head.
// then examines if buffer is empty and sets flag as appropriate for next read (or write)
if ((buffer_empty) | (head==tail))
{
     Data1=0x00; //null value
     xbee_rts=0; //good to go
    buffer_empty=1;
}
else
{
     //read 1 from head and inc head
      Data1 = rcv_buffa[head];
     if (head >= length)
    {
             head = 0;
     }
     else
     {
            head++;
     }

      //update flags
      buffer_full=0;
      xbee_rts=0;
     if (head==tail)
     {
            buffer_empty=1;
            xbee_rts=0; //good to go
     }
}
return Data1;
}
// end read byte from receive buffa


lemme know if anyone needs additional info or help with it :)

this one is tested with xbee pro module as a receive buffer.

im gonna use it for a transmit one too i think.


the RTS control stuff can be deleted if your not using it... (or not using an xbee module hahah)

< Message edited by corvette321 -- Dec. 13, 2007 9:44:51 AM >

(in reply to DarioG)
Post #: 12
1-wire Dallas code in Assembler for 16F PICs - Jan. 6, 2008 5:54:12 AM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
 ; BEGINNING OF CODE
 
     btfsc PORTB,SPI_232_I            ; se e' basso, c'e' iButton!
     goto noIButton
 
   movlw TO_ADDR
     movwf DstAddr
   movlw 55                                ; notifica da iButton
   call SetFrame
 
     movlw 250
     EXTENDED_CALL Delay_uS                    ; aspetto 250uSec
 
     movlw 0x33                            ; comando READ-ROM
     EXTENDED_CALL DoDallasOut
 
     bcf PORTB,SPI_232_I            ; DATA=0
 
     movlw 8                                ; 8 byte...
     movwf temp3
     movlw BuffO6Arg                ; ...a partire da parm1 del pacch. in uscita
     movwf FSR
 
 _iButton:
     EXTENDED_CALL DoDallasIn
     MY_PAGESEL _iButton
     movwf INDF
     incf FSR,f
     decfsz  temp3,f
     goto  _iButton
 
 
 noIButton:
 ; END...
 
 
 ; SUPPORT ROUTINES
 DoDallasOut:                    ; entra W= valore;  tSlot=100uS
     movwf temp
     movlw 8
     movwf tempC
 
     call setDataOutput
 
 DoDallasOut1:
     bcf  PORTB,SPI_232_I
 
     movlw 90
     btfsc temp,0
     movlw 10
     call Delay_uS
 
     bsf  PORTB,SPI_232_I
 
     rrf temp,f
     movlw 10
     btfsc STATUS,C
     movlw 90
     call Delay_uS
 
     decfsz tempC,f
     goto  DoDallasOut1
 
     return
 
 
 DoDallasIn:                    ; esce W= valore; tSlot=100uS
     movlw 8
     movwf tempC
 
 DoDallasIn1:
     call setDataOutput
     movlw 5
     call Delay_uS
 
     call setDataInput
     movlw 10
     call Delay_uS
 
     bcf STATUS,C
     btfsc PORTB,SPI_232_I
     bsf STATUS,C
     rrf temp,f
 
     movlw 85
     call Delay_uS
 
     decfsz tempC,f
     goto  DoDallasIn1
 
     movfw temp
     return 
 setDataOutput:                        
     bsf STATUS,RP0 ; Bank 1
     bcf TRISB,SPI_232_I            ; DATA e' output
     bcf STATUS,RP0 ; Bank 0
     return
 
 setDataInput:
     bsf STATUS,RP0 ; Bank 1
     bsf TRISB,SPI_232_I            ; DATA e' input
     bcf STATUS,RP0 ; Bank 0
     return
 
 


_____________________________

Dario Greggio

(in reply to corvette321)
Post #: 13
Writing large arrays (buffers) to FLASH on dsPIC33 proc... - Jan. 10, 2008 6:36:25 PM   
ren
Professional 2-5 years with MCHP products

 

Posts: 429
Joined: Apr. 20, 2006
From: So Cali
Status: offline
although there is a brief example of how to use the commands _erase_flash(), _write_flash16() and _write_flash24() that were added in C30 v3.01. This example shows how to write arrays that exceed the page boundary:

// Flash_Write Test_011008.c
//
// A test for demonstrating how to write a large array to FLASH (Program Memory)
// on the dsPIC33FJ256GP710 processor installed in the Explorer16 development
// board.  Objective: Define and write an array of 2048 16 bit words to FLASH.

#include "libpic30.h"
#include "p33Fxxxx.h"

// _FLASH_PAGE is a static definition (512 for the dsPIC33).
// _FLASH_ROW is a static definition (64 for the dsPIC33).
// Define an array of 2048 words in program memory.
int FLASH_data[_FLASH_PAGE*4] __attribute__((space(prog),aligned(_FLASH_PAGE*8)));



int main()
{
 int data_index;
 int page_index;
 int row_index;
 int Test_data[_FLASH_ROW];
 unsigned long Flash_pointer;

 // initialize some data for this test
 for (data_index = 0; data_index < _FLASH_ROW; )
      {
          Test_data[data_index] = data_index;
          data_index++;
      }

// Get the address of the predefined variable(s)in program space. 
_init_prog_address(Flash_pointer, FLASH_data);

// This outer loop is used to erase each page after the page boundary has been crossed.                                 
for (page_index = 0; page_index < 4; )
     {
          _erase_flash(Flash_pointer); // erase a page.

          // The row level loop.  8 rows per page for the dsPIC33 
          for (row_index = 0; row_index < 8; )
                {
                       // Write each row here with 64 words of data. 
                       _write_flash16(Flash_pointer, Test_data);
  
                       // increment the values for the test data before writing the next row.
                       // NOTE: This is a post increment so it will increment once more
                       // after the final row is written.
                       for (data_index = 0; data_index < _FLASH_ROW; )
                             {
                                    Test_data[data_index] += 64;
                                    data_index++;
                             }
                        asm("nop");  // nops here for breakpoint placement.
                        asm("nop");
                        asm("nop");
                        asm("nop");
   
                        // Increment the Flash_pointer by one row.
                        Flash_pointer += (_FLASH_ROW * 2);
                        // NOTE: No additional addressing action is required when
                        // page boundaries are crossed.  However, the page boundary
                        // must be kept track of since the page erase function is
                        // used prior to the writing of rows on a page.
   
                        // Increment the row index.
                        row_index++;
                }
                asm("nop");  // nops here for breakpoint placement.
                asm("nop");
                asm("nop");
                asm("nop");
 
                // Increment the page index. 
                page_index++;
     }
     asm("nop");  // Place Breakpoint here, then read the part to show data in FLASH.
     asm("nop");
     asm("nop");
     asm("nop");
}




< Message edited by ren -- Jan. 10, 2008 6:44:30 PM >

(in reply to DarioG)
Post #: 14
Using SHT11 on 16F628 in assembler - Jan. 21, 2008 4:40:06 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
 ; init code
 
     movlw 255                            ; almeno 9 impulsi di clock con DATA=1 per reset SHT11...
     EXTENDED_CALL DoI2CMO
     movlw 255
     EXTENDED_CALL DoI2CMO
 ;  movlw 44    
 ;    EXTENDED_CALL Delay_mS_free
     ; ritardo 11mS non necessario
     MY_PAGESEL main
 
 
 ; read
 
     movlw DELAY_I2C_SLOW
     movwf DelaySPIVal
 
 
                                                     ; I2Cstart x SHT11...
     bsf PORTB,SPI_232_I            ; imposto DATA=1 e CLK=0
     EXTENDED_CALL setDataOutput
     ; OCCHIO a manipolare PORTB che e' I/O! (v. anche IRQ)
     EXTENDED_CALL Delay_SPI
     bsf PORTA,SPI_232_O            ; CLK=1
     EXTENDED_CALL Delay_SPI
     bcf PORTB,SPI_232_I            ; DATA=0 ; data line goes low during high clock for start bit
     EXTENDED_CALL Delay_SPI
     bcf PORTA,SPI_232_O            ; CLK=0
     EXTENDED_CALL Delay_SPI
     bsf PORTA,SPI_232_O            ; CLK=1
     EXTENDED_CALL Delay_SPI
     bsf PORTB,SPI_232_I            ; DATA=1
     EXTENDED_CALL Delay_SPI
     bcf PORTA,SPI_232_O            ; CLK=0
     EXTENDED_CALL Delay_SPI
 
 
     movlw BuffI8Arg                ; ...a partire da parm3...
     movwf FSR
     EXTENDED_CALL DoI2CMO_INDF                ; mando INDF (address=cmd)
     ; return_code? in parm?
     MY_PAGESEL bytes51
 
     decf BuffI6Arg,f            ; se ce n'e' un altro...
     bz  byte51_2
     incf FSR,f
     EXTENDED_CALL DoI2CMO_INDF                ; mando INDF
     MY_PAGESEL bytes51
 
 byte51_2:
                                                 ; questo VUOLE un ritardo tra WR e RD per la conversione (v. data sheet: 55-210mS)
     movfw BuffI8Arg
     xorlw 3
     bz  byte51_4_
     xorlw 3 ^ 5
     bnz  byte51_4
                                                 ; MA SOLO in LETTURA TEMP/HUMID! (NO in impostazioni ecc.)
                                                 ; oppure aspettare che SDI scenda...
 byte51_4_:
     movlw 5
     movwf temp2
 byte51_5:
   movlw 200                            ; 50mS ca.
     EXTENDED_CALL Delay_mS_free
     MY_PAGESEL bytes51
     decfsz temp2,f
     goto byte51_5
 
 byte51_4:
     movlw 0xff
     movwf parm1
     movwf parm2
 
     movfw BuffI7Arg                ; se devo ricevere...
     bz    byte51_3                    ; (se no, potrei anche dare ACK semplice... o return_code del WRITE)
 
     decf BuffI7Arg,w            ; indico se ACK (Buff6=1 -> W=0)
     EXTENDED_CALL DoI2CMI
     MY_PAGESEL bytes51
     movwf parm1
     decf  BuffI7Arg,f
     bz  byte51_3
     decf BuffI7Arg,w            ; indico se ACK (Buff6=1 -> W=0)
     EXTENDED_CALL DoI2CMI
     MY_PAGESEL bytes51
     movwf parm2
 
 
 byte51_3:
     EXTENDED_CALL setDataOutput            ; rimetto a posto (mancando I2Cstop qua...)
     bsf PORTB,SPI_232_I            ; DATA=1 ; data goes high while clock high for stop bit
     EXTENDED_CALL Delay_SPI
     MY_PAGESEL bytes51
 
 
 
 ; support routines
 
 DoI2CMO_INDF:
     movfw INDF
 
 DoI2CMO:                                ; Master, output (CLK negativo): entra in W il byte
 
 
     movwf temp
     movlw 8
     movwf tempC
     call setDataOutput
 
 DoI2CMO_:
 ;  clrwdt            ; gia' in Delay_uS
     rlf temp,f                            ; MSB first
     btfss STATUS,C
     bcf PORTB,SPI_232_I            ; DATA=0
     btfsc STATUS,C
     bsf PORTB,SPI_232_I            ; DATA=1
 
     call  Delay_1uS                    ; serve un minimo di ritardo tra il settaggio di DATA e la salita di CLK
     bsf PORTA,SPI_232_O
     call  Delay_SPI
     bcf PORTA,SPI_232_O
     call  Delay_SPI
 
     decfsz tempC,f
     goto DoI2CMO_
 
     call setDataInput
     call  Delay_SPI
     call  setClockHigh                ; aspetto ACK
 ;        Per WAIT_STATE dello slave (CLK basso)... NON e' chiaro se PRIMA o DOPO ACK... (PicBell lo fa dopo!)
 ;            questo lo controlla SEMPRE!
     call  Delay_SPI
 
     ; dopo Delay, qua arrivo con W=0 e Z=1
     btfsc PORTB,SPI_232_I
     addlw -1                                        ; Z=1 se ACK=OK (basso), altrimenti Z=0 e W!=0
 
     bcf PORTA,SPI_232_O
     return
 
 
 DoI2CMI:                                ; Master, input (CLK negativo): esce in W il byte se C=0 o C=1=errore
                                                 ;   entra W=1 se bisogna dare ACK allo slave o 0 se no
 
     movwf temp2
     movlw 8
     movwf tempC
     call setDataInput
 
 DoI2CMI_:
 ;  clrwdt            ; gia' in Delay_uS
     call  Delay_SPI
 ;    call  setClockHigh            ; CLK=1    fare? boh?
     bsf PORTA,SPI_232_O
     call  Delay_SPI
 
 ;    btfss PORTB,SPI_232_I                ; inutile...
     bcf  STATUS,C
     btfsc PORTB,SPI_232_I
     bsf  STATUS,C
     rlf temp,f                            ; MSB first
 
     bcf PORTA,SPI_232_O
 
     decfsz tempC,f
     goto DoI2CMI_
 
     call setDataOutput
 
     movf  temp2,f                        ; invio ACK come richiesto (Z=1 se stop cioe' ACK=1, Z=0 cioe' ACK=0) 
     btfss STATUS,Z
     bcf PORTB,SPI_232_I            ; DATA=0
     btfsc STATUS,Z
     bsf PORTB,SPI_232_I            ; DATA=1
 
     bsf PORTA,SPI_232_O
     call  Delay_SPI
     bcf PORTA,SPI_232_O
     call Delay_SPI
     movfw temp
     return
 
 
 setDataOutput:                        
     bsf STATUS,RP0 ; Bank 1
     bcf TRISB,SPI_232_I            ; DATA e' output
     bcf STATUS,RP0 ; Bank 0
     return
 
 


(to be edited for clarity...)

_____________________________

Dario Greggio

(in reply to ren)
Post #: 15
Basic code for a Stepper Motor on PIC18F2420 - Feb. 5, 2008 2:00:40 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
Referenced here:
http://forum.microchip.com/post.aspx?m=312998

http://adpm.homeip.net/files/jeremy_step.zip


ADD: if anybody finds it useful, plz send 7$ via PayPal

< Message edited by DarioG -- Nov. 28, 2008 12:29:15 PM >


_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 16
RE: Basic code for a Stepper Motor on PIC18F2420 - Apr. 7, 2008 12:08:01 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
Software PWM to dim Leds, in assembler for 16F628:

         ORG     0x004             ; interrupt vector location
         movwf   w_temp            ; save off current W register contents
         movfw    STATUS                 ; move status register into W register
         movwf    status_temp       ; save off contents of STATUS register
 
         btfss    INTCON,T0IF                ; Timer 0
         goto  EndISR
                 
 int_TMR0:
         clrf  STATUS                        ; bank 0
         bcf   INTCON,T0IF                ; clear bit IRQ
 
         movlw TMR0BASE
         movwf TMR0                    ; re-inizializzo TMR0
 
         movfw Timer64RGB                ; gestisco i livelli PWM R-G-B
         subwf RVal,w
         btfss STATUS,C
         bsf   myPortB,RPWMOBit
         movfw Timer64RGB
         subwf GVal,w
         btfss STATUS,C
         bsf   myPortB,GPWMOBit
         movfw Timer64RGB
         subwf BVal,w
         btfss STATUS,C
         bsf   myPortB,BPWMOBit
 
         movfw myPortB
         movwf PORTB
 
         incf  Timer64RGB,f
         btfss Timer64RGB,6                ; se >= 64...
         goto  end_TMR0
 
         movfw myPortB
         andlw LedOVal | I2CClkVal | TX_RXVal
 ;        movlw LedOVal | I2CClkVal | TX_RXVal
 ;        andwf myPortB,f
         movwf myPortB
         movwf PORTB
         clrf  Timer64RGB
 
         incf  Timer1,f                        ; il timer a 200Hz 
 
 end_TMR0:
 
 
 EndISR:
         movfw   status_temp       ; retrieve copy of STATUS register
         movwf    STATUS                            ; restore pre-isr STATUS register contents
         swapf   w_temp,f
         swapf   w_temp,w          ; restore pre-isr W register contents
         retfie                    ; return from interrupt
 
 


The above handles 3 channels (RGB led) at PORTB: the desired values are placed in RVal, GVal, and BVal, 8bit variables.

Timer0 must be enabled to generate IRQs @ around 64*desired PWM frequency, i.e. circa 6400 Hz is ok on average.

_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 17
RE: Basic code for a Stepper Motor on PIC18F2420 - Apr. 7, 2008 12:10:23 PM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
Same thing in C, with C18, on a PIC18F such as 4520, 4550, 252, etc:
 void high_isr(void) {
     static byte i,j;
 //    static byte Timer64RGB;        messo sopra x ACCESSBANK
 
     if(INTCONbits.TMR0IF) {                // Timer 0 ..  
         INTCONbits.TMR0IF=0;                    // clear bit IRQ
 
 //        WriteTimer0(TMR0BASE);                    // reinizializzo TMR0
 // in questo modo evito overhead nell'interrupt... causa chiamata di funzione!
         TMR0L=TMR0BASE;
 //        TMR0H=0;
 
 
         Timer64RGB++;
 
         Timer64RGB &= 0x7f;
 
         if(Timer64RGB < RGBValue[0][0])
             m_RPWMO1Bit = 1;
         else
             m_RPWMO1Bit = 0;
 
 //        m_RPWMO1Bit = Timer64RGB < RGBValue[0][0] ? 1 : 0;    e' + veloce come sopra...
 
 
         if(Timer64RGB < RGBValue[1][0])
             m_RPWMO2Bit = 1;
         else
             m_RPWMO2Bit = 0;
         if(Timer64RGB < RGBValue[2][0])
             m_RPWMO3Bit = 1;
         else
             m_RPWMO3Bit = 0;
         if(Timer64RGB < RGBValue[3][0])
             m_RPWMO4Bit = 1;
         else
             m_RPWMO4Bit = 0;
         if(Timer64RGB < RGBValue[4][0])
             m_RPWMO5Bit = 1;
         else
             m_RPWMO5Bit = 0;
         if(Timer64RGB < RGBValue[5][0])
             m_RPWMO6Bit = 1;
         else
             m_RPWMO6Bit = 0;
         if(Timer64RGB < RGBValue[6][0])
             m_RPWMO7Bit = 1;
         else
             m_RPWMO7Bit = 0;
         if(Timer64RGB < RGBValue[7][0])
             m_RPWMO8Bit = 1;
         else
             m_RPWMO8Bit = 0;
 
 
 
         Counter++;
 
 
 //        m_Led2Bit ^= 1; //check timer
 
 
         }        //if timer...
 
 
     }
 
 


8 leds are handled in here.
A similar setup is used to the previous snippet of code.

_____________________________

Dario Greggio

(in reply to DarioG)
Post #: 18
RE: Basic code for a Stepper Motor on PIC18F2420 - Apr. 7, 2008 1:01:28 PM   
Xianthax

 

Posts: 47
Joined: Jan. 10, 2007
From: 0
Status: offline
Fast sqrt or inverse sqrt approximation:

Method and Credit to:
http://www.mceniry.net/papers/Fast%20Inverse%20Square%20Root.pdf

Issue at hand is a fast way to do float sqrt(float) or invsqrt to a reasonable accuracy...

code:

float fastSqrt(float x)
{
  union { float f; unsigned long ul;} y;
  y.f = x;
  y.ul = (0xbe6eb50cul - y.ul ) >> 1;
  y.f = 0.5f * y.f * (3.0f - x * y.f * y.f );
  //y.f = 0.5f * y.f * (3.0f - x * y.f * y.f );  //repeat iterations to achieve lower error
  //y.f = 0.5f * y.f * (3.0f - x * y.f * y.f );
  //y.f = 0.5f * y.f * (3.0f - x * y.f * y.f );
  //y.f = 0.5f * y.f * (3.0f - x * y.f * y.f );  //y.f ~= 1.0f/sqrt(x)
  return y.f * x;   // sqrt(x) = x / sqrt(x), return just y.f if you need invsqrt(x)
}

runs in about 123us on a pic18 @ 41.66666mhz vs clib sqrt(x) function at about 604us, (mplab sim, 1 newton step).

error functions can be found in the pdf listed about and newton steps can be added or subtracted as needed for accuracy...1 step yields max relative error <= ~.00175

i ran through the math far enough to find that doing a new version for sqrt(x) would not be faster to run than calculating 1.0/sqrt(x) and multiplying by x to get sqrt(x) as the newton step would require divisions.

-x

(in reply to DarioG)
Post #: 19
RE: Basic code for a Stepper Motor on PIC18F2420 - May 21, 2008 10:52:14 AM   
DarioG
5+ years with MCHP products

 

Posts: 23230
Joined: Feb. 25, 2006
From: Trana (TO), Italy
Status: offline
Software USART (only TX) for 16F PICs.

 ; ---------------------------------------------------------------------
 PutByte232_0:               ; manda uno 0
   clrw                  ; prosegue...
 
 ; al fondo c'e' un MOVLW/MOVWF per rimettere PORTB a posto (poiche' e' I/O)
 
 PutByte232:                ; manda un byte
     movwf Data_AREA
 
     CLRF COUNT232            ;RESET 8 BIT COUNT
 
 #ifdef TX_BUFFERED
     BCF PORTB,TXComBit         ;LOW RD FOR START BIT
 #else
     BsF PORTB,TXComBit         ;LOW RD FOR START BIT
 #endif
 
     CALL Delay_Bit
 
 SendByte1:
     RRF Data_AREA, F       ;SHIFT Data TO CARRY
 
     BTFSc STATUS,C        ;0 / 1 ?
 #ifdef TX_BUFFERED
     BSF PORTB,TXComBit        ;SEND A 1
 #else
     BcF PORTB,TXComBit        ;SEND A 1
 #endif
 
     BTFSs STATUS,C        ;1 / 0 ?
 #ifdef TX_BUFFERED
     BCF PORTB,TXComBit           ;SEND A 0
 #else
     BsF PORTB,TXComBit           ;SEND A 0
 #endif
 
     CALL Delay_Bit
     INCF COUNT232,F
   BTFSS COUNT232,3                    ;COUNT = 8 ?
     GOTO SendByte1
 
 #ifdef TX_BUFFERED
     BSF PORTB,TXComBit           ;SEND STOP BIT
 #else
     BcF PORTB,TXComBit           ;SEND STOP BIT
 #endif
     CALL Delay_Bit
 #ifdef TX_BUFFERED
     BSF PORTB,TXComBit           ;SEND STOP BIT (un altro...)
     movlw  TXComVal
   movwf PORTB                                  ; IMPORTANTE,xche' PORTB e'in/out (PS/2)
 #else
     BcF PORTB,TXComBit           ;SEND STOP BIT (un altro...)
   movlw  0                                     ; IMPORTANTE,xche' PORTB e' in/out (PS/2)
     movwf PORTB
 #endif
     GOTO Delay_Bit
 



Should be self-explaining; the Delay_Bit has to be computed for a bit-time delay, say 104uSec for 9600baud.

The "TX_BUFFERED" is defined when a MAX232 is used, and undefined otherwise (your case).

_____________________________

Dario Greggio

(in reply to Xianthax)
Post #: 20
Page:   [1] 2   next >   >>
All Forums >> [Development Tools] >> CML >> PLACEHOLDER FOR Code Module Library Page: [1] 2   next >   >>
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts


  Site Index  |  Legal Information  |  microchipDIRECT  |  Samples  |  Technical Support  |  Investor Information  |  Careers at Microchip  |  Contact Us  |  RSS Feeds ©2009 Microchip Technology Inc.  
  Shanghai ICP Recordal No.09049794  
Forum Software © ASPPlayground.NET Advanced Edition 2.5.5 Unicode

0.641