Hello,
Looking at the titles of some of the other posts here I feel a little out of my depth, but what the hell. Here's an easy problem for you to solve for once.
Right, im doing a project at Uni, we've been told we need to program a PIC as part of this project, which sounds a bit harsh to me as we haven't had any lectures on it and aren't due to before the hand in date.
So im trying to learn how they work along with getting my head around BASIC. I bought a PIC programmer VM111/K8048. It came with PIC16F627 I can get the basic demos to work, but as soon as I try anything of my own it all fails. I found a basic flashing LED program that was written for the 16F627, so I thought i'd give it a go, but can't for the life of me get the thing to work, here's the code,
LIST P=PIC16F627
INCLUDE C:\PicProg2009\Include\P16F627.inc
LOOP EQU 0x20
init BSF STATUS, RP0
BCF PCON, OSCF
MOVLW 0x00
MOVWF TRISB
BCF STATUS, RP0
LED_on BSF PORTB, 0
delay_1 DECFSZ LOOP, 1
GOTO delay_1
LED_off BCF PORTB, 0
delay_2 DECFSZ LOOP, 1
GOTO delay_2
GOTO LED_on
END
Sorry about the format, I assure you the spaces are in the correct place in my notepad file. From the datasheet the oscillator is at 37Khz, I did try adding some additional loops to keep the led on and off for longer but all I ever get is permanent ON LED. So I added this in place of LED_on and delay_1
LED_on BSF PORTB,0
MOVLW 0xFF
MOVWF LOOP
delay_1 DECFSZ LOOP,1
GOTO delay_1
MOVLW 0xFF
MOVWF LOOP
A1 DECFSZ LOOP,1
GOTO A1
MOVLW 0xFF
MOVWF LOOP
A2 DECFSZ LOOP,1
GOTO A2
I also added this to delay_2 but this made no difference, no matter how many times I add the loop the LED remains on. I just need some kind of foothold so I know what the hell is going on then I can build from there but at the moment nothing makes any sense.
Thanks for any help you can give me, even if it's just a slap round the head.
list p=16F627
include <16F627.inc>
__config _CP_OFF & DATA_CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
;No code protection (_CP_OFF)
;No data code protection (_DATA_CP_OFF)
;Low Voltage Programming off (_LVP_OFF)
;Brown Out Detection Off (_BODEN_OFF)
;Master Reset pin active (_MCLRE_ON)
;Power Up Timer on (_PWRTE_ON)
;Watchdog Timer off (_WDT_OFF)
;Internal RC oscillator (_INTRC_OSC_NOCLKOUT)
LOOP EQU 0x20 ;label address 0x20 with LOOP
init bsf STATUS, RP0 ;change to Bank 1
bcf PCON, OSCF ;set internal oscillator frequency to 37kHz
movlw 0x00 ;set Port A as all outputs
movwf TRISA
movlw 0x00 ;set Port B as all outputs
movwf TRISB
bcf STATUS,RP0 ;change to Bank 0
LED_on bsf PORTB, 0 ;turn on LED
call delay_1 ;wait
LED_off bcf PORTB, 0 ;turn off LED
call delay_1 ;wait
goto LED_on ;do it again
delay_1 movlw 0xFF ;start delay counter at 255
movwf LOOP
W8 decfsz LOOP, 1 ;decriment delay counter, branch if zero
goto W8 ;go back
return ;return from subroutine
end
list p=16f627 ; list directive to define processor
#include <p16f627.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & __INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_ON
cblock 0x20 ;start of general purpose registers
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
endc
org 0x0000 ;org sets the origin, 0x0000 for the 16F628,
;this is where the program starts running
movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
bsf STATUS, RP0 ;select bank 1
movlw b'00000000' ;set PortB all outputs
movwf TRISB
movwf TRISA ;set PortA all outputs
bcf STATUS, RP0 ;select bank 0
Loop
movlw 0xff
movwf PORTA ;set all bits on
movwf PORTB
nop ;the nop's make up the time taken by the goto
nop ;giving a square wave output
call Delay ;this waits for a while!
movlw 0x00
movwf PORTA
movwf PORTB ;set all bits off
call Delay
goto Loop ;go back and do it again
Delay movlw d'250' ;delay 250 ms (4 MHz clock)
movwf count1
d1 movlw 0xC7
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
end
DELAY_ROUTINE MOVLW D'100' ;54 Generate approx 10mS delay at 4Mhz CLK
MOVWF TIMER2
DEL_LOOP1 MOVLW D'100' ;60
MOVWF TIMER1
DEL_LOOP2 BTFSC PORTA,SW1
GOTO MENU
BTFSC PORTA,SW2
GOTO MENU
BTFSC PORTA,SW3
GOTO MENU
BTFSC PORTA,SW4
GOTO MENU
DECFSZ TIMER1,F
GOTO DEL_LOOP2
DECFSZ TIMER2,F
GOTO DEL_LOOP1
RETLW 0
blink_leds: ; this is a label
;your code goes here
goto blink_leds ;you will just sit in this loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Delay you want to return back where it was called
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Loop: ; I like this style of naming easy to read
movlw 0xff
movwf PORTA ;set all bits on
movwf PORTB
nop ;the nop's make up the time taken by the goto
nop ;giving a square wave output
call Delay ;this waits for a while!
movlw 0x00
movwf PORTA
movwf PORTB ;set all bits off
call Delay
goto Loop ;go back and do it again
Delay:
movlw d'250' ;delay 250 ms (4 MHz clock)
D1:
movlw 0xC7
movwf counta
movlw 0x01
movwf countb
Delay_0:
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
end
movf ADRESH,w ; Copy the display to the LEDs
movlw _1VOLT
subwf ADRESH, w
BNC LessThan1V ; Branch if less than 1V
movlw _2VOLT
subwf ADRESH, w
BNC LessThan2V ; Branch if Between 1V and 2V
movlw _2_5VOLT
subwf ADRESH, w
BNC LessThan2_5V ; Branch if Between 2V and 2.5V
movlw _3VOLT
subwf ADRESH, w
BNC LessThan3V ; Branch if Between 2.5V and 3V
movlw _4VOLT
subwf ADRESH, w
BNC LessThan4V ; Branch if Between 3V and 4V
movlw _5VOLT
subwf ADRESH, w
BNC LessThan5V ; Branch if Between 3V and 4V
goto MainLoop
LessThan1V:
movlw b'00000001'
movwf PORTC
goto MainLoop
LessThan2V
movlw b'00000010'
movwf PORTC
goto MainLoop
LessThan2_5V
movlw b'00000100'
movwf PORTC
goto MainLoop
LessThan3V
movlw b'00001000'
movwf PORTC
goto MainLoop
LessThan4V
movlw b'00010000'
movwf PORTC
goto MainLoop
LessThan5V
movlw b'00100000'
movwf PORTC
goto MainLoop
adcdelay:
nop ;1 cycle
return ;4 cycles (including call)
end
I guess it probably helps to know what language your using.
Using the code that Jon Wilder provided above, I wanted to make the LED flash when I pressed one of the buttons on the programming board (button SW1 triggers RA0).
I added this to the init routine,
movlw 0xFF ;set Port A as all inputs(Obviously removed the line that set them as outputs)
movwf TRISA
I then added this inbetween the init and LED_on routines,
MENU btfss PORTA,0 ;Test if bit 0 of PORTA is a 1 and skip next instruction if it is
goto MENU
But I get nothing, the LED doesn't flash whether im pressing SW1 or not. If I remove the MENU part the LED flashes away. Im trying to start with the basics here but im having no luck, it would have been nice for the Uni to actually teach us some of this stuff first, before expecting us to write a program.
I really appreciate the help by the way.
list p=16F627
include <16F627.inc>
__config _CP_OFF & DATA_CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
;No code protection
;No data code protection
;Low Voltage Programming off
;Brown Out Detection Off
;Master Reset pin active
;Power Up Timer on
;Watchdog Timer off
;Internal RC oscillator
LOOP EQU 0x20 ;label address 0x20 with LOOP
init bsf STATUS, RP0 ;change to Bank 1
bcf PCON, OSCF ;set internal oscillator frequency to 37kHz
movlw 0x00 ;set Port A as all outputs
movwf TRISA
movlw 0x00 ;set Port B as all outputs
movwf TRISB
bcf STATUS,RP0 ;change to Bank 0
movlw 0x07 ;disable on chip comparator
movwf CMCON
BUTTON btfsc PORTA,0 ;wait for button to be pressed
goto BUTTON
LED_on bsf PORTB, 0 ;turn on LED
call delay_1 ;wait
LED_off bcf PORTB, 0 ;turn off LED
call delay_1 ;wait
btfss PORTA,0 ;if button is pressed a second time, stop flashing
goto BUTTON_1 ;else continue flashing
goto LED_on ;do it again
delay_1 movlw 0xFF ;start delay counter at 255
movwf LOOP
W8 decfsz LOOP, 1 ;decriment delay counter, branch if zero
goto W8 ;go back
return ;return from subroutine
end
SCRAP THAT
Just added
MOVLW B'00000111' ;Disable Comparator module's
MOVWF CMCON
To the init routine and all is well.
movlw 0x07 ;disable on chip comparator
movwf CMCON
MainLoop:
movf sig_value,w ; Copy the display to the LEDs
movlw Signal_1
subwf sig_value, w
BNC LessThan1 ; Branch if less than 1V
movlw Signal_2
subwf sig_value, w
BNC LessThan2 ; Branch if Between 1V and 2V
movlw Signal_3
subwf sig_value, w
BNC LessThan2_3 ; Branch if Between 2V and 2.5V
movlw Signal_4
subwf sig_value, w
BNC LessThan4 ; Branch if Between 2.5V and 3V
goto MainLoop
LessThan1:
movlw b'00000001'
movwf PORTC ;displays to portc put what you want too happen
goto MainLoop
LessThan2
movlw b'00000010'
movwf PORTC
goto MainLoop
LessThan3
movlw b'00000100'
movwf PORTC
goto MainLoop
LessThan4
movlw b'00001000'
movwf PORTC
goto MainLoop
return ;4 cycles (including call)
end
Yes that's exactly what im doing. I have looked at MPLAB IDE and code composer and about a million other programs, but to be honest, I want to keep it simple at first, using big complicated programs with loads of options just makes it more likely that there's going to be some kind of mistake, by me of course.
I know this is OTP (can't help myself), but I find it hard to imagine going back 30 yrs. to my first editor introduction with IBM Edlin....ughhhh. I have a brother that loves VIMI've been using a text editor called Vim. It's an open source text editor that changes the text color according to the syntax of your code if you save the file with a file extension that matches up with a coding language. This makes it easy to spot syntax errors in your code. Then I use MPASM to assemble it. It's available for Unix based OS'es (i.e. Linux) as well as Windows.
You can download it here -
download : vim online
Cheers guys, at the moment im using the experiment/programmer board, so all the switches and LEDs seem to be set up correctly, but i'll have to keep that in mind when im actually building the thing myself. I think im getting it though, just managed to write a program that counts how long I hold the button down and displays the result in binary using the LEDs, if I press the button really fast 'track and field' style you can see the LEDs building up 1, 10, 11, 100 etc etc. Sweet, I now have some hope that I may be able to do this project. Any ideas on how I can compare two numbers as I mentioned before would be very much appreciated, but other than that you've helped me no end, seriously stressing out a couple of days ago.
Sorry be80be, didn't see your post, i'll check that out later, got some NYE drinking to be done now. Happy New Year!!!
movlw 0x0F ;see if value of register file NUMBER
subwf NUMBER,W ;is equal to 0x0F. Store result in W register.
btfsc STATUS,Z ;branch if equal (if result of subraction operation = 0)
goto A
movlw 0x0F ;see if value of register file NUMBER
xorwf NUMBER,W ;is equal to 0x0F. Store result in W register.
btfsc STATUS,Z ;branch if equal (if result of subraction operation = 0)
goto A
movlw 0x0F ;see if value of register file NUMBER
subwf NUMBER,W ;is equal to 0x0F. Store result in W register.
bz A ;branch if equal (if result of subraction operation = 0)
btfsc STATUS,Z ;branch if equal (if result of subraction operation = 0)
goto A
nickelflippr said:Not an assembler programmer, but If I'm not mistaken be80be's BNC is an 18f instruction. No help for the 16f627 (unless it's a 16f asm mnemonic?).
Jon Wilder Thanks for the link I haven't seen that pdf before nice pdf.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?