TODOPIC
Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: stk500 en 24 de Noviembre de 2007, 08:01:25
-
Despues de largas luchas con el codigo sin resultados positivo tiros los Guante :x :x :x
-
Aqui la 2da Parte
;**********************************************************************
ORG Start_Vector ; processor reset vector
nop ; Included for ICD
clrf PCLATH ; ensure page bits are cleared
goto Start ; go to beginning of program
ORG Interrupt_Vector ; interrupt vector location
MOVWF Int_W ; Save PIC state
SWAPF STATUS,W
CLRF STATUS
MOVWF Int_Status
MOVF PCLATH,W
MOVWF Int_PCLath
CLRF PCLATH
BCF STATUS,IRP
MOVF FSR,W
MOVWF Int_FSR
IH_Interrupt_Poll
btfsc INTCON,T0IF ; Test for timer0 interupt
goto IH_Timer0 ; Yes, Goto timer0 Handler
btfsc PIR1,RCIF ; USART Interupt Pending ?
goto IH_Check_USART ; Yes, Goto Usart handler
btfsc INTCON,INTF ; Test for RB0 Interupt
goto IH_RB0
btfsc PIR1,TMR1IF ; Timer 1 interupt ??
goto IH_Timer1
IH_Exit movf Int_FSR,W ; Restore PIC state
movwf FSR
movf Int_PCLath,W
movwf PCLATH
swapf Int_Status,W
movwf STATUS
swapf Int_W,F
swapf Int_W,W
retfie ; Return from interrupt
IH_Timer0
movf countervalue,w
movwf TMR0 ; Reload counter0
; Channel 1
decf IH_channel1cnt,f; decrease channel 1 count
btfsc STATUS,Z ; if zero then set output
bcf channel1op ; set output
; Channel 2
decf IH_channel2cnt,f; decrease channel 2 count
btfsc STATUS,Z ; if zero then set output
bcf channel2op ; set output
; Channel 3
decf IH_channel3cnt,f; decrease channel 3 count
btfsc STATUS,Z ; if zero then set output
bcf channel3op ; set output
; Channel 4
decf IH_channel4cnt,f; decrease channel 4 count
btfsc STATUS,Z ; if zero then set output
bcf channel4op ; set output
incf IH_position_count,f ; increse pulse count
bcf INTCON,T0IF ; Clear interupt
goto IH_Interrupt_Poll
IH_RB0 bsf STATUS,RP0 ; change to bank 1
btfsc OPTION_REG,INTEDG ; Test which edge of zerocross looking for
goto IH_RB0_End ; 1 = rising edge
IH_RB0_Start
bsf OPTION_REG,INTEDG ; set to look for Rising Edge
bcf OPTION_REG,T0CS ; Enable timer 0
bcf STATUS,RP0 ; move back to bank 0
bcf INTCON,INTF ; Clear interupt flag
clrf IH_position_count ; clear pulse count
bsf INTCON,T0IF ; Create timer Interupt
clrf TMR1L ; Clear Timer1
clrf TMR1H
bcf flag,mains_fail ; and flags....
btfsc PIR1,RCIF ; Is USART interrupt Pending ?
goto IH_Check_USART ; Yes, Do USART rec bit before going to handler.
incfsz IH_Timer_Count,f ; No, Increase No DMX Data Count
goto IH_Interrupt_Poll ; If NOT Zero then goto handler
if basic == 1
bcf Data_Rec_LED ; If Zero, Clear DMX data recieve LED
bcf Data_Error_LED ; And the DMX Error LED
endif
bcf flag,DMX_Data ; Clear DMX recieve flag
clrf Iflag ; Clear any DMX data being recieved
goto IH_Interrupt_Poll
IH_RB0_End
bsf OPTION_REG,T0CS ; Disable Timer 0
bcf INTCON,INTF ; Clear Interupt flag
bcf OPTION_REG,INTEDG ; Set RB0 Interupt to falling edge
bcf STATUS,RP0 ; change to bank 0
movlw .254
movwf PORTB ; clear ouputs
movf channel1update,w ; reload channel count
movwf IH_channel1cnt
movf channel2update,w ; reload channel count
movwf IH_channel2cnt
movf channel3update,w ; reload channel count
movwf IH_channel3cnt
movf channel4update,w ; reload channel count
movwf IH_channel4cnt
movf IH_position_count,w ; save pulse count
movwf position_count
bsf flag,phase_done
decfsz IH_Long_Count,f ; Decrease Long Count
goto IH_Interrupt_Poll
bsf flag,longcount ; set long count
goto IH_Interrupt_Poll
IH_Check_USART
bcf PIR1,RCIF ; Clear Interupt flag
;bsf Data_Rec_LED ; Set DMX Data LED
IH_Check_HW_Overrun
btfsc RCSTA,OERR ; Has a HW overrun occurred ?
goto IH_HW_Overrun ; Yes, do a HW reset
IH_Check_9th_bit
clrf IH_Timer_Count ; Clear Timer count
btfss RCSTA,RX9D ; Dose 9th Bit of data = 1, eg Break
goto IH_Wait_Break ; Yes, start receiving again
IH_Check_SW_Overrun
btfsc RCSTA,FERR ; Has a framing error occurred ?
goto IH_SW_Overrun ; Yes, do a Usart reset
IH_Test_Flags
btfsc Iflag,Valid_Channel ; Test to see if receiving valid channels
goto IH_Valid_Channel ; Yes, get next channel
btfsc Iflag,Start_Detected ; Test to see it start byte has arrived
goto IH_Wait_Channel ; Yes, Check Channel counts
btfsc Iflag,Break_Detected ; Test to see if break has arrived
goto IH_Wait_Start ; Yes, wait for start byte
IH_Wait_Break
clrf Iflag ; Clear all interupt flags
movf RCREG,w ; Move recieved data in to w
btfsc RCSTA,RX9D ; Test if break has arrived
goto IH_Interrupt_Poll ; No, Break not detected
btfsc STATUS,Z ; Yes, Dose detected break =0 ?
bsf Iflag,Break_Detected ; Yes, set flag to indicate break arrived
goto IH_Interrupt_Poll
IH_Wait_Start
clrf IH_Channels_Recieved ; Clear number of channels recieved
clrf IH_Channel_Count_L ; Clear Low channel count
clrf IH_Channel_Count_H ; Clear High channel count
bsf Iflag,Start_Detected ; Set flag to indicate Start Byte arrived
movf RCREG,w ; Check start code = 0
btfss STATUS,Z ;
clrf Iflag ; if No then clear flags and wait for next break
goto IH_Interrupt_Poll
IH_Wait_Channel
movf RCREG,w ; Store Recieved value in temp
movwf IH_Temp
incf IH_Channel_Count_L,f ; Increase channel count
btfsc STATUS,Z ; for both Low and High bytes
incf IH_Channel_Count_H,f ;
movf IH_Channel_Count_H,w ; Compare the high byte of channel count to
xorwf DMX_Start_Addr_H,w ; DMX start address
btfss STATUS,Z ; If Not equal then exit
goto IH_Interrupt_Poll
movf IH_Channel_Count_L,w ; Compare the low byte of channel count to
xorwf DMX_Start_Addr_L,w ; DMX Start address
btfss STATUS,Z ; if not equal then exit
goto IH_Interrupt_Poll
bsf Iflag,Valid_Channel ; if address equal then set valid channels
movf IH_Temp,w
movwf Channel_Values ; Store value in first channel
incf IH_Channels_Recieved,f ; and increase count
goto IH_Interrupt_Poll
IH_Valid_Channel
movlw Channel_Values ; Load address of memory block
addwf IH_Channels_Recieved,w ; add channel offset
movwf FSR ; and move in to FSR
movf RCREG,w ; Store result in the
movwf INDF ; channel position in memory
movf IH_Channels_Recieved,w ;
incf IH_Channels_Recieved,f ; Increase count (Note No effect on w !)
xorwf Channels,w ; Check if all channels recieved
btfss STATUS,Z ;
goto IH_Interrupt_Poll ; No, then return to interupt poll
clrf Iflag ; Yes, Clear flags and wait for break
if basic == 1
bsf Data_Rec_LED ; Set DMX Data LED
endif
bsf flag,DMX_Data ; Set DMX Data recieve flag
goto IH_Interrupt_Poll ; exit back to Handler
IH_HW_Overrun
bcf RCSTA,CREN ; Reset UART
bsf RCSTA,CREN ; receive logic
bsf flag,dmx_error ; Turn on hardware overrun LED
if basic == 1
bsf Data_Error_LED ; Turn on DMX Error led
endif
goto IH_Check_9th_bit
IH_SW_Overrun
bcf RCSTA,CREN ; reset UART
bsf RCSTA,CREN ; receive logic
bsf flag,dmx_error ; Turn on software Overrun Led
if basic == 1
bsf Data_Error_LED ; Turn on DMX Error led
endif
goto IH_Test_Flags
IH_Timer1 ; Mains Phase Fail
bcf PIR1,TMR1IF ; Clear interupt flag
bsf flag,mains_fail ; Set Mains Fail Flag
movlw .254
movwf PORTB ; clear ouputs
goto IH_Exit
; ---------------------------------------------------------------------------
seg_table ; Table for 7 Segment display
addwf PCL,f ; Place before possible programme
retlw .129 ; 0
retlw .243 ; 1
retlw .73 ; 2
retlw .97 ; 3
retlw .51 ; 4 ; Web Site Version
retlw .37 ; 5
retlw .7 ; 6
retlw .241 ; 7
retlw .1 ; 8
retlw .49 ; 9
retlw .67 ; d
retlw .17 ; A
retlw .25 ; P
retlw .13 ; E
retlw .79 ; c
retlw .23 ; h
retlw .255 ; <OFF>
; ---------------------------------------------------------------------------
Start clrf PORTA ; \
movlw .254 ; Clear ports
movwf PORTB ;
clrf PORTC ; /
clrf flag ; Clear flag register
clrf flag2
clrf Iflag ; Clear Interupt flag
clrf dflag ; Clear Display Flags
clrf DMX_Start_Addr_L; Clear DMX Address
clrf DMX_Start_Addr_H;
clrf Current_Preset
clrf olddisplayvalue
clrf STATUS ; Clear status
bsf STATUS,RP0 ; Set up port I/O directions
movlw B'11111111' ; 1 = Input 0 = Output
movwf TRISA ; Make PORTA all input
movlw B'00000001'
movwf TRISB ; Make PORTB all Output expect PB0
movlw B'000000000' ; Set AN0 - AN4 As analogue inputs left justified
movwf ADCON1
movlw B'11001000' ; set up options - Timer0 from instruction cycle clock with
movwf OPTION_REG ; no prescaler
Get_DMX_Address
movlw B'10001111' ; Set Up Switch directions
movwf TRISC
bcf STATUS,RP0 ; Go back to bank 0
nop
movlw B'00010000' ; Enable first bank of switches
movwf PORTC
call Delay ; Go for a little delay
movf PORTC,w ; Read Port C
andlw B'00001111' ; Mask un required bits
movwf DMX_Start_Addr_L; Store in addrees Low
movlw B'00100000' ; Get next bank of switches
movwf PORTC
call Delay
swapf PORTC,w ; Read switches and swap nibbles
andlw B'11110000' ; Mask undesirables
iorwf DMX_Start_Addr_L,f ; Store Higher nibble
movlw B'01000000' ; Get final bank of switches
movwf PORTC
call Delay
movf PORTC,w ; get switches
andlw B'00001111' ; mask narstry bits
movwf process_temp
andlw B'00001110' ; store other switch settings in flags.
movwf flag
btfsc process_temp,0 ; look for high address bit.
incf DMX_Start_Addr_H,f ; and set if required
clrf PORTC ; Clear Port C
movf DMX_Start_Addr_H,w
movwf NumH ; Load BIN -> BCD Converter
movf DMX_Start_Addr_L,w
movwf NumL
call bin2dec999fast ; Get BCD version of DMX Start Address
if basic == 1 ; ONLY DO FOR BASIC PACK
bcf Data_Rec_LED ; Turn off Data Recieve LED
bcf Data_Error_LED ; Turn Off DMX Error LED
endif
store_Number_channels
movlw Number_Of_Channels
movwf Channels ; Load Number of channels to recieve and store
; Initialize UART
bsf STATUS,RP0
movlw Baud_Rate_Constant
movwf SPBRG
bsf TXSTA,BRGH
bcf TXSTA,SYNC
bsf PIE1,RCIE
bcf STATUS,RP0
bsf RCSTA,RX9
bsf RCSTA,CREN
bsf RCSTA,SPEN
movlw B'10000001' ; Switch on the ADC channel RA0 20Mhz crystal
movwf ADCON0
movlw Timer0_cnt
movwf countervalue ; load counter reload variable
movwf TMR0 ; Load counter
bsf OPTION_REG,T0CS ; Disable timer 0
movlw B'00110001' ; Setup Timer1
movwf T1CON ; 1:8 Prescale - internal osc...
clrf TMR1L ; Clear Timer
clrf TMR1H
bsf STATUS,RP0 ; Bank 1
bsf PIE1,TMR1IE ; Enable Timer 1 Interupt
bcf STATUS,RP0
; Interrupts
clrf INTCON
bsf INTCON,PEIE
bsf INTCON,INTE ; Enable RB0 Interupt
bsf INTCON,T0IE ; Enable Timer0 Interrupts
bsf INTCON,GIE ; Enable global interrupts
; -----------------------------------------------------------------
Main
btfsc flag,mains_fail ; Is Mains Ok ??????
call D_Mains_Fail ; No,
btfsc flag,DMX_Data ; Is DMX Data being recieved ?
goto load_update_reg ; Yes, then just updata channels
if basic == 0 ; ONLY DO FOR Normal PACK
btfsc flag,presetmode ; Is preset mode selected ??? ***
goto preset_mode ; Yes, ***
endif
Get_Analogue_Values ; No, get Analogue values
movlw B'10000001' ; select Channel 1 in A2D
movwf ADCON0
call Delay
bsf ADCON0,GO ; start ADC conversion
nop
nop
wait1 btfsc ADCON0,GO ; Loop till conversion complete
goto wait1
movf ADRESH,w ; get and
movwf Channel_Values ; store channel 1
nop
movlw B'10001001' ; select Channel 2 in A2D
movwf ADCON0
call Delay
bsf ADCON0,GO ; start ADC conversion
nop
nop
wait2 btfsc ADCON0,GO ; Loop till conversion complete
goto wait2
movf ADRESH,w ; get and
movwf (Channel_Values+1) ; store channel 2
nop
movlw B'10010001' ; select Channel 3 in A2D
movwf ADCON0
call Delay
bsf ADCON0,GO ; start ADC conversion
nop
nop
wait3 btfsc ADCON0,GO ; Loop till conversion complete
goto wait3
movf ADRESH,w ; get and
movwf (Channel_Values+2) ; store channel 3
nop
movlw B'10011001' ; select Channel 4 in A2D
movwf ADCON0
call Delay
bsf ADCON0,GO ; start ADC conversion
nop
nop
wait4 btfsc ADCON0,GO ; Loop till conversion complete
goto wait4
movf ADRESH,w ; get and
movwf (Channel_Values+3) ; store channel 4
load_update_reg
movf Channel_Values,w ; copy and invert value from Channel 1
call process_curve ; Get value form curve
movwf channel1update
movf (Channel_Values+1),w; copy and invert value from Channel 2
call process_curve ; Get value from curve
movwf channel2update
movf (Channel_Values+2),w; copy and invert value from Channel 3
call process_curve ; Get Value from curve
movwf channel3update
movf (Channel_Values+3),w; copy and invert value from Channel 4
call process_curve ; Get value from curve
movwf channel4update
clrf PCLATH ; Clear PCLATH from scurve.
btfss flag,phase_done ; is phase complete ??
goto Main ; No,
call find_countervalue ; Yes, update counter value
if basic == 0 ; ONLY DO FOR Normal PACK
call display ; Do display ***
endif
goto Main
-
aqui la 3ra Parte
; *******************************************************
; * Preset Mode *
; *******************************************************
preset_mode
bsf STATUS,RP0 ; Move to bank 1
movlw B'00000110' ; Set port A as digital inputs.
movwf ADCON1
bcf STATUS,RP0 ; return to bank 0
nop ; delay to reset porta
nop
movf PORTA,w ; copy port A in to shadowa
movwf shadowa
xorwf oldporta,w ; look for changes
andwf shadowa,w ; look for rising edge only.
movwf oldporta ; and store in oldporta !
btfsc oldporta,4
call channel5
btfsc oldporta,5
call channel6
movf shadowa,w
movwf oldporta
btfss flag2,savepreset ; if save preset active then
goto load_update_reg
bsf STATUS,RP0 ; move to bank 1
movlw B'00000010' ; set PORTA back to Analogue
movwf ADCON1
bcf STATUS,RP0 ; return to bank 0
nop ; Delay to reset
nop
goto Get_Analogue_Values ; display analogue values
channel5
btfsc flag2,savepreset ; Is save preset in progress
goto save_to_ee ; Yes,
btfsc shadowa,5 ; No, both buttons pressed ??
goto save_preset ; Yes,
movf Current_Preset,w ; No, Load Current Preset in to Status register
movlw Max_Preset+1 ; set up w with new value
btfsc STATUS,Z ; current preset = 0 ??
movwf Current_Preset ; Yes, reload with maxium value then
decf Current_Preset,f ; No, decrease current preset
goto update_preset
channel6
btfsc flag2,savepreset ; Is save preset in progress
goto save_to_ee ; Yes,
btfsc shadowa,4 ; No, Both buttons presed ?
goto save_preset ; Yes,
incf Current_Preset,f ; No, Increse present preset
movf Current_Preset,w
sublw Max_Preset ; subtract max preset from preset
btfsc STATUS,C ; To Large ??
goto update_preset
clrf Current_Preset
update_preset
movf Current_Preset,w ; Move current preset to ee_address (in all Mem)
movwf ee_address
rlf ee_address,f ; * 4.
rlf ee_address,f
call ee_read ; Get channel 1 value
movwf (Channel_Values)
incf ee_address,f
call ee_read ; Get channel 2 value
movwf (Channel_Values+1)
incf ee_address,f
call ee_read ; Get channel 3 Value
movwf (Channel_Values+2)
incf ee_address,f
call ee_read ; Get channel 4 Value
movwf (Channel_Values+3)
return
save_preset
bsf flag2,savepreset ; Set save preset mode
return
save_to_ee
btfss shadowa,4 ; Check CH5 is selected.
return ; No,
btfss shadowa,5 ; Check CH6 is selected
return ; No,
movf Current_Preset,w ; Yes, Both channels
movwf ee_address ; set up EEaddress with current preset
rlf ee_address,f ; * 4
rlf ee_address,f
movf (Channel_Values),w
movwf ee_data
call ee_write ; save Channel 1 Value
incf ee_address,f
movf (Channel_Values+1),w
movwf ee_data
call ee_write ; save Channel 2 Value
incf ee_address,f
movf (Channel_Values+2),w
movwf ee_data
call ee_write ; Save Channel 3 Value
incf ee_address,f
movf (Channel_Values+3),w
movwf ee_data
call ee_write ; save Channel 4 Value
bcf flag2,savepreset ; Clear flag
clrf oldporta ; to prevent rerunning
return
; *********************************************************
; * Display Errors *
; * Input - flags Output - Nothing *
; *********************************************************
D_Mains_Fail
if basic == 1
bsf Data_Rec_LED ; Switch On Both LEDs
bsf Data_Error_LED ;
else
movlw .15 ; Display a F for Mains Fail
call seven_seg
endif
bcf INTCON,T0IE ; Disable Timer0 Interrupts
D_No_Mains_Loop ; No Mains Loop........
btfsc flag,mains_fail
goto D_No_Mains_Loop
call Delay
bsf INTCON,T0IE ; Enable Timer0 Interrupts
return
; ***********************************************
; * Display Routien *
; * Input - Control flags output - Nothing *
; ***********************************************
display
btfsc flag,DMX_Data ; Dmx Currently ??
goto dmx_display ; Yes,
movlw B'11110000' ; No, Clear dmx part of dflag
andwf dflag,f
bcf flag,dmx_error ; clear dmx error flag
btfsc flag,presetmode ; In Preset Mode Currently
goto preset_display ; Yes,
analogue_display ; No,
movlw .11 ; Display A
goto seven_seg
dmx_display
bcf dflag,preset_intro
btfsc flag,dmx_error ; Dmx error recieved ??
goto display_error ; Yes,
btfsc dflag,dmx_lsb ; Displaying LSB ??
goto display_d ; Yes,
btfsc dflag,dmx_csb ; Displaying CSB ??
goto display_lsb ; Yes,
btfsc dflag,dmx_msb ; Displaying MSB ??
goto display_csb ; Yes,
btfsc dflag,dmx_recieve ; Displaying New d ??
goto display_msb ; Yes,
clrf IH_Long_Count
bcf flag,longcount ; Clear and reset Long Count
bsf dflag,dmx_recieve
movlw .10 ; display d.
goto seven_seg
display_msb
btfss flag,longcount ; Has long count finished ??
return ; No,
clrf IH_Long_Count ; Yes, reset long count
bcf flag,longcount
bsf dflag,dmx_msb ; set display flag
movf dmx_hund,w ; and display
goto seven_seg
display_csb
btfss flag,longcount ; Has long count finished ??
return ; No,
clrf IH_Long_Count ; Yes, reset long count
bcf flag,longcount
bsf dflag,dmx_csb ; set display flag
movf dmx_ten,w ; and display
goto seven_seg
display_lsb
btfss flag,longcount ; Has long count finished ??
return ; No,
clrf IH_Long_Count ; Yes, reset long count
bcf flag,longcount
bsf dflag,dmx_lsb ; set display flag
movf dmx_one,w ; and display
goto seven_seg
display_d
btfss flag,longcount ; Has long count finished ??
return
movlw .10 ; Value for d
goto seven_seg ; And display
display_error movlw .13 ; Value for E
goto seven_seg ; and display
preset_display
btfsc flag2,savepreset ; Preset Save taking Place ??
goto display_save ; Yes,
btfsc dflag,preset_intro ; Done Intro Yet ??
goto display_current_preset ; Yes,
display_p
bsf dflag,preset_intro ;
clrf IH_Long_Count ; clear and reset long count.
bcf flag,longcount
movlw .12 ; Value for p
goto seven_seg
display_current_preset
btfss flag,longcount ; Wait for long count
return
movf Current_Preset,w ; display current preset (0 - 9)
goto seven_seg
display_save movlw .14 ; Save chacture = c
goto seven_seg
; ***********************************************
; * 7 Segment Display Drive *
; * Input - w Output = Nothing *
; ***********************************************
seven_seg
movwf displayvalue
xorwf olddisplayvalue,w ; Has display value changed ?
btfsc STATUS,Z ;
return ; No,
; Yes, Display neww value
movf displayvalue,w
movwf olddisplayvalue ; Update old display value
call seg_table
movwf displayvalue
movlw .8
movwf display_count
seven_loop
bcf display_clk ; End of clock pulse
nop
btfsc displayvalue,0 ; Set next data output
bsf display_data
btfss displayvalue,0
bcf display_data
nop
nop
rrf displayvalue,f ; set up next data value
nop
bsf display_clk ; start of clock pulse
nop
nop
decfsz display_count,f ; all data done yet ??
goto seven_loop
return
; *************************************************
; * Find counter value required *
; * Input - position_count output - countervalue *
; *************************************************
find_countervalue ; find amount left on counter and adjust counter
; value to make counter = 255 at end.
bcf flag,phase_done ; do this only after new mains cycle.
btfss position_count,7; if position count >128 then decrese count
goto lower_count ; else increase count
higher_count movf position_count,w
sublw .255 ; Sutract 254 from positioncount
btfsc STATUS,C ; if < 0 then
incf countervalue,f ; increase count
return
lower_count movf position_count,w
sublw .1 ; Sutract 2 from positioncount
btfss STATUS,C ; if > 0 then
decf countervalue,f ; decrease count
return
; ******************************************************
; * EEREAD *
; * *
; * ee_address = Address in EEPROM w = data read *
; ******************************************************
ee_read
bsf STATUS,RP1 ; Move to bank 2
movf ee_address,w
movwf EEADR ; Store eeaddress in correct location
bsf STATUS,RP0 ; Go to Bank 3
bcf EECON1,EEPGD ; Point to Data Memory
bsf EECON1,RD ; Start EEprom read cycle
bcf STATUS,RP0 ; Back to bank 2
movf EEDATA,w
bcf STATUS,RP1 ; Bank to bank 0
return
; ******************************************************
; * EEWRITE *
; * *
; * EEadr = Address in EEPROM eedata = data to write *
; ******************************************************
ee_write
bcf PIR2,EEIF ; clear EE interupt flag
bsf STATUS,RP1 ; Move to bank 2
bcf STATUS,RP0 ;
movf ee_address,w
movwf EEADR ; Save eeaddress
movf ee_data,w
movwf EEDATA ; save eedata
bsf STATUS,RP0 ; Move to bank 3
bcf INTCON,GIE ; Disable interupts
bcf EECON1,EEPGD ; Access Data Memory
bsf EECON1,WREN ; put WREN
movlw H'55'
movwf EECON2
movlw H'AA'
movwf EECON2
bsf EECON1,WR ; write cycle started
bcf STATUS,RP0 ; goto Bank 0
bcf STATUS,RP1
wr1 clrwdt
btfss PIR2,EEIF ; wait for EE write interupt flag
goto wr1 ; write cycle wait
bsf INTCON,GIE ; Enable all interupts
return
; ***********************************************
; * Fast binary to decimal conversion (0..999) *
; * *
; * Input: NumH:NumL *
; * Output Hund:Tens_Ones (packed BCD) *
; * *
; * Size: 59 instructions *
; * Execution time (with return): 60 *
; * *
; * 8-July-2000 by Nikolai Golovchenko *
; * Based on 8bit BIN2BCD of Scott Dattalo *
; ***********************************************
bin2dec999fast
swapf NumL,w ;Add the upper and lower nibbles
addwf NumL,w ;to get the one's digit
andlw 0x0F
skpndc ;Go through a binary to bcd
addlw 0x16 ;conversion for just the one's
skpndc ;digit
addlw 0x06
addlw 0x06
skpdc
addlw -0x06
btfsc NumL,4 ;bit 4 is a special case
addlw 0x16 - 1 + 0x6
skpdc
addlw -0x06 ;now adjust the ten's digit
btfsc NumL,5 ;2^5 = 32, so add 3 to the ten's
addlw 0x30 ;digit if bit 5 is set
btfsc NumL,6 ;2^6 = 64, so add 6
addlw 0x60 ;if bit 6 is set
btfsc NumL,7 ;2^7 = 128, so add 2 (the ten's
addlw 0x20 ;digit) if bit 7 is set
addlw 0x60 ;convert the ten's digit to bcd
clrf Hund
rlf Hund,f ;if there's a carry, then the input
btfss Hund,0 ;was greater than 99.
addlw -0x60
movwf Tens_Ones
movlw 0x66 ;2^8 = 256, so add 0x56 to Tens_Ones
btfsc NumH,0
movlw 0x56 + 0x66 ;add 0x66 for decimal adjust
addwf Tens_Ones,f
skpnc
incf Hund,f
clrw
skpc
iorlw 0x60
skpdc
iorlw 0x06
subwf Tens_Ones,f
movlw 0x66 ;2^9 = 512, so add 0x12 to Tens_Ones
btfsc NumH,1
movlw 0x12 + 0x66
addwf Tens_Ones,f
skpnc
incf Hund,f
clrw
skpc
iorlw 0x60
skpdc
iorlw 0x06
subwf Tens_Ones,f
btfsc NumL,7 ;finish with hundreds
incf Hund,f
movlw 2
btfsc NumH,0
addwf Hund,f
movlw 5
btfsc NumH,1
addwf Hund,f
split
movf Hund,w
movwf dmx_hund
movf Tens_Ones,w
andlw 0Fh
movwf dmx_one
swapf Tens_Ones,w
andlw 0Fh
movwf dmx_ten
return
; *******************************************************
; * Delay Loop *
; * No Input No Output *
; *******************************************************
Delay
movlw Delay_Value
movwf Delay_Count
Delay_Loop
decfsz Delay_Count,f
goto Delay_Loop
return
; *******************************************************
; * Process Required Curve *
; * Input - w controls in flag output in w *
; * Inverts input to output
; *******************************************************
process_curve
movwf process_temp ; Save value in w
btfsc flag,switch ; Switching required ??
goto process_switching ; yes,
btfsc flag,curve ; Cuve or linear ??
goto process_scurve ; Curve
process_linear
comf process_temp,w ; invert value in to w
btfsc STATUS,Z ; If zero then
movlw .1 ; make value = 1
return
process_switching
btfss process_temp,7 ; Look for 50 % value
retlw .254 ; < 50 % ( inverted value)
retlw .1 ; > 50 % ( inverted value)
process_scurve ; Do table lookup.
movwf tbllo ; Store low table value
movlw HIGH (tablestart) ; Get High Table value
movwf PCLATH ; store High Table value
movlw Low (tablestart) ; add lower offset to low value
addwf tbllo,w ;
btfsc STATUS,C ; Carry from the addition ?
incf PCLATH,f ; yes,
;movf tbllo,w
;call do_table
;clrf PCLATH
;return
;addwf PCL,f ; Do Jump
movwf PCL ; Do Jump
tablestart
retlw .255
retlw .249
retlw .243
retlw .238
retlw .234
retlw .230
retlw .227
retlw .223
retlw .221
retlw .218
retlw .215
retlw .213
retlw .211
retlw .209
retlw .207
retlw .205
retlw .203
retlw .202
retlw .200
retlw .198
retlw .197
retlw .195
retlw .194
retlw .193
retlw .191
retlw .190
retlw .189
retlw .188
retlw .187
retlw .185
retlw .184
retlw .183
retlw .182
retlw .181
retlw .180
retlw .179
retlw .178
retlw .177
retlw .176
retlw .175
retlw .175
retlw .174
retlw .173
retlw .172
retlw .171
retlw .170
retlw .169
retlw .169
retlw .168
retlw .167
retlw .166
retlw .166
retlw .165
retlw .164
retlw .163
retlw .163
retlw .162
retlw .161
retlw .161
retlw .160
retlw .159
retlw .159
retlw .158
retlw .157
retlw .157
retlw .156
retlw .155
retlw .155
retlw .154
retlw .154
retlw .153
retlw .152
retlw .152
retlw .151
retlw .151
retlw .150
retlw .149
retlw .149
retlw .148
retlw .148
retlw .147
retlw .147
retlw .146
retlw .145
retlw .145
retlw .144
retlw .144
retlw .143
retlw .143
retlw .142
retlw .142
retlw .141
retlw .141
retlw .140
retlw .139
retlw .139
retlw .138
retlw .138
retlw .137
retlw .137
retlw .136
retlw .136
retlw .135
retlw .135
retlw .134
retlw .134
retlw .133
retlw .133
retlw .132
retlw .132
retlw .131
retlw .131
retlw .130
retlw .130
retlw .129
retlw .129
retlw .128
retlw .128
retlw .127
retlw .127
retlw .126
retlw .126
retlw .125
retlw .125
retlw .124
retlw .124
retlw .123
retlw .123
retlw .122
retlw .122
retlw .121
retlw .121
retlw .120
retlw .120
retlw .119
retlw .119
retlw .118
retlw .118
retlw .117
retlw .117
retlw .116
retlw .116
retlw .115
retlw .115
retlw .114
retlw .114
retlw .113
retlw .113
retlw .112
retlw .112
retlw .111
retlw .111
retlw .110
retlw .110
retlw .109
retlw .109
retlw .108
retlw .108
retlw .107
retlw .107
retlw .106
retlw .106
retlw .105
retlw .105
retlw .104
retlw .104
retlw .103
retlw .103
retlw .102
retlw .102
retlw .101
retlw .100
retlw .100
retlw .99
retlw .99
retlw .98
retlw .98
retlw .97
retlw .97
retlw .96
retlw .95
retlw .95
retlw .94
retlw .94
retlw .93
retlw .92
retlw .92
retlw .91
retlw .91
retlw .90
retlw .89
retlw .89
retlw .88
retlw .87
retlw .87
retlw .86
retlw .85
retlw .85
retlw .84
retlw .83
retlw .83
retlw .82
retlw .81
retlw .81
retlw .80
retlw .79
retlw .78
retlw .78
retlw .77
retlw .76
retlw .75
retlw .74
retlw .74
retlw .73
retlw .72
retlw .71
retlw .70
retlw .69
retlw .68
retlw .68
retlw .67
retlw .66
retlw .65
retlw .64
retlw .63
retlw .62
retlw .61
retlw .59
retlw .58
retlw .57
retlw .56
retlw .55
retlw .54
retlw .52
retlw .51
retlw .50
retlw .48
retlw .47
retlw .45
retlw .43
retlw .42
retlw .40
retlw .38
retlw .36
retlw .34
retlw .32
retlw .30
retlw .27
retlw .25
retlw .22
retlw .19
retlw .16
retlw .12
retlw .8
retlw .3
retlw .0
retlw .0
retlw .0
retlw .0
retlw .0
END ; directive 'end of program
-
aqui os lo pongo completo
-
hola
podrias si no es mucho pedir, explicar que hace el programa y ver si lo podemos enfocar desde otro punto de vista, no me entra en el coco que hace el programa
he visto alguna cosilla que a lo mejor es una tonteria. para utilizar la tabla tablestart lo tienes escrito así
movwf PCL ; Do Jump
tablestart
retlw .255
retlw .249
retlw .243
retlw .238
retlw .234
retlw .230y creo que deberia de ser asi, que es como esta en el tutorial de tablas que me enviaste
La tabla de la verdad se sitúa desbordando los primeros 256 bytes de memoria de programa.
ORG .254 ; Cerca del borde de la primera página de 256 bytes.
TablaVerdad ; Posición 0x00FE de memoria de programa (PCH-PCL).
movwf PCL ; El salto dentro de la tabla: PCH=PCLATH, PCL=W.
retlw b'00001010' ; (Configuración 0). Posición 0x00FF.
retlw b'00001001' ; (Configuración 1). Posición 0x0100.
retlw b'00100011' ; (Configuración 2). Posición 0x0101.
retlw b'00001111' ; (Configuración 3). Posición 0x0102.
retlw b'00100000' ; (Configuración 4). Posición 0x0103.
retlw b'00000111' ; (Configuración 5). Posición 0x0104.
retlw b'00010111' ; (Configuración 6). Posición 0x0105.
retlw b'00111111' ; (Configuración 7). Posición 0x0106.
ENDademas que si te fijas utilizas movwf pcl este pone el valor de w en pcl y si no esta alprincipio de pagina deberias usar addwf pcl de esta forma da casi igual en que posicion este la tabla
un saludo espero te ayude
-
Gracias por contestar!
esto es un DMX Dimmer
que se controla con entrada analoga de 0 a 10 Voltio, pero solo son 4 canales, si te fija en el circuito donde esta mi projecto alli esta el Circuito, bien tambien se controla DMX pero no me funciona y creo que el problema radica en la Direciones de los canales, como puede apreciar el Circuito tiene un Dip switch para configurarlo, que puede ser o analogo o digital DMX y la forma de controlarlo que puede ser linear dandole una Curva linear o Switch, yo llevo ya 2 semana dandole vuelta y pensando que eran la Resistencia ARRAY que van a los puerto, la cambie de 100k 10k y ahora la tengo a 1k y aun asi nada :?
-
:x :x :x Tiro los Guantes :x :x
-
¿No era problema con el DIP Switch?
-
No manolo!
te explico, yo tengo el Hex y el ASM lo probe con los dos, claro que el Hex lo baje del tipo, ahora bien cuando lo compilo y uso la opcion Basic=1 para usarlo con los LED me funciona raro, es decir la parte analogo sin activar el DIP funciona y cuando pongo la direcion 1 del DIP no me funciona, mido la señale en la entrada del Optocoople y no me sale nada pero cuando lo hago analogo sin activar el DIP en posicion 0 todos y le pongo con un poti y una pila 9Volt me fuciona :x
los DIP switch se que estan bien de acuerdo al Circuito, y yo pienso que es algo en el codio, porque ni los LED me funcionan como deben ser, es decir le invierto la señale de entrada DMX para que me de error y el LED no hace nada, siempre esta activo como Señal es OK!
:x :x :x : Tiro los Guante :x :x
-
Suele suceder que por olvido u otra razon menos tonta, el hex y el archivo fuente no son de la misma version, prueba escribirle al autor a ver si es asi, comentale tus problemas, a ver si se apiada de ti y te da el fuente original y correcto... ;-) ;-) :z)
-
Yo creo que no deberías de tirar la toalla. Llevas un tiempo sobre el proyecto y seguro que alguien te puede ayudar. Yo no trabajo en ensamblador y por consiguiente no te puedo ayudar, pero seguro que los compañeros de ASM te pueden echar una mano. Por otra parte si decides portarlo a "C", seguro que te podremos ayudar.
Un saludo y ánimo, que no se diga que unos cuantos ceros y unos pueden más.
-
Yo creo que no deberías de tirar la toalla. Llevas un tiempo sobre el proyecto y seguro que alguien te puede ayudar. Yo no trabajo en ensamblador y por consiguiente no te puedo ayudar, pero seguro que los compañeros de ASM te pueden echar una mano. Por otra parte si decides portarlo a "C", seguro que te podremos ayudar.
Un saludo y ánimo, que no se diga que unos cuantos ceros y unos pueden más.
gracias Jesus!
eso espero! que alguien me pueda mirar el codigo y ver lo que anda mal, yo no espero que me haga nadie el codigo, simplemente de corregir los fallos,
ya he probado con uC y nada concreto, tengo la sensacion que son los FUSES ya que los DIP SWITCH no reacionan para nada,
:-/ :-/solo espero sugerencia :-/ :-/
-
¿Se podría hacer una simulación en Proteus para probar el programa?
Un saludo
-
¿Se podría hacer una simulación en Proteus para probar el programa?
Un saludo
Hola Jesus!
con el proteus no soy muy fino y no lo he probado, pero si tu pudiera me haria ese favor, aunque voy intentarlo despues!
:mrgreen: gracias Jesus por la Sugerencia :mrgreen:
-
Si tienes el esquema no tendría problema en pasarlo a Proteus.
Un saludo
-
aqui os pongo el Esquema
http://img356.imageshack.us/my.php?image=boardpg8.jpg
-
En cuanto tenga un hueco me pongo a ello.
Un saludo
-
:shock: aqui me salieron varios errores que en los mensajes y no me sale todos lo que puse, oseas esta incompleto :?
amigo Jesus, muchas gracias por contestarme aunque sea tarde, pues bien investigando todos estos tiempos por Red encontre muchas cosas,
y aprendi muchas gracias a mi amigote El Genio de la Botella Alias Nocturno :D :D :D
aparte el poco tiempo que he tenido por motivo de trabajo , pero encontre estos ,
Aqui le pongo la variable, y estoy intentando Compilar tal como esta, y me da un monton de errores, claro este code viene del propio Autor
variable basic=0 ; If Basic =1 then basic version
errorlevel 0, -302
RADIX DEC
list p=16f870 ; list directive to define processor
#include <p16f870.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF
; Programme constants
Start_Vector EQU .0
Interrupt_Vector EQU .4
Common_Ram_Base EQU H'70'
Ram_Base EQU H'20'
Osc_Freq EQU .20000000 ; Pic Frequency
Instruction_rate EQU Osc_Freq/.4 ; Instruction Rate
; Phase control constants
Resolution EQU .256 ; Analogue dimming resolution
Mains_freq EQU .100 ; 100 Parts a second
Interupts_s EQU Mains_freq*Resolution ; Interupts per second
Amount_to_cnt EQU Instruction_rate/Interupts_s ; number to count in timer0
Timer0_cnt EQU .256-Amount_to_cnt ; invert value to count (timer0 counts till overflow)
Delay_Value EQU .40
; DMX Constants
Baud_Rate EQU .250000
Baud_Rate_Constant EQU (Osc_Freq/(.16*Baud_Rate))-.1
Number_Of_Channels EQU .6
startcode EQU .0
; Preset Constants
Max_Preset EQU .9 ; Maxium Presets allowed (EEdata = max * 4 bytes)
; *********** Define Flags *************
; IFlag
Break_Detected equ 0 ; Break detected
Start_Detected equ 1 ; Start Byte detected
Valid_Channel equ 2 ; Reached valid channels
No_DMX_Data equ 7 ; No recieved DMX Data
; Flag
longcount equ 0 ; Long count flag (2.5s) when activated
presetmode equ 1 ; Preset Mode on no DMX data
curve equ 2 ; S Curve selected
switch equ 3 ; Switch curve selected
DMX_Data equ 4 ; New DMX Data recieved
phase_done equ 5 ; Flag to show mains phase complete
dmx_error equ 6 ; Error detected in DMX tranmission
mains_fail equ 7 ; Maind Failure Flag
; Flag2
savepreset equ 0 ; save preset started flag
; DFlag
dmx_recieve equ 0 ; Dmx recieve display
dmx_msb equ 1 ; Displaying DMX MSB
dmx_csb equ 2 ; Displaying DMX CSB
dmx_lsb equ 3 ; Displaying DMX LSB
preset_intro equ 4 ; Displaying Preset Intro
; control ports
#DEFINE Zerocross PORTB,0
#DEFINE channel1op PORTB,1
#DEFINE channel2op PORTB,2
#DEFINE channel3op PORTB,3
#DEFINE channel4op PORTB,4
#DEFINE Data_Rec_LED PORTC,4 ; Not Used on 7 seg Pack ***
#DEFINE Data_Error_LED PORTC,5 ; Not Used on 7 seg Pack ***
#DEFINE display_clk PORTC,5 ; Not Used on Basic Version
#DEFINE display_data PORTC,4 ; Not Used on basic Version
voy a tener que estudiarlo para acaba con este lio de projectos :D
quizas alguien encontres Solucion
Gracias por todas ayudas
-
No entiendo ese código, Rafael, ¿sabes qué compilador de Basic hay que usar?
En cualquier caso, sólo has pegado la parte de las definiciones, ¿no?
-
tu no entiende y meno yo tampoco, me meti en el Foro del Autor en epanorama.net y de ahi lo baje ya que muchos estaban con dudas como yo, ahora mismo no tengo tiempo porque estoy en el Curro, pero estoy buscando Info de eso, no se que compilador usa y creo que es Basic pro algo asi
:x :x
Saludo
-
El programa está en ensamblador y la página con el programa es:
http://www.epanorama.net/digipack/Digi_Pack/dmx_pack.asm
Y en la página del autor esta la información:
http://www.epanorama.net/digipack/
Y aquí está un fichero Zip con el esquema, el programa fuente y el HEX ya compilado:
http://www.epanorama.net/digipack/Digi_Pack/dmx_pack.zip
Un saludo
-
Muchas gracias Jesus!
pero debo decirte que de ahi mismo me lo baje desde un principio, solo que con tu observa en el Define yo no veo claro ya que los ponr con Mplab y me salio muchos errores, lastima desde aqui donde trabajo no puedo ahora probarlo.
Saludo