'**************************************************************************** '* My first attempts to writing code for a 16 bit PIC * ' *************************************************************************** ' Although the 24 series is a lot more complicated than the 8 bit chips, _ ' things seem much more logical. ' Interrupts for example: each interrupt has its own handler, you simply write one handler for each interrupting ' device without having to work out which interrupt it is. Timers are more logical: you specify the count going upwards that will trigger an _ 'interrupt rather than working out when the counter would underflow. I even managed to work out the preset value by 'hand without needing a plug-in to do it (which was very useful before). ' So here is the code I started with (using a PicKit3 to program the chip): Device = 24EP128MC202 '24HJ128GP502 Config FGS = GWRP_OFF, GCP_OFF Config FOSCSEL = FNOSC_FRCPLL, IESO_OFF 'Config FOSCSEL = FNOSC_FRCPLL, IESO_ON, PWMLOCK_OFF Config FOSC = POSCMD_NONE, OSCIOFNC_ON, IOL1WAY_OFF, FCKSM_CSDCMD Config FWDT = WDTPOST_PS256, WINDIS_OFF, FWDTEN_OFF 'Config FWDT = WDTPOST_PS256, WINDIS_OFF, PLLKEN_ON, FWDTEN_OFF 'Config FPOR = FPWRT_PWR128, ALTI2C_OFF 'Config FPOR = ALTI2C1_ON, ALTI2C2_OFF Config FICD = ICS_PGD1, JTAGEN_OFF ' this sets the pins used for the programmer Declare Xtal = 80 '32 '80.00 '79.23 ' ? 10MHz X-tal * 8 Declare Hserial_Baud = 31250 ' USART1 baud rate - set to MIDI Declare Hrsout1_Pin = PORTB.8 ' RP35 ' = PORTB.4 'PORTB.14 ' Select the pin for TX with USART1 Declare HRSin1_Pin = PORTB.9 ' RP41 PPS_Output(cOut_Pin_RP40, cOut_Fn_U1TX) ' Map UART1 TX pin to RP40 'RP35 PPS_Input(cIn_Pin_RP41, cIn_Fn_U1RX) ' Map UART1 RX pin to RP41 'RPI34 PLL_Setup(32, 2, 2, $0300) ' set pp1 for 80MHz - seems to work... 'PLL_Setup(43, 2, 2, $0300) 'set ppl for 79.23Megs ' Setup the Oscillator to operate the device at 140.03MHz ' Fosc = (7.37 * 76) / (2 * 2) = 140.03MHz 'PLL_Setup(76, 2, 2, $0300) ' for the dsPIC30F3010 we had: '//Defines for System Clock Timing - '//For oscillator configuration XT x PLL8 mode, '//Device Throughput in MIPS = Fcy = 7372800*8/4 = ~14.74 MIPS '//Instruction Cycle time = Tcy = 1/(Fcy) = ~68 nanoseconds '#define XTFREQ 15000000 ' //On-board Crystal frequency '#define PLLMODE 4 '//On-chip PLL setting '#define FCY XTFREQ*PLLMODE/4 '//Instruction Cycle Frequency ' Config FBS = BWRP_WRPROTECT_OFF, BSS_NO_FLASH, BSS_NO_BOOT_CODE gives error ' Config FSS = SWRP_WRPROTECT_OFF, SSS_NO_FLASH, RSS_NO_SEC_RAM ' Config FGS = GWRP_OFF, GCP_OFF ' Config FOSCSEL = FNOSC_FRCPLL, IESO_OFF ' Config FOSC = POSCMD_NONE, OSCIOFNC_ON, IOL1WAY_OFF, FCKSM_CSDCMD ' Config FWDT = WDTPOST_PS256, WINDIS_OFF, FWDTEN_OFF ' 'Config FPOR = FPWRT_PWR128, ALTI2C_OFF Symbol led PORTB.5 Dim timer_flag As Bit ' WHILE ' TOGGLE led ' DelayMS 100 ' WEND IFS0bits_T1IF = 0 ' clear Timer1 interrupt flag IPC0bits_T1IP0 = 0 ' set priority IEC0bits_T1IE = 1 ' Enable the Timer1 interrupt TMR1 = 0 ' clear the count PR1 = 65535 ' load Timer1 period T1CON = %1000000000110000 ' pre-scale 256. bit 15 is "start" GoTo MAIN ' jump over irq's ' (I copied the configs at the end blindly without trying to work out what was going on) ' I compiled it, loaded it into the chip, ticked the box on the PicKit2 which turns on the 3.3V Vdd and voila! A flashing led. Could it be any simpler? ' Now I needed a timer. The first timer in this chip is Timer1. A 16 bit timer. ' The interrupt handler for it looks like this: Isr- T1Interrupt ' timer1 interrupt timer_flag = 1 ' tell my main code that timer has completed IFS0bits_T1IF = 0 ' Reset the Timer1 interrupt flag EndIsr- ' exit the interrupt MAIN: While If timer_flag = 1 Then ' timer has expired, toggle the led timer_flag = 0 ' clear our marker Toggle led EndIf Wend 'How often will the LED flash? ' The clock is 80Megs (I know it's 79.23 but 80 is easier to work with) ' The prescale (bits 4,5 in T1CON) is set at 256 (both bits set). And the timer is fed from the system clock/2 ' So 40,000,000/256 is 156,250 per second (into the timer) ' And the timer is dividing this by 65535 (max value) giving 2.38 per second ' So the LED will be toggled 2.4 times a second, which means it will be on for about half a second and off for the same. ' I think that this is the slowest you can get a single 16 bit timer to run with an 80meg clock. ' The datasheet shows that you can link two timers to form a 32 bit unit. ' Don't forget that these babies do one instruction every two clocks, that's 40 million instructions a second. The first machine I ever worked on took 288uS ' to do a single simple instruction. And 80 meg clocks are pretty slow these days! ' So copy and paste the above into your IDE and off you go! You are started on the 24 road. It's not difficult. And thanks to Les who has worked wonders on the compiler. ' PS If you want to know how the re-assign pins easily, hadv215 has written a very good short article called: ''code snoppet: [ from Proton forum] ' 'Interface to an AD5293 digital potentiometer chip '' Written by Les Johnson for the Proton24 compiler '' ' Device = 24FJ64GA002 ' Declare Xtal = 32 ' Declare Hserial_Baud = 9600 ' UART1 baud rate ' Declare Hrsout1_Pin = PORTB.14 ' Select which pin is to be used for TX with USART1 '' '' Setup the pins for the software SPI routines '' ' $define AD5293_DIPin PORTB.2 ' Connects to the AD5293's DIN pin ' $define AD5293_CLKPin PORTB.0 ' Connects to the AD5293's SCLK pin ' $define AD5293_SyncPin PORTB.1 ' Connects to the AD5293's SYNC pin ' Dim wRDAC_Value As Word ' Holds the 10-bit value to write to the chip ''----------------------------------------------------------------------------------- '' Write 16-bits to the SPI bus (Most Significant Bit First). '' Input : pDataOut holds the word to transmit to the SPI interface '' Output : None '' Notes : None '' 'Proc SPI_Write16(pDataOut As Word) ' Dim Index As Byte ' For Index = 15 To 0 Step -1 ' 16-bit SPI loop ' AD5293_DIPin = pDataOut.15 ' Put the current outgoing bit on AD5293_DIPin ' pDataOut = pDataOut << 1 ' Shift the next bit into MSB ' Set AD5293_CLKPin ' Set AD5293_CLKpin high ' DelayUS 1 ' Clear AD5293_CLKPin ' Pull AD5293_CLKpin low ' Next 'EndProc ''----------------------------------------------------------------------------------- '' Adjust the AD5293 digital potentiometer '' Input : pValue holds the 10-bit value to write to the chip '' Output : None '' Notes : None '' 'Proc AD5293_Write(pValue As Word) ' Clear AD5293_SyncPin ' Enable the SPI interface ' SPI_Write16($1802) ' Unlock the chip ' Set AD5293_SyncPin ' Disable the SPI interface ' pValue.10 = 1 ' Set to write serial register to the RDAC (C0) ' Clear AD5293_SyncPin ' Enable the SPI interface ' SPI_Write16(pValue) ' Write to the peripheral ' Set AD5293_SyncPin ' Disable the SPI interface 'EndProc ''----------------------------------------------------------------------------------- '' Setup the peripherals and I/O pins '' 'Proc Setup() ' RPOR7 = 3 ' Make Pin RP14 U1TX ' CLKDIV = 0 ' CPU peripheral clock ratio set to 1:1 ' Write_OSCCONH($10) ' Enable PLL ' Low AD5293_DIPin ' SPI DI to output low ' Low AD5293_CLKPin ' SPI CLK to output low ' High AD5293_SyncPin ' SPI Sync to output high 'EndProc ''---------------------------------------------------------------- '' The main program loop starts here '' 'MAIN: ' Setup() ' While ' For wRDAC_Value = 0 To 1023 ' AD5293_Write(wRDAC_Value) ' HRSOut Dec wRDAC_Value, 13 ' DelayMS 10 ' Next ' Wend '---------------------------------------------------------------- ' For internal oscillator with PLL ' ' Config Config1 = JTAGEN_OFF, GCP_OFF, GWRP_OFF, BKBUG_OFF, COE_OFF, ICS_PGx1, FWDTEN_OFF, WINDIS_OFF, FWPSA_PR128, WDTPOST_PS256 ' Config Config2 = IOL1WAY_OFF, COE_OFF, IESO_OFF, FNOSC_FRCPLL, FCKSM_CSDCMD, OSCIOFNC_ON, POSCMOD_NONE