Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

LED sequence program

Status
Not open for further replies.

Ambient

New Member
So I have finally written my first PIC program, just wondering if you guys can take a quick look and tell me if it looks alright.

Note:eek:nly error I get is "Register in Operand not in bank 0", but I specified bank 1 already for those instructions. I am assuming it is a default warning just as a reminder.

The purpose of the program is to flash red, white, and blue LED's in sequence, with a 1M ohm pot and A/D (only lower 8 bits) determining the number of times Timer0 has to overflow before going to the next LED in the sequence. I know it may not be the most efficient program, but I just need it to work.

Thanks for any help you can provide.

List p=12f683
include P12F683.INC

Delay EQU 0x0020 ;variable RAM address
Done EQU 0x0021
red EQU b'00000001'
wht EQU b'00000010'
blue EQU b'00000100'

org 0x0000
goto INIT
NOP
NOP
NOP

org 0x0004
GOTO ISR

org 0x0005
INIT
CLRWDT

BSF STATUS,RP0 ;selects memory Bank 1

MOVLW b'01000001'
MOVWF OSCCON ;sets oscillator to 1MHz

MOVLW b'00000001'
MOVWF OPTION_REG ;enables Timer0, 1:4 PS (1.024ms/overflow)

MOVLW b'10100000'
MOVWF INTCON ;enable GIE, Timer0 interrupt

MOVLW b'00000111'
MOVWF CMCON0 ;disables comparator

BCF STATUS,RP0 ;selects memory Bank 0
CLRF GPIO
BSF STATUS,RP0 ;Bank 1 selected
MOVLW b'00010000' ;GP4 analog input enable, FOSC/2
MOVWF ANSEL
MOVLW b'00011000' ;GP0,1,2,5 as outputs, GP3,4 as inputs.
MOVWF TRISIO ;GP3,5 are for future add-ons.

MOVLW b'10001101' ;right justify, VDD ref, AN0, ADON
MOVWF ADCON0

BCF STATUS,RP0 ;Bank 0 selected

START
CLRWDT
CLRF TMR0
BSF ADCON0,GO ;get A/D data for "Delay" variable
BTFSC ADCON0,GO
GOTO $-1
MOVF ADRESL,W
MOVWF Delay
BCF ADCON0,ADON ;disables A/D till next use.


;==================RED=========================
RedON
MOVLW red
MOVWF GPIO ;turns red LED on.
BTFSC Done,h'0001';tests for decrementing complete
GOTO WhtON ;executed when complete
GOTO $-2 ;executed when not complete

;==================WHITE========================
WhtON
MOVLW wht
MOVWF GPIO ;turns white LED on.
BTFSC Done,h'0001'
GOTO BlueON
GOTO $-2

;==================BLUE=========================
BlueON
MOVLW blue
MOVWF GPIO ;turns blue LED on.
BTFSC Done,h'0001'
GOTO RedLoop
GOTO $-2

;*********************ISR************************
ISR
CLRWDT
BCF INTCON,T0IE
DECFSZ Delay,F
RETFIE ;If not done decrementing, returns to current loop
MOVLW h'0001'
MOVWF Done ;done decrementing, places h'1' in "Done" register
RETFIE
END
 
A couple of things I spotted,

You don't clear Done so once set it will stay set.
You should check bit 0 of Done not bit 1.
You don't save the context in you ISR - see the template file in C:\Program Files\Microchip\MPASM Suite\Template\Code it's called 12F683temp.asm and is a good file to start with. Just copy your code into it.

It also helps if you place code tags around your code. Put [co de] and [/co de], without the space, around your code.

Mike.
 
Thanks. The first two were pretty dumb mistakes that I missed. I have fixed those with this new code. I will have to look at your other suggestions when I get up tomorrow. I did not think a simple program like this would need any context saved, as I am not using many advanced features. I will look into it.

Thanks!

List p=12f683
include P12F683.INC

Delay EQU 0x0020 ;variable RAM address
Done EQU 0x0021
red EQU b'00000001'
wht EQU b'00000010'
blue EQU b'00000100'

org 0x0000
goto INIT
NOP
NOP
NOP

org 0x0004
GOTO ISR

org 0x0005
INIT
CLRWDT

BSF STATUS,RP0 ;selects memory Bank 1

MOVLW b'01000001'
MOVWF OSCCON ;sets oscillator to 1MHz

MOVLW b'00000001'
MOVWF OPTION_REG ;enables Timer0, 1:4 PS (1.024ms/overflow)

MOVLW b'10100000'
MOVWF INTCON ;enable GIE, Timer0 interrupt

MOVLW b'00000111'
MOVWF CMCON0 ;disables comparator

BCF STATUS,RP0 ;selects memory Bank 0
CLRF GPIO
BSF STATUS,RP0 ;Bank 1 selected
MOVLW b'00010000' ;GP4 analog input enable, FOSC/2
MOVWF ANSEL
MOVLW b'00011000' ;GP0,1,2,5 as outputs, GP3,4 as inputs.
MOVWF TRISIO ;GP3,5 are for future add-ons.

MOVLW b'10001101' ;right justify, VDD ref, AN0, ADON
MOVWF ADCON0

BCF STATUS,RP0 ;Bank 0 selected

START
CLRWDT
CLRF TMR0
BSF ADCON0,GO ;get A/D data for "Delay" variable
BTFSC ADCON0,GO
GOTO $-1
MOVF ADRESL,W
MOVWF Delay
BCF ADCON0,ADON ;disables A/D till next use.


;==================RED=========================
RedON
BCF Done,h'0000'
MOVLW red
MOVWF GPIO ;turns red LED on.
BTFSC Done,h'0000';tests for decrementing complete
GOTO WhtON ;executed when complete
GOTO $-2 ;executed when not complete

;==================WHITE========================
WhtON
BCF Done,h'0000'
MOVLW wht
MOVWF GPIO ;turns white LED on.
BTFSC Done,h'0000'
GOTO BlueON
GOTO $-2

;==================BLUE=========================
BlueON
BCF Done,h'0000'
MOVLW blue
MOVWF GPIO ;turns blue LED on.
BTFSC Done,h'0000'
GOTO RedLoop
GOTO $-2

;*********************ISR************************
ISR
CLRWDT
BCF INTCON,T0IE
DECFSZ Delay,F
RETFIE ;If not done decrementing, returns to current loop
MOVLW h'0001'
MOVWF Done ;done decrementing, places h'1' in "Done" register
RETFIE
END
 
Actually, you can get away without context saving in your ISR if you use the bsf instruction.

Code:
ISR
	CLRWDT
	BCF	INTCON,T0IE
	DECFSZ	Delay,F
	RETFIE		;If not done decrementing, returns to current loop
	bsf	Done,0	;done decrementing, places h'1' in "Done" register
	RETFIE
However, this is bad practice and sure to cause you problems later.

I also can't see where RedLoop is defined. I think it should be START anyway.

Mike.
 
ah, another mistake. I replaced RedLoop, WhtLoop, and BluLoop in favor of the GOTO $-2. That way I had less code to look at. "RedLoop" is just a remnant that I missed. I deleted the GOTO RedON on accident, but even that was supposed to be GOTO START, as you pointed out. Thanks
 
Last edited:
Fixed the ISR to save the STATUS and W registers

ISR CLRWDT
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
BCF INTCON,T0IE
DECFSZ Delay,F
GOTO CONTEXT ;If not done decrementing, returns to current loop
MOVLW h'0001'
MOVWF Done ;done decrementing, places h'1' in "Done" register
GOTO CONTEXT
CONTEXT
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
END
 
hi ambient,

You can suppress Bank 'warning messages' reporting by inserting

errorlevel -302

near the top of your program say, just below the 'include'.

If you look at the assembler 'error' messages in the asm help files, you will see 'errors' have a unique numbers.
 
Ambient, I can't find the __CONFIG directive in your program. It's used to embed the configuration word within the asm file.
 
Ambient said:
with a 1M ohm pot and A/D (only lower 8 bits) determining the number of times Timer0 has to overflow before going to the next LED in the sequence.
I havent had time to go into the code, but aren't you going to want to use the 8 upper bits, instead of the 8 lower? If you use the 8 lower on a 10 bit ADC, then the speed will be at max at 1/4, 1/2, 3/4, and full turns, half speed at 1/8, 3/8, 5/8 and 7/8 turns, etc. Using the upper 8 instead would give you a single range, with max at full turn only.
 
I did put in the errorlevel -302 level already, I just didn't copy the whole program on the last post.

eric and eng1:
I did not use the __CONFIG options because I thought that was just for using the WDT off, A?D options, etc. I just made those configurations manually, since I want to see exactly what is going on. I am not sure what you mean by "configuration word", is that an option that I missed?

Toodles:
I justified the A/D registers to the right. The lower 8 bits would be bits 0-7 out of 0-9. As long as this is the case It will work fine. A max value for the count of 256 is fine, as I want it faster than that anyways. A value of 256 will give me 1/4 second per LED. Am I wrong with this approach? It seems like it will work fine to me, but I am a noob as far as PIC's go.
 
Last edited:
I know the value will jump up and down as I turn the pot, but that is alright. It will only need to be adjusted once, and I can use a 3M ohm resister in series with the pot to stop it from cycling like you said. That would also allow me to tune it finer.
 
A capacitor/resistor in a simple low pass aragement will filter out the wiper noise.
 
Ambient said:
I did not use the __CONFIG options because I thought that was just for using the WDT off, A?D options, etc. I just made those configurations manually, since I want to see exactly what is going on. I am not sure what you mean by "configuration word", is that an option that I missed?
The configuration word is a 14-bit register that allows you to select the oscillator type and other features such as WDT (as you said), BODEN, PWRT, code protection, LVP.
You can set the configuration bits manually, but it's good practice to use the __CONFIG directive, that enables the configuration word to be present at assembly time rather than at programming time.
 
eng1 said:
The configuration word is a 14-bit register that allows you to select the oscillator type and other features such as WDT (as you said), BODEN, PWRT, code protection, LVP.
You can set the configuration bits manually, but it's good practice to use the __CONFIG directive, that enables the configuration word to be present at assembly time rather than at programming time.

hi,
This is the page #84 of the 12F683 datasheet that eng1 is referring to.

Example for the 16F877.[yours will be different, but you get the idea]
Placed near the top of the program, close to include.

__CONFIG _CP_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF
 
Last edited:
Well hi ambient...

Congrats on writing first program in pic...

Actually.. i've also started working on PIC and members are taking care of my doubts.. Specially Moderator... as he wants me to learn the new tech for betterment of mine...


I hope if any doubt comes then also we can assist each other...

Regards,

Simran..:)
 
The best place to get the configuration string is in the template files. They're located in C:\Program Files\Microchip\MPASM Suite\Template\Code. The one for the 12F683 is called 12F683temp.asm and contains the following line,

Code:
	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

As I said earlier, the template files are a really good starting point for any project. They even contain the errorlevel -302 as standard!

Mike.
 
Thanks guys. I did take care of the CONFIG register in my code manually, but I will change that over to the __CONFIG commands since it is what you all recommend. I just did not like the idea of not seeing what every bit was in the program.

I did use a filter cap in my design, as I am pretty familiar with hardware. Here is my final schematic:

**broken link removed**
 
Damn, I over-engineered it again. I had that thought in the back of my head but I just kept designing it like that. I forgot I do not need to get a 0-12V swing on the base.

Thanks, that made the pcb less crowded.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top