PLACEHOLDER FOR Code Module Library

Page: < 123 > Showing page 2 of 3
Author
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
itoa() by Cawilkie: 2008/05/22 07:57:00 (permalink)
0
itoa() by Cawilkie:
 

#include <stdio.h>

char *itoa(char *buffer, int i) {
unsigned int n;
unsigned int negate = 0;
int c = 6;

if (i < 0) {
negate=1;
n = -i;
} else if (i == 0) {
buffer[0] = '0';
buffer[1] = 0;
return buffer;
} else {
n = i;
}
buffer[c--] = 0;
do {
buffer[c--] = (n % 10) + '0';
n = n / 10;
} while (n);
if (negate) {
buffer[c--] = '-';
}
return &buffer[c+1];
}



( http://forum.microchip.com/fb.aspx?m=240997 )



post edited by DarioG - 2010/12/27 03:04:28

GENOVA :D :D ! GODO
#21
davepfz
Starting Member
  • Total Posts : 34
  • Reward points : 0
  • Joined: 2004/08/21 06:07:14
  • Status: offline
RE: Basic code for a Stepper Motor on PIC18F2420 2008/05/23 13:27:20 (permalink)
0
Since printing of floating point numbers has been a frequent issue here, I thought I'd provide a solution that works for me. The previous solutions did not allow for very large or small numbers, but this does in that it prints the number in very FOTRAN like format.

Use it with caution and test, test, test. Otherwise, enjoy!


/*  PrintFloat(Number, Buffer)
*
*  The PrintFloat routine takes a floating point number and converts it to a string located
*  at Buffer. The format of the string is in the 'scientific' notation of Sx.xxxESxx where
*  the Sx.xxx is a signed number between 1.000 and 9.999 and the Sxx is the signed exponent.
*
*  Although this is the format chosen here, it is easily extended to add digits, etc. Just
*  remember that the precision is limited by the underlying floating point library being used.
*
*  Cautions:
*    - It is up to the calling routine to ensure that there is ample buffer space.
*    - Be forewarned that the log10() and pow() routines are both memory and time hogs!
*/

 
#include   <math.h>
 
void PrintFloat(float Number, char *Buffer) {
  char Sign, ExpSign;
  int Exponent;
  float LogNumber, Mantissa;
 
  if (Number < 0.0) {                     // First capture the sign of the number
      Sign = '-';
      Number = -Number;                   // Now, the number is positive (required for log10()
  } else {
      Sign = ' ';
  }
  LogNumber = log10(Number);              // Find the logarithm
  if (LogNumber < 0.0) {                  // Cature the sign of the exponent
      ExpSign = '-';
      LogNumber = -LogNumber;             // Now, the exponent is also positive
  } else {
      ExpSign = '+';
  }
  Exponent = (int)LogNumber;              // Keep the integer portion of the logarithm
  Mantissa = LogNumber - (float)Exponent; // Find the frational part
  Number = pow(10.0, Mantissa);           // Extract the 'normalized' number
  sprintf(Buffer, "%c%d.%03dE%c%d", Sign, (int)Number, (int)(1000.0 * (Number - (int)Number + 0.0005)), ExpSign, Exponent);
  return;
}

 
Original thread is at http://forum.microchip.com/tm.aspx?m=339822&mpage=1&key=&#339822
 
post edited by davepfz - 2008/05/29 10:18:59
#22
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
a smarter (genius etc grin grin) PWM by Mike (K8LH) - BAM 2008/05/23 15:24:28 (permalink)
0
a smarter (genius etc gringrin) PWM by Mike (K8LH)
 

;
;  Mike McLaren, K8LH
;  Micro Application Consultants
;
;
;  unsigned char Interval = 0;                               // 0..99
;  unsigned char PWM[] = { 99, 99, 99, 14, 3, 0, 99, 0 };    // 0..99 duty cycle
;  unsigned char Toggle[] = { 0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0,
;                             0,0,0,0,0,0,0,0,0,0 };
;
;
;  void pwm_isr()
;  { PIR1bits.TMR2IF = 0;               // clear timer 2 interrupt flag
;    LATB ^= Toggle[Interval];          // update outputs
;    Toggle[Interval++] = 0;            // clear element for next period
;    if(Interval = 100)                 // if end of period, rebuild array
;    { Toggle[PWM[0]] |= 0b00000001;    // insert b0 toggle point
;      Toggle[PWM[1]] |= 0b00000010;    // insert b1 toggle point
;      Toggle[PWM[2]] |= 0b00000100;    // insert b2 toggle point
;      Toggle[PWM[3]] |= 0b00001000;    // insert b3 toggle point
;      Toggle[PWM[4]] |= 0b00010000;    // insert b4 toggle point
;      Toggle[PWM[5]] |= 0b00100000;    // insert b5 toggle point
;      Toggle[PWM[6]] |= 0b01000000;    // insert b6 toggle point
;      Toggle[PWM[7]] |= 0b10000000;    // insert b7 toggle point
;      Interval = 0;                    // reset Interval for new period
;      Toggle[0] ^= 0xFF;               // invert first element
;    }
;  }


(comes from here
http://forum.microchip.com/tm.aspx?m=336389
)



post edited by DarioG - 2010/12/27 03:03:59

GENOVA :D :D ! GODO
#23
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
ASM30 template for PIC24: 2008/10/06 08:31:40 (permalink)
0
ASM30 template for PIC24:

 

;------------------------------------------------------------------------------
; Listing Controls
;------------------------------------------------------------------------------
.psize 0              ; 0 = do not break listing by pages
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Turn on the global visibility of the following symbols:
;------------------------------------------------------------------------------
;  These symbols are declared in a linker script - do not change their names:
.global__reset                ; Turn on the global visibility of the code start label
.global __SPI2Interrupt         ; Turn on the global visibility of the SPI 2 ISR label
.global __U2RXInterrupt        ; Turn on the global visibility of the UART 2 receive ISR label
.global__T1Interrupt          ; Turn on the global visibility of the Timer 1 ISR label
; Put here other ISR global names if required

.global __ReservedTrap0        ; Turn on the global visibility of the error traps ISR label
.global __OscillatorFail        ;
.global __AddressError          ;
.global __StackError            ;
.global __MathError             ;
.global __ReservedTrap5         ;
.global __ReservedTrap6         ;
.global __ReservedTrap7         ;

;  These names are arbitrary:
;.global       xtal           ; Uncomment for crystal resonator clock instead of internal RC clock

;------------------------------------------------------------------------------
; Processor Setup
;------------------------------------------------------------------------------
.include       "p24hj128gp206.inc"        ; Changeto your particular MCU type
.list

;------------------------------------------------------------------------------
; Equates & Symbols
;------------------------------------------------------------------------------
fxtal   = 8000000       ; External quartz crystal frequency, Hz
ffrc    = 7372800       ; Internal fast RC oscillatot factory default frequency, Hz
plldiv  = 4             ; PLL postscaler value (minimal)

.ifdecl xtal            ; PLL multiplier value calculation for ~40 MIPS:
fosc    = fxtal         ; Main oscillatot frequency, Hz
pllmul  = 40            ; PLL multiplier value for crystal
.else
fosc    = ffrc
pllmul  =43            ;PLL multiplier value for internal fast RC oscillatot
.endif

fcy     = fosc*pllmul/plldiv/2  ; Calculated Fcy, Hz
mips    = fcy/1000000           ; Calculated MIPS

fclk    =fcy*2                ; Calculated peripheral clock frequency, Hz

baud    =38400                ; UART Baud rate
brgval  = (((fcy/baud)/16)-1)   ; Calculated UART BRG value

extref  =0            ; Set to 1 to configure ADC1 for external voltage reference

;------------------------------------------------------------------------------
; External connections to the ports:
;------------------------------------------------------------------------------
; Port aliases:
lcdport = LATD          ; Character SPI LCD port
leds    = LATD          ; LED port

; Digital outputs:
d1      = RD0           ; LED1 (1 = ON)
d2      = RD1           ; LED2 (1 = ON)
d3      = RD2           ; LED3 (1 = ON)
d4      = RD3           ; LED4 (1 = ON)

lcdcs   = RD6           ; LCD CS line
lcdrs   = RD7           ; LCD RS line

; Digital inputs:
;sw1    = MCLR          ; SW1 (Reset)
sw2     = RB3           ; SW2 (0 = pressed)
sw3     = RB4           ; SW3 (0 = pressed)
sw4     = RB5           ; SW4 (0 = pressed)

; Analog inputs:
pot1    = RB2
pot2    = RB1
temper  = RB0
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; X RAM Data
;------------------------------------------------------------------------------
.data           ; RAM memory
foobuf:        .space  32      ; Example 32-byte buffer declaration
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Flash Code & Data
;------------------------------------------------------------------------------
.text           ; Program memory
;------------------------------------------------------------------------------
; Configuration Fuses
;------------------------------------------------------------------------------
.ifdecl xtal
; System clock setup for medium frequency xtal oscillator w/PLL:
; System clock = primary osc w/PLL:
      config  __FOSCSEL,FNOSC_PRIPLL
; Clock switching and monitor disabled, OSC2 pin function = osc out, primary osc mode = XT:
      config  __FOSC,FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT

.else
; System clock setup for internal fast RC oscillator w/PLL:
; System clock = internal fast RC osc w/PLL:
      config  __FOSCSEL,FNOSC_FRCPLL
; Clock switching and monitor disabled, OSC2 pin function = i/o port, primary osc disabled:
      config  __FOSC,FCKSM_CSDCMD & OSCIOFNC_ON & POSCMD_NONE
.endif

      config  __FWDT,FWDTEN_OFF       ; Watchdog timer disabled
      config  __FICD,JTAGEN_OFF &ICS_PGD1    ; JTAG off, debugger pins = PGD1/PGC1
      config  __FPOR,FPWRT_PWR1       ; Power on timer disabled
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Main Code
;------------------------------------------------------------------------------
__reset:
      mov    #__SP_init,w15          ;Initalize the Stack Pointer
      mov    #__SPLIM_init,w0        ; Initializethe Stack Pointer Limit Register
      mov    w0,SPLIM               ; (__SP_init & __SPLIM_init values are calculated by linker)
     nop                            ; Add NOP to follow SPLIM initialization

      clr    PSVPAG                 ; Assume 32K limit for PSV space data access
      clr    TBLPAG                 ; Assume 32K limit for code space data access
      bset   CORCON,#PSV            ; Enable Program Space Visibility

      rcall  init_osc               ; Set up oscillator
      rcall  init_ports             ; Set up i/o ports
      rcall  init_UART2             ; Set up UART2
      rcall  init_timer1            ; Set up timer 1
      rcall  init_timer3            ; Set up timer 3 (ADC timer)
      rcall  init_ADC1              ; Set up ADC1
      rcall  init_SPI2              ; Set up SPI2

;------------------------------------------------------------------------------
; Main program loop
main:
      bra     main
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Oscillator setup
init_osc:
      mov     #pllmul-2,w0    ; Set PLL multiplier value
      mov     w0,PLLFBD

      clr    CLKDIV          ; Disableclock postscaler

      mov     #OSCCON,w0      ; Prepare unlock values
      mov.b   #0x46,w1
      mov.b   #0x57,w2

      mov.b  w1,[w0]         ; Unlock theOSCCON.L register
      mov.b   w2,[w0]
      bset.b  OSCCON,#LPOSCEN ; Enable secondary (32.768K) RTC oscillator

      return
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; I/O ports setup
init_ports:

      mov     #~((1<<pot1)|(1<<pot2)|(1<<temper)),w0
      mov    w0,AD1PCFGL            ; Configure as analog input(s)
.ifdecl AD2PCFGL
      mov    w0,AD2PCFGL            ; Same for 2nd ADC if present
.endif
      mov    #(1<<pot1)|(1<<pot2)|(1<<temper)|(1<<sw2)|(1<<sw3)|(1<<sw4),w0
      mov    w0,TRISB               ; Configure as digital input(s)

      clr    TRISC                  ; Configure as digital output(s)
      clr    TRISD                  ; Configure as digital output(s)
      clr    TRISF                  ; Configure as digital output(s)
      clr    TRISG                  ; Configure as digital output(s)

      bset   CNPU1,#CN5PUE          ; Enable SW2 pullup
      bset   CNPU1,#CN6PUE          ; Enable SW3 pullup
      bset   CNPU1,#CN7PUE          ; Enable SW4 pullup

      return
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; UART2 setup
init_UART2:
      mov    #brgval,w0             ; Set Baudrate
      mov    w0,U2BRG               ;

      clr    U2STA                  ; Clear status/error flags

      clr    U2MODE                 ; Enable UART for 8-bit data,
      bset   U2MODE,#UARTEN          ;no parity, 1 STOP bit, no flow control, no wakeup

      bset   U2STA,#UTXEN           ; Enable transmit, set TX int flag

      mov    #(4<<U2RXIP0),w0        ; SetUART2 RX ISR IPL to 4
      ior     IPC7

      bclr   IFS1,#U2RXIF           ; Clear RX interrupt flag
      bset   IEC1,#U2RXIE           ; Enable RX interrupts

      return
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Timer1 setup (128 Hz, free running, low power secondary 32768 Hz crystal osc clocked):
init_timer1:
      mov    #0,w0          ; Forcefree running mode (no interrupt will be generated)
      mov     w0,PR1

      mov    #(1<<TON)|(1<<TCS)|(3<<TCKPS0),w0      ; Run Timer1 at 32768/256=128 Hz
      mov     w0,T1CON

      return
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Timer3 setup (for ADC conversion start):
init_timer3:

t3_hz   = 15    ; Timer3 overflow rate, Hz

      mov    #fcy/t3_hz/256,w0       ; Timer3 willoverflow t3hz times a second
      mov    w0,PR3                 ;

      mov    #(1<<TON)|(3<<TCKPS0),w0       ; Run Timer3 at Fin = Fcy/256
      mov     w0,T3CON

      return
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; ADC1 setup
init_ADC1:
; 12 bit mode, integer data format, sync from timer3, auto sampling:
      mov    #(1<<AD12B)|(0<<FORM0)|(2<<SSRC0)|(1<<ASAM),w0
      mov     w0,AD1CON1

; Selected Vref, one interrupt per every 3 conversions, autoscan:
      mov     #(extref<<VCFG0)|(2<<SMPI0)|(1<<CSCNA),w0
      mov     w0,AD1CON2

; No ADRC (4 MHz) clock, 31 AD clocks per sample, 128 Tcy clocks per AD clock:
      mov     #(0 << ADRC)|(31 << SAMC0)|(255 << ADCS0),w0
      mov     w0,AD1CON3

; Autoscan AN0, AN1, AN2 analog inputs:
      mov     #(1<<RB0)|(1<<RB1)|(1<<RB2),w0
      mov     w0,AD1CSSL

; Set ADC1 ISR IPL to 4:
      mov     #(4 << AD1IP0),w0
      ior     IPC3

      bclr   IFS0,#AD1IF            ; Clear ADC1 interrupt flag
      bset   AD1CON1,#ADON          ; Turn on ADC and start conversions
;       bset   IEC0,#AD1IE            ; Enable ADC interrupts

      return
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; SPI2 setup:
init_SPI2:
      mov    #(1<<MSTEN)|(7<<SPRE0)|(1<<PPRE0),w0   ; Master mode, Fsck1 = Fcy/16
      mov     w0,SPI2CON1

      bset   SPI2STAT,#SPIEN                ; Turn on SPI1

      return
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Delay for W0 usec:
delay_us:
      repeat  #mips-4
      nop

      dec     w0,w0
      bra     NZ,delay_us

      return
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; ISRs
;------------------------------------------------------------------------------
; UART2 receive ISR:
__U2RXInterrupt:
      push    w0

      mov    U2RXREG,w0      ; Read a received byte fromUART2
      mov     w0,U2TXREG      ; Send it back to PC

      bclr   U2STA,#OERR     ; Clear the UART2 receive overrunflag (just for safety sake)
      bclr    IFS1,#U2RXIF    ; Clear the UART2 receive interrupt flag

      pop     w0
      retfie
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Constants in program memory
;------------------------------------------------------------------------------

banner: .asciz  "PIC24HJ128GP206"

.end

post edited by DarioG - 2010/12/27 03:03:28

GENOVA :D :D ! GODO
#24
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Relocatable Code Example by BitWise 2008/12/11 10:41:40 (permalink)
0
Relocatable Code Example by BitWise
http://forum.microchip.com/tm.aspx?m=389657

(rename attachment to "zip")
post edited by DarioG - 2010/12/27 03:03:08

GENOVA :D :D ! GODO
#25
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Code to access DeviceID or IDLocations in C18 (all memory models): 2009/12/06 12:58:19 (permalink)
0
Code to access DeviceID or IDLocations in C18 (all memory models):

 
    // ID LOCS
{
      rom char far *pID=(rom char far *)0x200000;  // make this 0x3ffffe for Device ID

      INTCONbits.GIE=0;
      USBPCBuffO[2]=*pID++;
      USBPCBuffO[3]=*pID++;
      USBPCBuffO[4]=*pID++;
      USBPCBuffO[5]=*pID;

      TBLPTRU=0;            // sect. 3.1 C18 User's guide...
      INTCONbits.GIE=1;
}

post edited by DarioG - 2010/12/27 03:02:47

GENOVA :D :D ! GODO
#26
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Generating a bit-reversal lookup-table on PIC16 and PIC18 ASM 2010/05/11 14:11:12 (permalink)
0
Generating a bit-reversal lookup-table on PIC16 and PIC18 ASM (by 1and0)
 

#define bitrev(i) upper((((i) * 0x8020 & 0x88440) | ((i) * 0x0802 & 0x22110)) * 0x10101)


variable i
i = 0
while i <= 0xFF
retlw bitrev(i)
i++
endw


variable i
i = 0
while i <= 0xFF
db bitrev(i), bitrev(i+1)
i += 2
endw
post edited by DarioG - 2010/12/27 03:01:37

GENOVA :D :D ! GODO
#27
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Helper functions for converting UTC (SNTP) time into useful date/time structs: 2010/05/15 14:53:33 (permalink)
5 (3)
Helper functions for converting UTC (SNTP) time into useful date/time structs:

 
/* Following code:
 * Copyright (c) 2007, LJCV Electronics. All Rights Reserved                  *
 * San Antonio, Texas, USA. info@ljcv.net, www.ljcv.net                       *
 *                                                                            *
 *- Version Log --------------------------------------------------------------*
 *   Date       Author        Comments                                        *
 *----------------------------------------------------------------------------*
 * 06/26/07 Jorge Amodio      Beta 0.9 test version                           *
//**************************************************************************** */


#ifdef MORE_TIME_STUFF

// Three character representation of month names
ROM char *month_str[] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };

// Three character representation of the day of the week
ROM char *wday_str[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

// The following table is used to construct the string with different
// formats produced by asctime(), each group represents a time format
// that is composed by a sequence of 1 to 4 smaller character strings.
ROM char tformat[9][4] = {
  { 1, 2, 3, 4 }, { 2, 3, 0, 0 }, { 3, 0, 0, 0 }, { 5, 0, 0, 0 },
  { 3, 5, 0, 0 }, { 5, 3, 0, 0 }, { 6, 0, 0, 0 }, { 5, 6, 0, 0 },
  { 6, 5, 0, 0 }
    };

#endif

// Days on each month for regular and leap years
ROM char days_month[2][12] = {
  { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
  { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    };

// isleap() takes the argument year and returns a non zero value if it is a
// leap year.
//
int isleap(int year) {
  BYTE y;

  y = (( year % 4 == 0 ) && ( year % 100 != 0 || year % 400 == 0 ));
  return(y);
    }

#ifdef MORE_TIME_STUFF
//*****************************************************************************
// mktime() take a tm time structure and generates the equivalent time_t
// value.
//
time_t mktime(tm *p) {
  time_t j;
  int i;

  j = 0;

  for(i=START_YEAR ; i < p->tm_year ; i++ ) {
    j += isleap(i) ? 366 : 365;
      }
 
  for(i=0 ; i < p->tm_mon ; i++ ) {
    j += days_month[isleap(p->tm_year)][i];
      }
  
  j = j + p->tm_mday - 1;
  j *= 86400;      // convert to seconds

  j = j + (time_t) (p->tm_hour * 3600L);
  j = j + (time_t) (p->tm_min * 60L);
  j = j + (time_t) (p->tm_sec);

  return(j);
    }
#endif

//*****************************************************************************
// offtime() takes a time_t value and generates the corresponding tm time
// structure taking in account leap years. It also takes an offset value
// as argument to facilitate correction for Time Zone and Day Light Savings
// Time.
//
void offtime(tm *ts, time_t t, long offset) {
  long days, j;
  int i, k;
  char *p;

  t += offset;                               // Correct for TZ/DST offset
  days = t / 86400;                          // Integer number of days
  j = t % 86400;                             // Fraction of a day
  ts->tm_hour = j / 3600;                    // Integer number of hours
  j %= 3600;                                 // Fraction of hour
  ts->tm_min = j / 60;                       // Integer number of minutes
  ts->tm_sec = j % 60;                       // Remainder seconds
  ts->tm_wday = ( days + START_WDAY ) % 7;   // Day of the week

  i = START_YEAR;

  // Count the number of days per year taking in account leap years
  // to determine the year number and remaining days
  while(days >= (j = isleap(i) ? 366 : 365) ) {
    i++;
    days -= j;
    }

  while(days < 0) {
    i--;
    days += isleap(i) ? 366 : 365;
    }

  ts->tm_year = i;                           // We have the year 
  ts->tm_yday = days;                        // And the number of days

  i = isleap(i);

  // Count the days for each month in this year to determine the month
  for(k=0; days >= days_month[i][k] ; ++k ) {
    days -= days_month[i][k];
    }

  ts->tm_mon = k;                            // We have the month
  ts->tm_mday = days + 1;                    // And the day of the month
    }


#ifdef MORE_TIME_STUFF
//*****************************************************************************
// asctime() takes a tm time structure and converts the values into different
// character string formats. The seecond argument is a pointer to a character
// array that must be defined by the calling function with enough memory
// allocated to hold the resulting string, the string is terminated with the
// null (\0) character and does not contain CRLF (\n\r).
//
// The last argument specifies the desired output format for the string,
// current supported formats are:
//
//    0  DDD MMM dd HH:MM:SS YYYY
//    1  MMM dd HH:MM:SS
//    2  HH:MM:SS
//    3  mm/dd/yy
//    4  HH:MM:SS mm/dd/yy
//    5  mm/dd/yy HH:MM:SS
//    6  HH:MM
//    7  mm/dd/yy HH:MM
//    8  HH:MM mm/dd/yy
//
void asctime(tm *p, BYTE *q, BYTE format) {
  BYTE i, j;

  i = 0;

  for(j=0 ; j < 4 ; j++ ) {
    if(tformat[format][j] == 0 ) {
          i--;
          break;
          }

      switch(tformat[format][j]) {
        case 1: // DDD
                memcpypgm2ram( &q[i], wday_str[p->tm_wday], 3);
                i += 3;
                break;
   
            case 2: // MMM dd
                memcpypgm2ram( &q[i], month_str[p->tm_mon], 3);
                i += 3;
                q[i++] = ' ';
                itoa(p->tm_mday,&q[i++]);
               
                if ( p->tm_mday > 9 )
                    i++;
               
                break;
   
           case 3: // HH:MM:SS
             if(p->tm_hour < 10 ) {
               q[i++] = '0';
               itoa(p->tm_hour, &q[i++]);
               }
             else {
               itoa(p->tm_hour, &q[i]);
               i += 2;
               }
             q[i++] = ':';   
   
             if(p->tm_min < 10 ) {
              q[i++] = '0';
               itoa(p->tm_min, &q[i++]);
               }
             else {
               itoa(p->tm_min, &q[i]);
               i += 2;
               }
             q[i++] = ':';   
   
             if(p->tm_sec < 10 ) {
                 q[i++] = '0';
                 itoa(p->tm_sec, &q[i++]);
               }
             else {
                 itoa(p->tm_sec, &q[i]);
                 i += 2;
               }
             break;
   
           case 4: // YYYY
             itoa(p->tm_year, &q[i]);
             i += 4;
             break;
   
           case 5: // mm/dd/yy
             if ( p->tm_mon < 9 ) {
                q[i++] = '0';
               itoa(p->tm_mon + 1, &q[i++]);
               }
             else {
               itoa(p->tm_mon + 1, &q[i]);
               i += 2;
                 }
             q[i++] = '/';   
   
             if(p->tm_mday < 10 ) {
               q[i++] = '0';
               itoa(p->tm_mday, &q[i++]);
                 }
             else {
               itoa(p->tm_mday, &q[i]);
               i += 2;
                 }
                q[i++] = '/';   
                itoa(p->tm_year, &q[i]);
                memcpy((void *)&q[i], (void *)&q[i+2], 2);
                i += 2;
                q[i] = ' ';
                q[i+1] = ' ';
                break;
   
            case 6: // HH:MM
          if ( p->tm_hour < 10 ) {
            q[i++] = '0';
            itoa(p->tm_hour, &q[i++]);
            }
          else {
            itoa(p->tm_hour, &q[i]);
            i += 2;
            }
          q[i++] = ':';   
   
          if( p->tm_min < 10 ) {
            q[i++] = '0';
            itoa(p->tm_min, &q[i++]);
            }
          else {
            itoa(p->tm_min, &q[i]);
            i += 2;
            }
          break;
        }

    q[i++] = ' ';
    }

  q[i] = '\0';
    }

#endif


post edited by DarioG - 2010/12/27 03:01:20

GENOVA :D :D ! GODO
#28
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
a detailed guide to building your own DC/DC converter using a little PIC, by Olin Lathrop 2010/10/26 04:10:08 (permalink)
0
a detailed guide to building your own DC/DC converter using a little PIC, by Olin Lathrop

http://www.microchip.com/forums/tm.aspx?m=450042
post edited by DarioG - 2010/12/27 02:56:58

GENOVA :D :D ! GODO
#29
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
A quick guide to Microchip USB Stack, by Tsuneo Chinzei 2010/12/27 02:56:40 (permalink)
0
So, I'm looking for a documentation, a tutorial or getting started guide that explain a little what are the different function like "USBDeviceTasks" and "ProcessIO".


Microchip has provided these documents for their USB device stack. Unfortunately, they are old ones. The stack has evolved further since those days. Almost 50% of their contents don't match to the current version.

MCHPFSUSB Firmware Userís Guide (2007)
http://ww1.microchip.com/...FSUSB_FW_UG_51679a.pdf

Microchip USB Device Firmware Framework Userís Guide (2008)
http://ww1.microchip.com/...n/DeviceDoc/51679b.pdf

Stack functions and callbacks of current version are briefly explained in this help file. However, it doesn't cover "USBDeviceTasks" and "ProcessIO"
C:\Microchip Solutions v2010-10-19\Microchip\Help\MCHPFSUSB Library Help.chm


OK, I'll give a brief explanation. (on the latest v2.8, v2010-10-19 version)

USBDeviceTasks()

The source code of USBDeviceTasks() is placed in
C:\Microchip Solutions v2010-10-19\Microchip\USB\usb_device.c

This routine responds to register flags set by the USB engine (SIE: Serial Interface Engine) on PIC chip for these events. And it handles these events following to the USB spec.
a) USB Transactions
b) USB bus events

a) USB Transactions
On USB cable, Packets (SETUP, IN, OUT, DATA0, DATA1, ACK, NAK, STALL) are the unit of  USB communication. These Packets are tightly bound in sequence and timing, and they consist a Transaction (SETUP, IN, OUT). Every transaction is started by host. SIE processes Packets automatically. Just when a Transaction completes, it notifies to firmware by TRNIF bit. ie. for firmware, Transactions are the basic unit of USB communication.

Every Transaction has its target endpoint (EP).
On the default EP (EP0), Transactions are aligned in Control transfer protocol. Control transfer starts with SETUP Transaction, followed by IN or OUT Transaction(s) as DATA/STATUS stage. For every Transaction on EP0, USBDeviceTasks() should be called to move the state of Control transfer process.

By a Control transfer, a Request is carried. Standard Device Requests (Get_Descriptor, Set_Address, etc.) are mainly used for enumeration sequence. Class-specific Requests (HID:Get_Report, CDC:Set_Line_Coding) are defined for each USB Class. USBDeviceTasks() also processes these Requests almost internally. To modify stack default behavior, a couple of callbacks (USBCBInitEP(), etc) are placed on main.c of Microchip examples.

On EPs other than EP0, USBDeviceTasks() usually does nothing but flushing USTAT FIFO on the SIE. The Transactions for these endpoints are processed by your code in ProcessIO()(), using the stack routines like HIDTxHandleBusy(), HIDTxPacket(), etc.

b) USB bus events
Other than Transactions, USB cable carries these bus events to your device.
- Bus Reset
- Suspend/Resume
- SOF (Start Of Frame)
- Attach/Detach
SIE also notifies these events to firmware on register flags. USBDeviceTasks() processes (most of) required job for these events. To customize the stack default behavior, you may provide your code in the callbacks (USBCBSuspend(), etc) on main.c.


In above explanation, many USB terms appear. You'll find further explanation on these USB terms in these readings.

USB Made Simple - Part3 - Data Flow
http://www.usbmadesimple.co.uk/ums_3.htm

USB in a NutShell - USB Protocols
http://www.beyondlogic.org/usbnutshell/usb3.shtml


USBDeviceTasks() is repeatedly called in main loop, when USB_POLLING is #define'd in usb_config.h
This routine moves to USB ISR (Interrupt Service Routine), when USB_INTERRUPT is #define'd instead of USB_POLLING
Microchip supposes you don't change this configuration at all.
 main.c
 
  
 #if defined(__18CXX)
 void main(void)
 #else
 int main(void)
 #endif
 {  
     InitializeSystem();
 
     #if defined(USB_INTERRUPT)
         USBDeviceAttach();
     #endif
 
     while(1)
     {
         #if defined(USB_POLLING)
         // Check bus status and service USB interrupts.
         USBDeviceTasks(); // Interrupt or polling method.  If using polling, must call
                           // this function periodically.  This function will take care
                           // of processing and responding to SETUP transactions
                           // (such as during the enumeration process when you first
                           // plug in).  USB hosts require that USB devices should accept
                           // and process SETUP packets in a timely fashion.  Therefore,
                           // when using polling, this function should be called
                           // regularly (such as once every 1.8ms or faster** [see
                           // inline code comments in usb_device.c for explanation when
                           // "or faster" applies])  In most cases, the USBDeviceTasks()
                           // function does not take very long to execute (ex: <100
                           // instruction cycles) before it returns.
         #endif
                       
 
         // Application-specific tasks.
         // Application related code may be added here, or in the ProcessIO() function.
         ProcessIO();        
     }//end while
 }//end main
 

ProcessIO()
ProcessIO() is also repeatedly called in the main loop. Microchip expects majority of your custom code goes in this routine.
The contents of this routine is separated by (A) line, as follows.
  
void ProcessIO(void)
 {  
     //
     // Processes which don't use USB endpoint
     //
 
     // User Application USB tasks
     if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;  // <--- (A)
 
     //
     // Processes which use USB endpoint
     //
 }
 



I would like a document that speak about the timing for the call of this function

As explained above, USBDeviceTasks() is called to process USB events notified by SIE.
The process deadline (time out) of each event is here.

USB Transactions on EP0
Around 100 us deadline when USB_PING_PONG__NO_PING_PONG is #define'd in usb_config.h
But it is relaxed to 50 ms for other ping-pong modes (FULL_PING_PONG, EP0_OUT_ONLY).
Therefore, you should not assign NO_PING_PONG

Bus Reset - 10 ms
Suspend - 7 ms (10ms - 3ms detection delay)
Resume - 20 ms
Attach - 100 ms

The calling interval (USB_POLLING) or interrupt latency (USB_INTERRUPT) is the minimum of these deadlines.
post edited by DarioG - 2010/12/27 02:59:47

GENOVA :D :D ! GODO
#30
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
proof of concept for using the EUSART in synchronous mode to generate 1KHz to 100 2011/11/02 15:09:25 (permalink)
0
Here is my proof of concept for using the EUSART in synchronous mode to generate both the 1KHz to 100KHz clock and the 120Hz to 12KHz clock. Is does work but the jitter between the two clock does not improve at lower frequencies.
(by Dan1138)


          ;  
     ;   Filename:     main.asm
     ;   Date:         2011-NOV-1
     ;   Author:       dan1138
     ;   Company:      
     ;                
     ;   Files required: P18F4431.INC
     ;                   18F4431_G.LKR generic linker script
     ;  
     ;   Description:
     ;  
     ;  
             IFDEF __18F4520
         
         list P=18F4520, r=dec, n=0
     #include "P18F4520.INC"
         
     ;   /* setup to use the 4xPLL with the 8MHz internal fast RC oscillator for a 32MHz system clock */
         
     ;  
         config OSC = INTIO67        ;/* Internal oscillator block, port function on RA6 and RA7          */
         config FCMEN = OFF          ;/* Fail-Safe Clock Monitor disabled                                 */
         config IESO = OFF           ;/* Oscillator Switchover mode disabled                              */
         config PWRT = ON            ;/* PWRT enabled                                                     */
         config BOREN = OFF          ;/* Brown-out Reset disabled in hardware and software                */
         config BORV = 3             ;/* Brown-out voltage minimum setting                                */
         config WDT = OFF            ;/* HW Disabled - SW Controlled                                      */
         config WDTPS = 32768        ;/* 1:32768                                                          */
         config CCP2MX = PORTC       ;/* CCP2 input/output is multiplexed with RC1                        */
         config PBADEN = OFF         ;/* PORTB<4:0> pins are configured as digital I/O on Reset           */
         config LPT1OSC = ON         ;/* Timer1 configured for low power operation                        */
         config MCLRE = ON           ;/* MCLR pin enabled; RE3 input pin disabled                         */
         config STVREN = OFF         ;/* Stack full/underflow will not cause Reset                        */
         config LVP = OFF            ;/* Single-Supply ICSP disabled                                      */
         config XINST = OFF          ;/* Instruction set extension and Indexed Addressing mode disabled   */
         
     ;   /* Turn off all code protection */
         config CP0   = OFF, CP1   = OFF, CP2   = OFF, CP3   = OFF, CPB   = OFF
         config WRT0  = OFF, WRT1  = OFF, WRT2  = OFF, WRT3  = OFF, WRTB  = OFF, WRTC  = OFF
         config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF
         
     ;   /* Specify the System clock frequency in Hz */
     #define FOSC 32000000
         
             ENDIF
         
             IFDEF __18F4431
         
         list P=18F4431, r=dec, n=0
     #include <P18F4431.INC>
             
     ;   /* setup to use the 8MHz internal oscillator for system clock */
         
         config OSC = IRCIO          ;/* Internal oscillator block, port function on RA6 and RA7          */
         config FCMEN = OFF          ;/* Fail-Safe Clock Monitor disabled                                 */
         config IESO = ON            ;/* Oscillator Switchover mode enabled                               */
         config PWRTEN = OFF         ;/* Power up timer enabled                                           */
         config BOREN = OFF          ;/* Brown-out Reset disabled in hardware and software                */
         config BORV = 27            ;/* VBOR set to 1.90 V nominal                                       */
                                     ;
         config WDTEN = OFF          ;/* Watch dog timer is always disabled. SWDTEN has no effect.        */
         config WDPS = 32768         ;/* 1:32768                                                          */
         config WINEN = OFF          ;/* WDT window disabled                                              */
         config PWMPIN = OFF         ;/* PWM outputs disabled upon Reset (default)                        */
         config LPOL = LOW           ;/* PWM0, 2, 4 and 6 are active-low                                  */
         config HPOL = LOW           ;/* PWM1, 3, 5 and 7 are active-low                                  */
         config T1OSCMX = OFF        ;/* Standard (legacy) Timer1 oscillator operation                    */
         config FLTAMX = RC1         ;/* FLTA input is multiplexed with RC1                               */
         config SSPMX = RC7          ;/* SCK/SCL clocks and SDA/SDI data are multiplexed with RC5 and RC4, respectively. SDO output is multiplexed with RC7. */
         config PWM4MX = RB5         ;/* PWM4 output is multiplexed with RB5                              */
         config EXCLKMX = RC3        ;/* TMR0/T5CKI external clock input is multiplexed with RC3          */
         config MCLRE = ON           ;/* MCLR pin enabled; RE3 input pin disabled                         */
         config STVREN = ON          ;/* Stack full/underflow will cause Reset                            */
         config LVP = OFF            ;/* Single-Supply ICSP disabled                                      */
     ;    
     ;   /* Turn off all code protection */
         config CP0   = OFF, CP1   = OFF, CP2   = OFF, CP3   = OFF, CPB   = OFF, CPD   = OFF
         config WRT0  = OFF, WRT1  = OFF, WRT2  = OFF, WRT3  = OFF, WRTB  = OFF, WRTC  = OFF, WRTD  = OFF
         config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF
         
     ;   /* Specify the System clock frequency in Hz */
     #define FOSC 8000000
         
             ENDIF
         
     ;   /* Specify the Peripheral clock frequency in Hz */
     #define FCYC (FOSC/4)
         
     ;   Divisors for USART bit rate generator
     #define CLK_100KHZ (FCYC/100000-1)
     #define CLK_1KHZ (FCYC/1000-1)
         
     ; Put ISR context save storage in the ACCESS bank
     INT_VAR         UDATA_ACS
     W_TEMP          RES        1    ; w register for context saving (ACCESS)
     STATUS_TEMP     RES        1    ; status used for context saving
     BSR_TEMP        RES        1    ; bank select used for ISR context saving
         
     ;------------------------------------------------------------------------------
     ; RESET VECTOR
     ;------------------------------------------------------------------------------
         
     POR     CODE    0x0000          ; processor reset vector
             GOTO    Main            ; go to IDATA initializer
         movlw      R25T3_LENGTH
         
     ;------------------------------------------------------------------------------
     ; HIGH PRIORITY INTERRUPT VECTOR
     ;------------------------------------------------------------------------------
         
     ISRHV   CODE    0x0008
             ; Run the High Priority Interrupt Service Routine
             GOTO    HIGH_ISR            
         
     ;------------------------------------------------------------------------------
     ; LOW PRIORITY INTERRUPT VECTOR
     ;------------------------------------------------------------------------------
         
     ISRLV   CODE    0x0018
             ; Run the High Priority Interrupt Service Routine
             GOTO    LOW_ISR            
         
     ;------------------------------------------------------------------------------
     ; HIGH PRIORITY INTERRUPT SERVICE ROUTINE
     ;------------------------------------------------------------------------------
         
     ISRH    CODE                        ; let linker place high ISR routine
         
     HIGH_ISR:
         
         ; Insert High Priority ISR Here
         
         retfie  FAST
         
     ;------------------------------------------------------------------------------
     ; LOW PRIORITY INTERRUPT SERVICE ROUTINE
     ;------------------------------------------------------------------------------
         
     ISRL    CODE    ; let linker place low ISR routine
         
     LOW_ISR:
         ; Context Saving for Low Priority ISR
         MOVFF   STATUS, STATUS_TEMP ; save status register
         MOVWF   W_TEMP              ; save W register
         MOVFF   BSR, BSR_TEMP       ; save bankselect register
         
         ; Insert Low Priority ISR Here
         
         ; Restore Context for Low Priority ISR
         MOVFF   BSR_TEMP, BSR       ; restore bank select register
         MOVF    W_TEMP, W           ; restore W register
         MOVFF   STATUS_TEMP, STATUS ; restore status register
         RETFIE
         
     ;------------------------------------------------------------------------------
     ; MAIN PROGRAM
     ;------------------------------------------------------------------------------
     ;
     ;******************************************************************************
         
     ;******************************************************************************
     ; Start of main program
     ;  
     MAIN_DATA_ACCESS  UDATA_ACS
     R25T3_INDEX res 1
         
     MAIN_CODE CODE              ; let linker place main program
         
     Main:
         clrf    INTCON
         bsf     RCON,IPEN
     ;  
     ; Initialize PIC I/O pins
     ;  
         IFDEF   __18F4520
         
         movlw   0x70                ; select internal 8MHz oscillator
         movwf   OSCCON              ;
         movlw   0x40                ; enable the 4xPLL
         movwf   OSCTUNE
         
         ; Keep us happy by turning off the comparators
         ; and letting their pins be digital I/O.
         movlw   0x07                ; Turn off comparators
         movwf   CMCON
         
         ; Keep simulator happy by initializing the ADC
         ; Keep us happy by turning the ADC off.
         movlw   0x02                ; Select internal RC as ADC clock source
         movwf   ADCON2
         movlw   0x0F                ; set all ADC inputs for digital I/O
         movwf   ADCON1
         movlw   0x00                ; Turn off ADC
         movwf   ADCON0
         
         ENDIF
         
         IFDEF   __18F4431
         
         movlw   0x70                ; Set primary oscillator as system clock source
         movwf   OSCCON,ACCESS       ; Use 8MHz internal oscillator
         
         MOVLW   0x00                ; Configure A/D
         MOVWF   ANSEL0              ; for digital inputs
         MOVWF   ANSEL1
         
         ENDIF
         
         CLRF    LATA                ; Initialize PORTA by clearing output data latches
         MOVLW   0x00                ; Value used to initialize data direction
         MOVWF   TRISA               ; Set RA<7:0> as outputs    
         
         CLRF    LATB                ; Initialize PORTB by clearing output data latches
         MOVLW   0x00                ; Value used to initialize data direction
         MOVWF   TRISB               ; Set RB<7:0> as outputs    
         
         CLRF    LATC                ; Initialize PORTC by clearing output data latches
         MOVLW   0xC0                ; Value used to initialize data direction
         MOVWF   TRISC               ; Set RC<7:0> as outputs    
         
     ;  
     ; Test 100KHz and 12KHz ouput using synchronous USART TXD and TX clock
     ;  
         movlw   B'00001000'         ; set for 16-bit BRG
         movwf   BAUDCON
         movlw   B'10110100'
         movwf   TXSTA               ; enable synchronous TX
         movlw   B'10000000'
         movwf   RCSTA               ; enable serial port
         
         movlw   HIGH(CLK_100KHZ)    ; setup bit rate
         movwf   SPBRGH
         movlw   LOW(CLK_100KHZ)
         movwf   SPBRG
         
         clrf    R25T3_INDEX
         
     ;***
     Idle:
         btfss   PIR1,TXIF
         bra     Idle
         
         movlw   HIGH(R25T3)         ; send a sequence of
         movwf   PCLATH              ; bit fields to cause
         bcf     STATUS,C            ; the TXD line to toggle
         rlcf    R25T3_INDEX,W       ; at a 25:3 ratio with
         addlw   LOW(R25T3)          ; the TX clock output.
         bnc     Idle2
         incf    PCLATH,F
     Idle2:
         call    R25T3_LOOKUP
         movwf   TXREG
         
         incf    R25T3_INDEX,F
         movlw   R25T3_LENGTH
         cpfslt  R25T3_INDEX
         clrf    R25T3_INDEX
         goto    Idle
         
     ;  
     ; TX clock to TXD 25:3 ratio
     ; Note: Table must have less than 128 elements
     ;  
     R25T3_LOOKUP:
         movwf   PCL
     R25T3:
         dt  B'11110000'
         dt  B'11110000'
         dt  B'11110000'
         dt  B'11100001'
         dt  B'11100001'
         dt  B'11000001'
         dt  B'11000011'
         dt  B'11000011'
         dt  B'11000011'
         dt  B'10000111'
         dt  B'10000111'
         dt  B'00000111'
         dt  B'00001111'
         dt  B'00001111'
         dt  B'00001111'
         dt  B'00011111'
         dt  B'00011110'
         dt  B'00011110'
         dt  B'00111100'
         dt  B'00111100'
         dt  B'00111100'
         dt  B'01111100'
         dt  B'01111000'
         dt  B'01111000'
         dt  B'11110000'
         dt  B'11110000'
         dt  B'11110000'
         dt  B'11110000'
         dt  B'11100001'
         dt  B'11100001'
         dt  B'11000001'
         dt  B'11000011'
         dt  B'11000011'
         dt  B'11000011'
         dt  B'10000111'
         dt  B'10000111'
         dt  B'00000111'
         dt  B'00001111'
         dt  B'00001111'
         dt  B'00001111'
         dt  B'00011111'
         dt  B'00011110'
         dt  B'00011110'
         dt  B'00111100'
         dt  B'00111100'
         dt  B'00111100'
         dt  B'01111100'
         dt  B'01111000'
         dt  B'01111000'
     R25T3_LENGTH equ    ($-R25T3)/2
         
         end

post edited by DarioG - 2011/11/02 15:11:02

GENOVA :D :D ! GODO
#31
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
DDS in software on (old) PIC16, by JorgeF 2012/10/10 07:41:57 (permalink)
0
  
 
 
     list p=PIC16C54C  
       
     #include <p16c54c.inc>  
 
 
 ; ==== PIC configuration ====  
 
     __CONFIG   _CP_OFF & _WDT_OFF & _HS_OSC        ; External 20MHz crytal oscillator yelding an instruction cycle of 0.2 uS  
 
 
 ; ===== Definitions =======  
 
 ; ----- I/O ports ---------  
 
 ; register for port A (output) image due to R-M-W issue  
 PortImage        equ        0x08  
 
         #ifdef __DEBUG  
 InputsPort        equ        0x09        ; Dummie register for MPLAB SIMulator debug  
         #else  
 ; Inputs port  
 InputsPort        equ        PORTB  
         #endif          
 
 ; Outputs port  
 OutputsPort        equ        PORTA  
 
 
 ; ----- I/O bit maps ---------  
 
 ; Output pin in port A  
 OscilOutput        equ        RA0  
 
 ; freq select inputs in port B  
 SelFreq_1        equ        RB0  
 SelFreq_2        equ        RB1  
 SelFreq_3        equ        RB2  
 SelFreq_4        equ        RB3  
 SelFreq_5        equ        RB4  
 
 
 ; ===== Code ==============  
 
         org 0x00  
 
     nop  
     clrf        PortImage        ; reset outputs image  
     clrf        OutputsPort        ; reset outputs  
 
         #ifndef __DEBUG  
     ; Only for real hardware not used for MPLAB SIMulator  
     movlw        ((.1<<SelFreq_1)|(.1<<SelFreq_2)|(.1<<SelFreq_3)(.1<<SelFreq_4)|(.1<<SelFreq_5))  
     tris        InputsPort        ; Unused pin as outputs  
         #endif  
 
     movlw        0x00  
     tris        OutputsPort        ; all outputs  
 
 
 ; ******************************************************  
 ; The minimum step in instruction cycles for nested  
 ; loops is 2 so the intended cycle duratios of  
 ; 8, 9, 10, 11, 12, 13 instruction cycles must be splited    
 ; alternatelly in two groups    
 ;    
 
 ; ===== Code ==============  
 
 Loop1  
     nop  
     movlw        (.1<<OscilOutput)  
     xorwf        PortImage, F  
     movf        PortImage, W  
     movwf        OutputsPort  
 Loop1b  
     btfss        InputsPort, SelFreq_1        ; 310 (312.5) KHz  
     goto        Loop1                        ; 8 instruction cycles - Inputs: 0x00  
 
     btfss        InputsPort, SelFreq_2        ; 250 (250) KHz  
     goto        Loop1                        ; 10 instruction cycles    - Inputs: 0x01  
 
     btfss        InputsPort, SelFreq_3        ; 210 (208.33) KHz  
     goto        Loop1                        ; 12 instruction cycles    - Inputs: 0x03  
     goto        Loop2b  
 
 Loop2  
     btfss        InputsPort, SelFreq_3        ; get back to first loop (even cycles)  
     goto        Loop1b  
     movlw        (.1<<OscilOutput)  
     xorwf        PortImage, F  
     movf        PortImage, W  
     movwf        OutputsPort  
 Loop2b  
     btfss        InputsPort, SelFreq_4        ; 280 (277.78) KHz    
     goto        Loop2                        ; 9  instruction cycles    - Inputs: 0x07  
 
     btfss        InputsPort, SelFreq_5        ; 225 (227.27) KHz    
     goto        Loop2                        ; 11 instruction cycles    - Inputs: 0x0f  
 
     nop  
     goto        Loop2                        ; 190 (192.31) KHz  
                                             ; 13 instruction cycles    - Inputs: 0x1f  
 
     END  
 

 
http://www.microchip.com/forums/fb.ashx?m=680759
post edited by DarioG - 2012/10/10 07:43:03

GENOVA :D :D ! GODO
#32
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Slave I2C in Software 2013/01/15 15:51:55 (permalink)
0
(code derived from some AN I found many many years ago...! Used quite often with success, and also ported to C: assembler @20MHz and C @40MHz)
 

; obvious defines :) this implementation used RC6-7
TCREAD        EQU    11111001b                     ;TRIS register for SDA read
TCWRITED    EQU    01111001b                   ;TRIS register for SDA write
TCWRITEC    EQU    10111001b                   ;TRIS register for SCL write (wait)
PCINIT   EQU  00011000b                            ;verificare su I2C hardware!!
 
TCINIT        EQU    TCREAD                           ;Initial TRIS value (PORTC)
 
I2CCIBit    equ 6        ; Clock I2C
I2CDBit        equ 7        ; Dati I2C
I2CCIVal    equ 1 << I2CCIBit
I2CDVal        equ 1 << I2CDBit
 
 
; this part of code implements handling of incoming (writes) and outgoing (reads) commands...
recvMsg:
#ifdef I2C_SMBUS
    movlw  I2CR0+1
#else
    movlw  I2CR0
#endif
    movwf  FSR
    movlw        high recvMsgTable        ; serve davvero?? sÿì!
    movwf        PCLATH
    movfw   I2CSUBA           ;switch()
    andlw        0fh
    addwf        PCL, f                ;Add offset


  if (high recvMsgTable != high (recvMsgTableHigh))
        ERROR    "Table crosses memory boundary"
  endif

recvMsgTable:
    goto        recvMsg_cls
    goto        recvMsg_setXY
    goto        recvMsg_print
    goto        recvMsg_vScroll            ; cambiare ?
    goto        recvMsg_setClock
    goto        recvMsg_setLight_Clock_Buzz
    goto        recvMsg_setLed
    goto        recvMsg_unused


recvMsgTableHigh:

recvMsg_cls:
    goto LCDCls
   

recvMsg_setXY:
  return   

recvMsg_print:

#ifdef I2C_SMBUS
    decf  I2CCNT,w
    movwf  temp2
#else
    movfw  I2CCNT
    movwf  temp2
#endif
    goto   LCDWriteN


recvMsg_vScroll:
    goto  LCDScrollDown


recvMsg_setLight_Clock_Buzz:
#ifdef I2C_SMBUS
    btfsc   I2CCNT,2                ; qui devono essere proprio 5
    btfss   I2CCNT,0
#else
    btfss   I2CCNT,2                ; qui devono essere proprio 4
#endif
    return

;    movfw        I2CR0            ; qui ci sarebbe il cnt.byte (in modalita' BLOCK_WRITE SmBus)
    movfw INDF
    bz  noLuceSet

    btfsc INDF,7                ; b7=fading
    bsf  FLAGS,FADEON

    addlw -1                                ; 1..16
    andlw 0xf
    movwf LuceLCD
    movfw FSR                    ; salvo FSR per EEprom...
    movwf temp2
    movlw LuceLCD
    call EEcopiaAEEPROM
    movfw temp2
    movwf FSR
noLuceSet:

    incf FSR,f
    movfw INDF
    bz  noContrSet
    addlw -1                                ; 1..16
    andlw 0xf
    movwf ContrLCD           
    movfw FSR                    ; salvo FSR per EEprom...
    movwf temp2
    movlw ContrLCD
    call EEcopiaAEEPROM
    movfw temp2
    movwf FSR
noContrSet:

    incf FSR,f
    btfsc INDF,0
    bsf  FLAGS2,CLOCK_ON
    btfss INDF,0
    bcf  FLAGS2,CLOCK_ON
    btfsc INDF,1
    bsf  FLAGS2,BIG_CLOCK_ON
    btfss INDF,1
    bcf  FLAGS2,BIG_CLOCK_ON
    btfsc INDF,4                                    ;1=no! (per lasciare default=sÿì...)
    bsf  FLAGS,NOKCLICK
    btfss INDF,4
    bcf  FLAGS,NOKCLICK

    incf FSR,f
    movfw INDF
    bz  noFreqSet
    sublw 32-1                    ; minimo 32 (v. PWM luce) (circa 10KHz per buzzer)
    movfw INDF
    btfsc STATUS,C
    movlw 32
    movwf BeepFreq
  return   

recvMsg_setLed:
#ifdef I2C_SMBUS
;    movfw        I2CR0            ; qui ci sarebbe il cnt.byte (in modalita' BLOCK_WRITE SmBus)
    incf  FSR,f
#else
#endif
    movfw     INDF
    movwf  PORTE
recvMsg_unused:
    retlw 0

recvMsg_setClock:
;#IFDEF __16F874                    ; altrimenti dare errore?? NO, uso Flash ext!
#ifdef I2C_SMBUS
    bsf STATUS,RP0                    ; per I2CR0
;    movfw        I2CR0            ; qui ci sarebbe il cnt.byte (in modalita' BLOCK_WRITE SmBus)
    movlw  Clock_S
    movwf  FSR
    movfw    I2CR0+1
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+2
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+3
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+4
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+5
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+6
    call  EEscrivi
    bcf STATUS,RP0
#else
    bsf STATUS,RP0                    ; per I2CR0
    movlw  Clock_S
    movwf  FSR
    movfw    I2CR0
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+1
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+2
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+3
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+4
    call  EEscrivi
    incf  FSR,f
    movfw    I2CR0+5
    call  EEscrivi
    bcf STATUS,RP0
#endif

    clrf  Clock_10
    retlw 0



; ---------------------------------------------------------------------------------
sendMsg:
    movlw        high sendMsgTable
    movwf        PCLATH
    movfw   I2CSUBA          ;switch()
    andlw        03h
    addwf        PCL, f                ;Add offset

  if (high sendMsgTable != high sendMsgTableHigh)
        ERROR    "Table crosses memory boundary"
  endif

sendMsgTable:
    goto        sendMsg_getID
    goto        sendMsg_getCfg
    goto        sendMsg_getCfg2
    goto        sendMsg_readFlash
sendMsgTableHigh:


sendMsg_getID:

;**********************************************************************
;* Device ID Table (must be at start - OCCHIO a ADDWF PCL,F)
;* TABLE FOR UNIT ID returns next char in W
;**********************************************************************
GETID:
    MOVFW   I2CCNT            ;W=I2CCNT
    ANDLW   07H             ;Limit to 8 locations
    ADDWF   PCL,F

;**********************************************************************
;* Device ID text: read starting at sub-address 0
;**********************************************************************
    dt  "ADPMLCD", (VERNUMH << 4) | VERNUML

sendMsg_getCfg:                        ; v. anche QUERY_STATUS per 232!
    MOVFW   I2CCNT          ;byte count
    ANDLW    3                                ;0..3 (2 dim.LCD + 2 pos. cursore)
    addlw   LCDCols                    ;Offset from buffer start
    MOVWF   FSR             ;Indirect address
    MOVFW   INDF            ;Get data from register
    return

sendMsg_getCfg2:                    ; v. anche QUERY_STATUS per 232!
    MOVFW   I2CCNT            ;W=I2CCNT
    ANDLW   03H             ;Limit to 4 locations (GET_EQUIPMENT)
    ADDWF   PCL,F
    retlw 1
    retlw 2
    retlw 0
    retlw 0

    return

; from here onward, the actual tight loop that manages the communication with the Master; this has to be called quite often (say <10uS in order to meet the 100KHz clock frequency), then the actual command may take more by mean of clock-stretching)

;************************************************************
; Main wait loop while idle. POLL loop should be called here
;************************************************************

I2CWAIT:
    clrf I2CFLG                    ;Init state flags
    clrf I2CCNT
    ; I2CSUBA viene pulito solo in seguito a uno stop, in modo che la BLOCK_READ (che usa uno start-ripetuto) puo' "riciclarlo" piu' volte...
    bsf  INTCON,GIE                                ; riabilito tutti gli interrupt
;    bcf FLAGS,NOSCANK                            ; oppure basta questo...?

loop1:
    CLRWDT                  ;Clear watchdog timer (senza prescaler => tWDT=18mSec)

    call doMain                            ;Call user code while in idle state

    btfsc PORTC,I2CDBit            ;Wait for SDA&SCL=H
loop2:
    btfss PORTC,I2CCIBit            ;
    GOTO  loop1                            ; No longer valid to wait for start!

    CLRWDT                  ;Clear watchdog timer

    call doMain                            ;Call user code while in idle state

;** wait for start **
    btfsc PORTC,I2CCIBit        ;Clock has dropped, niente.
    btfsc PORTC,I2CDBit            ;Se invece data dropped con CLK=1... Start!
    GOTO  loop2

I2CRESTART:

    bcf  INTCON,GIE                                ; disabilito tutti gli interrupt

    clrf I2CFLG                    ;Init state flags
;** START RECEIVED! --- wait for first bit!
loop3:
    btfsc    PORTC,I2CDBit
    goto I2CWAIT                        ;Data raised before clock dropped -- abort
    btfsc PORTC,I2CCIBit
    goto loop3                            ;Wait for clock low


NEXTBYTE:
; ********* mettere TIME-OUT in caso la comunicazione non terminasse correttamente!!

    CLRWDT                  ;Clear watchdog timer
    MOVLW   1               ;Init receive byte so bit falls off at end!
    MOVWF   I2CREG

;** Shift bits! -- external poll may be executed during low clock cycle only!
;* ENABLE line is checked for loss of enable ONLY during HIGH CLOCK

;*** CLOCK IS LOW -- DATA MAY CHANGE HERE
;*** We have at least 4us before any change can occur

loop4:
loop4A:
    CLRWDT
    btfss PORTC,I2CCIBit
    goto    loop4A                            ;Wait for clock high

;*** CLOCK IS HIGH -- SHIFT BIT - then watch for change
    RLF     PORTC,W                    ;Move RC7 (data) into C
    RLF     I2CREG,F        ;Shift in bit

    SKPNC                                    ;Skip if not done
    GOTO    ACK_I2C         ;Acknowledge byte

    BTFSC   I2CREG,0        ;Skip if data bit was 0
    GOTO    ii_1            ;This bit was set
ii_0:
    btfss PORTC,I2CCIBit
    goto  loop4                            ;Wait for clock low
    btfss PORTC,I2CDBit            ;Data low-high == stop
    GOTO    ii_0

I2CSTOP:
 
    MOVLW   TCWRITEC                ; wait state
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0
    call  recvMsg           ; process completed message! (ricevuto STOP, fine byte ricevuti, processo il gruppo di byte ricevuti)
    pagesel recvMsg                    ; riaggiusta PCLATH in caso da recvMsg fosse andato nel bank 1
    MOVLW   TCINIT
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0
    clrf  I2CSUBA                        ; pulisco subaddr...
    GOTO    I2CWAIT         ;back to main loop

ii_1:
    CLRWDT
    btfss PORTC,I2CDBit
    goto  I2CRESTART                    ;Data high-low (a meta' ricezione) == re-start
    btfss PORTC,I2CCIBit
    goto  loop4                            ;Wait for clock low
    GOTO  ii_1

ACK_I2C:
    btfss    I2CFLG,B_UA
    goto  ACK_UA                            ;Not addressed - check unit address
    btfsc I2CFLG,B_SA
    goto  ACK_SA                            ;Reading secondary address

;****
;** Do what must be done with new data bytes here (before ACKloop)
;** Don't ack if byte can't be processed!
;****
;--------

    ;USER_RECV                            ; qua ci passo byte per byte, dopo i primi 2 (address e subaddress)
    btfsc   I2CCNT,3                ; devono essere max 8 (0..7) ...
    goto        I2CWAIT                    ; ...altrimenti non-ACK
    movlw   I2CR0           ; mi posiziono nel buffer
    addwf        I2CCNT,w                ; guardo quanti byte ho gia' usato
    INCF    I2CCNT,F                ;Next position
    MOVWF   FSR             ;Indirect address
    MOVFW   I2CREG
    MOVWF   INDF            ;Put data into register

IN_CONT:                  ;continue point for intercepted bytes (non usato)

ACKloop:
    CLRWDT
    btfsc PORTC,I2CCIBit
    goto  ACKloop                        ;Wait for clock low

    MOVLW   TCWRITED                ; Set ACK (=0)
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0

ACKloop2:
    CLRWDT
    btfss PORTC,I2CCIBit
    goto ACKloop2                        ;Wait for clock high

ACKloop3:
    CLRWDT
    btfsc PORTC,I2CCIBit
    goto ACKloop3                        ;Wait for clock low

    MOVLW  TCINIT             ;End ACK
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0

;    nop    ; NO qui non serve altro ritardo!


    btfss I2CFLG,B_RD                ; se sono in lettura, vado a spedirgli i byte...
    goto NEXTBYTE                        ;   (altrimenti continuo a ricevere)

normalRead:               
#ifdef I2C_SMBUS                    ; (se in SmBus)...e comincio indicando 4/8 byte da ricevere all'host
    movlw 8                                    ; 8 byte per comando 0...
    movf    I2CSUBA,f
    btfss STATUS,Z
    movlw 4                                    ; ...e 4 per gli altri
    goto  OUT_CONT
#else
    call  sendMsg                        ; (altrimenti NON metto il # byte all'inizio!)
    INCF    I2CCNT,F        ;Next byte
    goto  OUT_CONT
#endif


;*********************************************************************
; I2C Readback (I2C read request)
; Application specific code to get bytes to send may be added here.
; This routine gets data from location pointed to by I2CSUBA and
; sends it to I2C. Subsequent reads get sequential addresses. This version
; AND's the register # with 7 to limit to 8 registers (for speed). This
; could be modified to do a comparison to an absolute number.
;
;*********************************************************************

NEXTOUT:

;*** <<< PUT NEXT BYTE INTO I2CREG HERE NOW! >>> ***
    MOVFW   I2CREG


OUT_CONT:
    MOVWF   I2CREG
;-- add code here to init I2CREG! when B_ID is clear!    boh?
    MOVLW   8               ;Bit counter
    MOVWF   I2CBITS

;** OUT bits! -- external poll may be executed during low clock cycle, but
;                may also be executed during high cycle if necessary.

;* ENABLE line is checked for loss of enable ONLY during HIGH CLOCK

;*** CLOCK IS LOW -- CHANGE DATA HERE FIRST!

;*** loop 1: data was 1
iiOUT_loop_1:
    RLF     I2CREG,F        ;Shift data out, MSB first
    SKPNC                                    ;1->0: change
    GOTO    iiOUT_1         ;Output another 1!
    MOVLW   TCWRITED                ; output 0
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0

iiOUT_0:

iiOUT_loop_02:
    CLRWDT                  ;Clear watchdog timer
    btfss PORTC,I2CCIBit
    goto iiOUT_loop_02            ;Wait for clock high

iiOUT_loop_03:
    CLRWDT
    btfsc PORTC,I2CCIBit
    goto iiOUT_loop_03            ;Wait for clock low

    DECFSZ  I2CBITS, F      ;Count bits
    GOTO    iiOUT_loop_0    ;Loop for last bit 0
    MOVLW  TCINIT           ;Done with last bit 0... Set to 1 for ACK
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0
;    nop
    nop
    nop

    GOTO    iiOUT_ack       ;Get ACK

iiOUT_loop_0:
    RLF     I2CREG,F        ;Shift data out, MSB first
    SKPC                                  ;0->1: change
    GOTO    iiOUT_0         ;Output another 0!

    MOVLW  TCINIT             ;Set to 1
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0
;    nop
    nop
    nop


iiOUT_1:
    CLRWDT                  ;Clear watchdog timer

iiOUT_loop_12:
    CLRWDT
    btfss PORTC,I2CCIBit
    goto    iiOUT_loop_12            ;Wait for clock high

iiOUT_loop_13:
    CLRWDT
    btfsc PORTC,I2CCIBit
    goto    iiOUT_loop_13            ;Wait for clock low

    DECFSZ  I2CBITS, F      ;Count bits
    GOTO    iiOUT_loop_1    ;Loop for last bit 1


iiOUT_ack:                                ;Get acknowledge

iiOUT_loop_a2:
    CLRWDT
    btfss PORTC,I2CCIBit
    goto  iiOUT_loop_a2            ;Wait for clock high

    btfsc PORTC,I2CDBit
    goto    I2CWAIT                        ;No ACK --- wait for restart!

;-- prepare next character here!
    MOVLW   TCWRITEC                ; wait state
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0
    call  sendMsg

    MOVWF   I2CREG
    MOVLW  TCINIT
    bsf        STATUS,RP0                ; bank 1
    movwf    TRISC
    bcf        STATUS,RP0                ; bank 0
    INCF    I2CCNT,F        ;Next byte

iiOUT_loop_a3_:
    CLRWDT
    btfss PORTC,I2CCIBit
    goto    iiOUT_loop_a3            ;Wait for clock low...

    btfss PORTC,I2CDBit
    goto    iiOUT_loop_a3_        ; ...e che termini ACK


iiOUT_loop_a3:
    CLRWDT
    btfss PORTC,I2CCIBit
    goto    NEXTOUT                        ;Wait for clock low - output next char!

    btfsc PORTC,I2CDBit
    goto    iiOUT_loop_a3            ;Watch out for new start condition!
    clrf  I2CSUBA                        ; pulisco subaddr...
    GOTO  I2CWAIT                        ;Stop received!

;    USER_READ                 ;user code to process data sent

;    GOTO  I2CWAIT


;**********************************************************************
;* Unit address received - check for valid address
;*
;**********************************************************************
ACK_UA:
    bsf            I2CFLG,B_UA            ;Flag unit address received
    BTFSC   I2CREG,0        ;Skip if data coming in
    bsf            I2CFLG,B_RD            ;Flag - reading from slave
    MOVFW   I2CREG            ;Get address
    ANDLW   0FEH            ;Mask direction flage before compare
    XORLW   DEVICE_ADDRESS  ;Device address
    BNZ     I2CWAIT         ;Not for me! (skip rest of message)
    btfsc        I2CFLG,B_RD
    goto        ACKloop                    ;Read - no secondary address
    bsf            I2CFLG,B_SA            ;Next is secondary address
    GOTO    ACKloop         ;Yes! ACK address and continue!

;**********************************************************************
;* Secondary address received - stow it!
;**********************************************************************
ACK_SA:
    bcf            I2CFLG,B_SA            ;Flag second address received
    MOVFW   I2CREG          ;Get subaddress
    MOVWF   I2CSUBA         ;Set subaddress
    GOTO    ACKloop


doMain:

 

 
Note that some (basic) handling of SMBus was also tried.
post edited by DarioG - 2013/01/15 15:57:30

GENOVA :D :D ! GODO
#33
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re:Slave I2C in Software 2013/01/18 05:34:33 (permalink)
0
And, due to more requests Smile, here it goes the C version:
 
(stupid forum won't let me post the code, it is attached...)
 
Similar restriction and considerations about timing and ports used apply.
post edited by DarioG - 2013/01/18 05:35:51

GENOVA :D :D ! GODO
#34
AbuSaleh
New Member
  • Total Posts : 3
  • Reward points : 0
  • Joined: 2012/12/13 15:12:35
  • Location: 0
  • Status: offline
Re:Code for sending int/floats as raw binary data (chars) to USART 2013/01/24 15:00:18 (permalink)
0
Thank you for reply, but this is for sending one float. How to send 4 floats simultaneously ?
#35
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
SW UART in C (C18; only TX) 2013/02/03 06:00:15 (permalink)
0

#include <p18cxxx.h>
#include <typedefs.h>
#include "sw_uart.h"

/************************************************
;*      SUBROUTINE TO SEND A BYTE               *
;*      AS RS232C FORMAT 8,N,1                  *
;************************************************/

void putcUART(byte Data_AREA) {
    byte COUNT;

    INTCONbits.GIE=0;

#ifndef BIT_7_MODE
    COUNT=8;             //RESET 8 BIT COUNT
#else
    COUNT=7;                // reset 7 bit count
#endif

#ifdef TX_BUFFERED
    m_TXBit=0;               //LOW RD FOR START BIT
#else
    m_TXBit=1;            //High RD FOR START BIT
#endif
    BitWork();

    do {

        if(Data_AREA & 1) {        //0 / 1 ?
#ifdef TX_BUFFERED
            m_TXBit=1;            //SEND A 1
#else
            m_TXBit=0;            //SEND A 1
#endif
            }
        else {
#ifdef TX_BUFFERED
            m_TXBit=0;                //SEND A 0
#else
            m_TXBit=1;                //SEND A 0
#endif
            }
        Data_AREA >>= 1;       //SHIFT Data TO CARRY
        BitWork();
        } while(--COUNT);          //COUNT = ?

#ifdef TX_BUFFERED
    m_TXBit=1;                //SEND STOP BIT
#else
    m_TXBit=0;                //SEND STOP BIT
#endif
    BitWork();

/* boh, no
#ifdef TX_BUFFERED
    m_TXBit=1;                //SEND STOP BIT (un altro...)
#else
    m_TXBit=0;                //SEND STOP BIT (un altro...)
#endif
    BitWork();
*/
    INTCONbits.GIE=1;
    }

void putsUART(char *s) {

    while(*s)
        putcUART(*s++);
    }

void putrsUART(const rom char *s) {

    while(*s)
        putcUART(*s++);
    }



 
This is include file sw_uart.h

#undef TX_BUFFERED

#define BAUD_TIME 52

#define BitWork() Delay_uS(BAUD_TIME-9)        //19200baud
void putcUART(byte );
void putsUART(char *);
void putrsUART(const rom char *);

#define m_TXBit LATCbits.LATC5        //boh, a caso, solo x debug

 

GENOVA :D :D ! GODO
#36
odalcet
New Member
  • Total Posts : 14
  • Reward points : 0
  • Joined: 2012/07/15 04:21:09
  • Location: 0
  • Status: offline
Re:Working CONFIG settings for 18F2550/4550 2013/03/18 13:16:57 (permalink)
#37
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re:Working CONFIG settings for 18F2550/4550 2013/03/18 14:16:48 (permalink)
0
Hmm yeah... a pity, it was not mine Smile !

GENOVA :D :D ! GODO
#38
Ian.M
Super Member
  • Total Posts : 13224
  • Reward points : 0
  • Joined: 2009/07/23 07:02:40
  • Location: UK
  • Status: offline
Re:Working CONFIG settings for 18F2550/4550 2013/03/18 14:42:03 (permalink)
#39
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re:Working CONFIG settings for 18F2550/4550 2013/03/19 02:13:52 (permalink)
0
wow thanks!
(not that it adds any special info to what is already in the datasheet, but... Smile )

GENOVA :D :D ! GODO
#40
Page: < 123 > Showing page 2 of 3
Jump to:
© 2019 APG vNext Commercial Version 4.5