• PicŪ Basic


  • Re: Using Microchip assembler program in Proton

    A Forum User presented this question...and Les offered a solution
    I'm working with the Microchip MCP1630 LED driver board using a PIC12F683 controller, and they offer the firmware in assembler.

    How can use this assembler in Proton, so I can modify it? If I set the device type in Proton and enclose their code between Asm- and Endasm- I get quite a few different assembler errors. Am I doing something basically wrong?

    John




    I've started the conversion for you John, bed calls now so I'll post what I've got and you can finish the rest:

    Code:
    '   This file is a basic code template for assembly code generation   *
    '   on the PICmicro PIC12F683. This file contains the basic code      *
    '   building blocks to build upon.                                    *
    '                                                                     *
    '   If interrupts are not used all code presented between the ORG     *
    '   $004 directive and the label main can be removed. In addition    *
    '   the variable assignments for 'w_temp' and 'status_temp' can       *
    '   be removed.                                                       *
    '                                                                     *
    '   Refer to the MPASM User's Guide for additional information on     *
    '   features of the assembler (Document DS33014).                     *
    '                                                                     *
    '   Refer to the respective PICmicro data sheet for additional        *
    '   information on the instruction set.                               *
    '                                                                     *
    '                                                                     *
    '    Notes:                                                           *
    '    This code implements constant current drive for power LEDs       *
    '    Potentiomenter on AN1 is sampled to provide PWM dimming of LED   *
    '    Output voltage on AN3 is sampled to provide open circuit
    '    protection                                                       *
    '**********************************************************************
    
        Device = 12F683        
        Declare Xtal = 8
        On_Hardware_Interrupt GoTo Int_Handler
        
      '  __CONFIG   $33E4 
    ' '__CONFIG' directive is used to embed configuration word within .asm file.
    ' The lables following the directive are located in the respective .inc file.
    ' See data sheet for additional information on configuration word settings.
    
    
    '***** VARIABLE DEFINITIONS
    
    'INT_VAR        UDATA_SHR    $70   
        Dim w_temp        As Byte        ' variable used for context saving 
        Dim status_temp   As Byte        ' variable used for context saving
        Dim PWMCount    As Byte        ' holds count for software PWM
        Dim Temp        As Byte
        Dim DimDuty        As Byte        ' Duty cycle for PWM dimming
        Dim bStatus        As Byte        ' bStatus,0 -> Over voltage flag
                                            ' bStatus,1 -> Potentiometer detection flag
        Dim RestartDly    As Byte        ' Delay counter
    
    '*********************************************************************************
    
            GoTo    Main                 ' go to beginning of program
    
    ' Interrupt Service Routine
    'INT_VECTOR    CODE    $004            ' interrupt vector location
    Int_Handler:
            Movwf   w_temp                ' save off current W register contents
            Movf    STATUS,w              ' move status register into W register
            Movwf    status_temp           ' save off contents of STATUS register
    
            Clear INTCONbits_T0IF            ' clear TMR0 interrupt flag
            'BankSet    TMR0
            'movlw    128                '
            'addwf    TMR0,F                ' set interrupt period to 50usec
            TMR0 = TMR0 + 128
            
    CheckPeriod:
            Incf    PWMCount
            Movlw    63
            Subwf    PWMCount,W            ' W = PWMCount - 63
            Btfsc    STATUSbits_Z            ' Is result 0?
            Clrf    PWMCount            ' Yes, clear count variable
            
    CheckDimDuty:            
            Movf    DimDuty,W
            Btfsc    STATUSbits_Z            ' Is duty 0?
            GoTo    DimOutputOff        ' Yes, force output to 0
            Subwf    PWMCount,W            ' W = PWMCount - Duty
            Btfsc    STATUSbits_C
            GoTo    DimOutputOff
    DimOutputOn:
            '@banksel GPIO
            'btfss    bStatus,0            ' Is overvoltage flag set?
            'bsf        GPIO,5                ' Don't turn on power supply if it is
            'goto    ExitISR
            If bStatus.0 = 0 Then Set GPIO.5
            GoTo    ExitISR
    DimOutputOff:
            Clear GPIO.5
    ExitISR:
            Movf    status_temp,w     ' 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
    
    '*********************************************************************************
    
    Main:
            OSCCON =    $70                ' set internal oscillator to 8MHz.
            Set STATUSbits_RP0
            'movwf    OSCCON
    CLOCK_STABLE:
            Btfss    OSCCONbits_HTS            ' frequency stable?.
            GoTo    CLOCK_STABLE        ' no, wait.
    
            Call    InitPort            ' Call port setup initiallisation
            Call    InitPWM                ' Call the PWM setup routine
            Call    InitADC                ' Call ADC setup routine
            
            Clear    bStatus                ' Initialization
            DimDuty = $3F
            Clear    PWMCount
            
    ' Potentiometer detection on GP1
    
            Btfss    GPIO,1                ' Test GP1 and set flag if a pot is connected
            GoTo     SetPotFlag
            Clear bStatus.1            ' Clear pot flag if not connected
            GoTo    EnableInterrupts
    SetPotFlag:
            Clear WPU.1                
            Clear CMCON0
            Set ANSEL.1
            Set bStatus.1            ' Set Potentiometer flag 
    
    EnableInterrupts:                    ' Enable Interrupt
            Set INTCONbits_T0IE
            Set INTCONbits_GIE
    
    '*********************************************************************************
    
    MainLoop:
    '        @banksel    TMR0            ' uncomment next 4 lines for 
    '        movf    TMR0,W            ' software clock dithering
    '        @banksel    OSCTUNE
    '        movwf    OSCTUNE
            
    StartADC:                
            Set ADCON0bits_GO        ' Start ADC
    WaitADC:
            Btfsc    ADCON0bits_GO        ' Is conversion over?
            GoTo    WaitADC            ' No, wait for the conversion to over
                    
            Btfsc    ADCON0,3        ' is the mux set to CH1 or CH3?
            GoTo    ProcessCH3
    
    '*********************************************************************************
    ' ADC Channel 1, AN1
            
    ProcessCH1:                        ' CH1 monitors pot for dimming
            Set ADCON0.3        ' change to to CH3
            Btfss    bStatus,1        ' Check if a pot is connected by testing a flag
            GoTo    GetFullDimDuty    ' If a pot is not connected, Drive LED with full brightness 
    
    ' If a pot is connected, drive LED with the ADC result
    GetPotResult:
            Movlw    $ff            ' Invert ADC result so that
            Xorwf    ADRESH,W        ' 0V = full brightness
            Movwf    Temp            ' Shift result to get 6 LSB's
            Rrf        Temp
            Rrf        Temp
            Movf    Temp,W
            Andlw    $3F            ' Mask upper 2 bits
    ' If ADC result is less than 10%, switch off LEDs
            Movwf    Temp
            Sublw    06                ' Is ADC result less than 10%?
            Btfss    STATUSbits_C
            GoTo    GetDimDuty        ' No, drive LED with ADC result
    
            CCPR1L = 4          ' Yes, switch off clock to the MCP1630
            @banksel    GPIO
    
            GoTo    MainLoop        
    
    ' If ADC result is more than 10%, switch on LEDs 
    GetDimDuty:
            Clear    CCPR1L          ' restart clock to the MCP1630
            DimDuty = Temp            ' Drive LED with ADC result
    
    
            GoTo    MainLoop    
    
    ' If pot is not connected        
    GetFullDimDuty:
            DimDuty = $FF
            GoTo    MainLoop    
    
    '*********************************************************************************
    ' ADC Channel 3, AN3
    
    ProcessCH3:                        ' CH3 monitors bus voltage for 
                                    ' over-voltage protection
            Clear ADCON0.3        ' change MUX to  CH1
            
            Btfsc    bStatus,0
            GoTo    RestartWait
            Movlw    225            
            Subwf    ADRESH,W        ' Is it over voltage?
            Btfsc    STATUSbits_C        
            GoTo    OverVoltage        ' Yes, go for over voltage protection
            GoTo    MainLoop        ' No, normal operation
            
    ' If over voltage detected, switch off the clock and reference to MCP1630
    ' provide delay and restart clock and reference to the MCP1630 
    OverVoltage:
            CCPR1L = 4           ' disable clock to MCP1630
            Clear GPIO.5            ' turn off reference to MCP1630
            Set bStatus.0        ' Set overvoltage flag    
            RestartDly = 200            ' Initialize delay counter
            GoTo    MainLoop
    
    ' Wait for the delay counter to expire
    RestartWait:
            Decfsz    RestartDly        ' If restart delay hasn't expired,
            GoTo    MainLoop
            Clear CCPR1L                ' restart clock to the MCP1630
            Clear bStatus.0        ' Clear overvoltage flag
            GoTo    MainLoop
    
    '*********************************************************************************
    ' Port, PWM and ADC initialization        
    InitPWM:
            PR2 =  $03                ' Write to PR2 register for setting PWM
            
            CCP1CON = $3C                ' Load CCP1CON<5,4> with lower two bits
            
            CCPR1L = $00                 ' Load the upper 8 bits for a 10 bit  resolution duty cycle
    
            Set T2CONbits_TMR2ON        ' Set Timer2 as the PWM time base for PWM mode 
            Return                        ' of CCP module
    
    InitPort:
            Clear     GPIO                 ' Init GPIO
            CMCON0 = $07               ' Set AN0, AN1, AN2 as digital I/O
    
            ANSEL = $28          ' AN3 Analog input ADC clock is Fosc/16
    
    
            @banksel    TRISIO
            Movlw    $1A                ' GP0 as output for scope flag
            Movwf     TRISIO                 ' Set GP2 and GP5 as out ports
    
            Movlw   %00001000            ' TMR0 prescaler 1:1, internal clock
            Movwf    OPTION_REG             
    
            Set WPU.1                ' set weak pull up for a potentiometer                
                                        ' detection
            @banksel    GPIO                 ' Bank 0
            Return
    
    InitADC:
            @banksel    ADCON0                ' turn on ADC, CH1
            Movlw    $05        
            Movwf    ADCON0
            Set ADCON0bits_GO
            Return
    This article was originally published in forum thread: Using Microchip assembler program in Proton started by John Lawton View original post