Monday 7 March 2011

Timer Module stuff...

Another weekend away, and I've not managed to get very far onwards. I've read a number of data sheet entries and sample programs in my time away.  Little things like finding out that numbers starting with a full stop (e.g. ".123") are decimal values.  Binary values can be displayed as b'11110000'.

Also there seem to be a number of commands which exist within the MASM compiler to make coding easier.  For example it is possible to use the command "variable xyz" to make a variable instead of having to assign bytes to variables in the data section...

I did even try a bit of code in the DisplaySegments procedure:

 variable TEST_VAR
 andlw 0x0F
 movff WREG, TEST_VAR
 goto $ + (4 * TEST_VAR)


Unfortunately this didn't work, I still wonder if it is possible, since "goto $ + 8" does work, it may just be static references which work...

Monday 28 February 2011

LED Segment Counter

After a little playing with the program, I've now managed to get the program to count up from 0 to F, then back to 0, while toggling the processing LED every time the LED display is changed.  While this may be a simple program, it did teach me a few things about how to jump around code, (in order to display the value based on an entry in the working register there had to be the value multiplied by 4, then added to the Program Counter).

There's not much I can really say, other than posting the code, which doesn't quite feel like the place here to post, however I may as well post it, although the formatting may be a bit out where tabs are just transferred as spaces. 

So anyway, the Macro Include file, (I put Macro's into a different include file):

;***********************************************************************
; Filename:      LED_Segment.inc
; Date:          28th February 2011
; Author:        M.J.Andrews
; Purpose:       Program to contain macro's for the LED Segment program.
;***********************************************************************

;***********************************************************************
;****                        M A C R O ' S                         ****
;***********************************************************************

; ----------------------------------------------------------------------
; Macro   : TOGGLE_STATUS_LED
; Purpose : Macro to toggle the processing LED.  This is kept flashing
;           while we run the program as it shows that the processor is
;           working correctly and make it obvious if the code gets stuck.
; ----------------------------------------------------------------------
TOGGLE_STATUS_LED MACRO
 btg  LATA, RA0    ; Toggle the LED status
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_LATC
; Purpose : Macro to set the value of the LATC byte which is most of the
;           7-segment display entries.  We also toggle the status LED so
;           that we can see the LED flash to show the processor running.
; ----------------------------------------------------------------------
SET_LATC MACRO LATCValue
 TOGGLE_STATUS_LED
 MOVLW  LATCValue
 MOVWF  LATC
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_0
; Purpose : Set the LED 7-Segment display to "0"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_0 MACRO
 SET_LATC 0x80
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_1
; Purpose : Set the LED 7-Segment display to "1"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_1 MACRO
 SET_LATC 0xFB
 bcf  LATB, 0
 bsf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_2
; Purpose : Set the LED 7-Segment display to "2"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_2 MACRO
 SET_LATC 0x44
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_3
; Purpose : Set the LED 7-Segment display to "3"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_3 MACRO
 SET_LATC 0x41
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_4
; Purpose : Set the LED 7-Segment display to "4"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_4 MACRO
 SET_LATC 0x03
 bcf  LATB, 0
 bsf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_5
; Purpose : Set the LED 7-Segment display to "5"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_5 MACRO
 SET_LATC 0x01
 bsf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_6
; Purpose : Set the LED 7-Segment display to "6"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_6 MACRO
 SET_LATC 0x00
 bsf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_7
; Purpose : Set the LED 7-Segment display to "7"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_7 MACRO
 SET_LATC 0xFB
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_8
; Purpose : Set the LED 7-Segment display to "8"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_8 MACRO
 SET_LATC 0x00
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_9
; Purpose : Set the LED 7-Segment display to "9"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_9 MACRO
 SET_LATC 0x01
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_A
; Purpose : Set the LED 7-Segment display to "A"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_A MACRO
 SET_LATC 0x02
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_B
; Purpose : Set the LED 7-Segment display to "b"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_B MACRO
 SET_LATC 0x00
 bsf  LATB, 0
 bsf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_C
; Purpose : Set the LED 7-Segment display to "C"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_C MACRO
 SET_LATC 0x8C
 bsf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_D
; Purpose : Set the LED 7-Segment display to "d"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_D MACRO
 SET_LATC 0x40
 bcf  LATB, 0
 bsf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_E
; Purpose : Set the LED 7-Segment display to "E"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_E MACRO
 SET_LATC 0x04
 bsf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_F
; Purpose : Set the LED 7-Segment display to "F"
; ----------------------------------------------------------------------
SET_SEGMENT_TO_F MACRO
 SET_LATC 0x06
 bsf  LATB, 0
 bcf  LATB, 1
 ENDM

; ----------------------------------------------------------------------
; Macro   : SET_SEGMENT_TO_CLEAR
; Purpose : Set the LED 7-Segment display to blank with no LED's lit
; ----------------------------------------------------------------------
SET_SEGMENT_TO_CLEAR MACRO
 SET_LATC 0xFF
 bsf  LATB, 0
 bsf  LATB, 1
 ENDM
And the main application file:

;******************************************************************************
; Filename:      LED Segment.asm                                              *
; Date:          28th February 2011                                           *
; Author:        M.J.Andrews                                                  *
;******************************************************************************

LIST P=18F2455, F=INHX32 ; Directive to define processor
#include <P18F2455.INC>  ; Processor specific variable definitions
#include <LED_Segment.INC> ; Macro's for use with this program

;******************************************************************************
; Configuration bits

CONFIG FOSC = INTOSC_HS ;HS - HS OSCILLATOR
;******************************************************************************
; Variable definitions

  UDATA
WREG_TEMP   RES 1  ; Variable in RAM for context saving
STATUS_TEMP   RES 1  ; Variable in RAM for context saving
BSR_TEMP   RES 1  ; Variable in RAM for context saving

  UDATA_ACS
CNT_INNER   RES 1  ; Delay procedure, Inner Loop Count
CNT_OUTER   RES 1  ; Delay procedure, Outer Loop Count
LED_SEGMENT_DISP RES 1  ; LED Segment counter variable

;******************************************************************************
; EEPROM data

DATA_EEPROM CODE 0xf00000
  DE "Test Data",0,1,2,3,4,5
;******************************************************************************
; Reset vector's

RESET_VECTOR CODE 0x0000
  goto Main ; Go to start of main code
HI_INT_VECTOR CODE 0x0008
  bra HighInt  ; Go to high priority interrupt routine
LOW_INT_VECTOR CODE 0x0018
  bra LowInt  ; Go to low priority interrupt routine

;******************************************************************************
;****                  Start of the Program Code Section                   ****
;******************************************************************************

  CODE
;******************************************************************************
; High priority interrupt routine
;******************************************************************************
HighInt:
  retfie FAST

;******************************************************************************
; Low priority interrupt routine
;******************************************************************************
LowInt:
  movff STATUS,STATUS_TEMP ;save STATUS register
  movff WREG,WREG_TEMP  ;save working register
  movff BSR,BSR_TEMP  ;save BSR register

; *** low priority interrupt code goes here ***
  movff BSR_TEMP,BSR  ;restore BSR register
  movff WREG_TEMP,WREG  ;restore working register
  movff STATUS_TEMP,STATUS ;restore STATUS register
  retfie

;******************************************************************************
;****                           M A I N   C O D E                          ****
;******************************************************************************

Main:
Initialize
 bcf  TRISA, TRISA0   ; RA0 as an output for the "working" led
 bcf     TRISB, TRISB0   ; RB0 as an output for the 7-segment LED
 bcf     TRISB, TRISB1   ; RB1 as an output for the 7-segment LED
 clrf WREG     ; Clear the Working Register
 movwf TRISC     ; W-REG to PORTC to set as all outputs

 movlw 0x00     ; Start with 0 in the Working Register
 movwf LED_SEGMENT_DISP  ; Move the 0 to the Segment counter

Start_Loop
 movff LED_SEGMENT_DISP, WREG ; Copy the value of the counter to W-REG
 call DisplaySegments   ; Call proc to display LED value in W-REG
 call Delay     ; Call the delay procedure so we see value
 incf LED_SEGMENT_DISP  ; Increment the LED counter
 goto Start_Loop    ; Go back to the start of the loop

;******************************************************************************
;****                          P R O C E D U R E S                         ****
;******************************************************************************

; ----------------------------------------------------------------------
; Function: DisplaySegments
; Purpose : Procedure which can be called to display the low 4-bit value
;           from the W-REG as a numeric value on the LED 7-Segment display.
; ----------------------------------------------------------------------

DisplaySegments
 andlw 0x0F     ; Ensure the value in W-REG is 0->F
 mullw 0x04     ; Multiply W-REG to see how far to jump
 movff PRODL, WREG    ; Move the result back to the W-REG

 addwf PCL      ; Add the value to the Program counter
         ; This will skip forward to the goto
         ; command below to display the LED's
 goto  DISP_0
 goto  DISP_1
 goto  DISP_2
 goto  DISP_3
 goto  DISP_4
 goto  DISP_5
 goto  DISP_6
 goto  DISP_7
 goto  DISP_8
 goto  DISP_9
 goto  DISP_A
 goto  DISP_B
 goto  DISP_C
 goto  DISP_D
 goto  DISP_E
 goto  DISP_F

DISP_0 SET_SEGMENT_TO_0   ; Use the Macro to set the LED to '0'
  return
DISP_1 SET_SEGMENT_TO_1   ; Use the Macro to set the LED to '1'
  return
DISP_2 SET_SEGMENT_TO_2   ; Use the Macro to set the LED to '2'
  return
DISP_3 SET_SEGMENT_TO_3   ; Use the Macro to set the LED to '3'
  return
DISP_4 SET_SEGMENT_TO_4   ; Use the Macro to set the LED to '4'
  return
DISP_5 SET_SEGMENT_TO_5   ; Use the Macro to set the LED to '5'
  return
DISP_6 SET_SEGMENT_TO_6   ; Use the Macro to set the LED to '6'
  return
DISP_7 SET_SEGMENT_TO_7   ; Use the Macro to set the LED to '7'
  return
DISP_8 SET_SEGMENT_TO_8   ; Use the Macro to set the LED to '8'
  return
DISP_9 SET_SEGMENT_TO_9   ; Use the Macro to set the LED to '9'
  return
DISP_A SET_SEGMENT_TO_A   ; Use the Macro to set the LED to 'A'
  return
DISP_B SET_SEGMENT_TO_B   ; Use the Macro to set the LED to 'b'
  return
DISP_C SET_SEGMENT_TO_C   ; Use the Macro to set the LED to 'C'
  return
DISP_D SET_SEGMENT_TO_D   ; Use the Macro to set the LED to 'd'
  return
DISP_E SET_SEGMENT_TO_E   ; Use the Macro to set the LED to 'E'
  return
DISP_F SET_SEGMENT_TO_F   ; Use the Macro to set the LED to 'F'
  return

; ----------------------------------------------------------------------
; Function: Delay
; Purpose : Procedure to wait roughly 128*255 program cycles before
;           continuing, so that we can see the changes of the LED's
; ----------------------------------------------------------------------

Delay
 movlw 0x80            ; Initialize outer loop counter (0x40 - 128)
 movwf CNT_OUTER,A     ; Set outer loop variable to the counter
DelayOuter
 movlw 0xFF            ; Initialize inner loop counter (0xFF - 255)
 movwf CNT_INNER,A     ; Set inner loop variable to the counter
DelayInner
 decfsz CNT_INNER,F,A   ; Decrease Inner counter, skip next on 0
 goto DelayInner      ; Go to the next Inner count, (NOP on 0 CNT_INNER)
DelayInner_End
 decfsz CNT_OUTER,F,A   ; Decrease Outer counter, skip next on 0
 goto DelayOuter      ; Go to the next Outer count, (NOP on 0 CNT_OUTER)
DelayOuter_End
 return                  ; Return back to the place which called this proc

;******************************************************************************
;****                      E N D   O F   P R O G R A M                     ****
;******************************************************************************
  END

And the current circuit diagram as updated in KiCAD for the current version.

Checking through the DMX connector's

I arrived back from my weekend away to find that the cables and connector's I'd ordered had arrived in the post from Canford.  Before I describe the bits, I should say I found the location to get stuff from when I stumbled accross the a USB to DMX website.  In this site, the connector they use is an XLR socket "NC5FDM3H" from Canford code 40-583, and I thought I may as well use this part as they come from a working system.

Unfortunately since I failed on two counts with my order, I seem rather inept at ordering what I want!  Firstly I got three 3-pin connector's, 2 female, one male.  And secondly all of the connectors I got were vertical mounting, not horizontal which is what I was expecting!  Of course if I'd have been thinking enough I'd have realised this before!  So lets look at the part number used, "NC5FDM3H"...

First it looks like the "NC5" is the important bit for a 5-pin connector, (not the M3 on the letters near the end of the reference, as I thought since the image of the M3-H on the website had 5 pins).  Secondly, despite the website saying Horizontally mounted pins, I for some reason went and got vertically mounting ones!

While this doesn't matter in the grand scheme of things since I'll just solder some wires to the connectors, and the lights I plan on getting all require 3-pin connector's anyway, it is still a little annoying!

It turns out the M3 version of the connector has M3 threaded holes in the connecting plate so that it can be behind the plastic outside with a bolt through, while the other one has counter-sunk holes.  Of these, I definitely prefer the M3 version because it means that only the socket and screws will be visible.

Anyway here's the picture of the bits I got:


I had anopther N00B moment while looking at the individual connector's trying to figure out how they can be 'locked' into place.  Eventually I realised that the entrance to the hole you can use a tiny screwdriver to turn the locking mechanism is actually at the front of the socket, not the back!  Also it appears as though there is a fourth pin which is there purely so the locking mechanism doesn't get lost when unlocked, the pin appears removable once the component is all installed and locked properly.




Top Left: Female 3-Pin socket
Top Right: View of the pins for the socket
Bottom Left: You can just about see the screwdriver shaped slot in the 4th hole
Bottom Right: Opening the socket when unlocked

Friday 25 February 2011

DMX Cables & LED Segment

Last night I decided to get round to buying two cables, a 3-pin and a 5-pin female PCB socket connector, along with one 3-pin male connector.  I could have got the cables as a length of wire, and a few end pieces but I was feeling a bit lazy.  Two wires should be plenty for testing the DMX lights I'm going to buy in a bit, (the local theatre is buying some cheap LED parcans for the next show so I've said I'll buy two back after the show so they can reduce the budget and so I can get two lights to play with).. The LED pars have 3-pin DMX connectors, hence the 3-pin stuff.  The 5-pin is because I believe that is the proper DMX connector.  2 wires to plug DMX from the circuit to one light, then the second for the wire between the two lights.

The company phoned this morning saying they didn't have 2meter cables in black, so I changed it to a red and a blue ire instead.  I'd have preferred black, but when it comes to it they are only really meant for testing.

Anyway I'm off for an extended weekend, hence the day off work.  I've been thinking about my problem setting the PortB bits on the circuit and programming in the LED segment.  While I may be in a bit of a rush, I thought Meh, and sat down for an hour...

A little searching on the Microchip site shows that I should be setting the "LATB" register when I'm using the bsf and bcf methods to stop any inputs interferring or something...  Changing that and it solved all my previous problems trying to set those LED segments, (wierd how something so simple wastes so much time).

Anyway I've now coded a few macro's based on how I've wired the chip at the moment so I can use the Macro's to set the LED segment to match a certain entry.  It's a shame I couldn't use one full 8-bit port really as that would have meant just two processor instructions to set the segment.  As it is, I need four, (and thinking about it maybe I should be using LATC instead of PORTC when setting it to a byte, however for now the macro's for the segment settings is shown below:

SET_PORTC MACRO PortCValue
 MOVLW  PortCValue
 MOVWF  PORTC
 ENDM


SET_SEGMENT_TO_0 MACRO
 SET_PORTC 0x80
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM


SET_SEGMENT_TO_1 MACRO
 SET_PORTC 0xFB
 bcf  LATB, 0
 bsf  LATB, 1
 ENDM


SET_SEGMENT_TO_2 MACRO
 SET_PORTC 0x44
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM


SET_SEGMENT_TO_3 MACRO
 SET_PORTC 0x41
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM


SET_SEGMENT_TO_4 MACRO
 SET_PORTC 0x03
 bcf  LATB, 0
 bsf  LATB, 1
 ENDM


SET_SEGMENT_TO_5 MACRO
 SET_PORTC 0x01
 bsf  LATB, 0
 bcf  LATB, 1
 ENDM


SET_SEGMENT_TO_6 MACRO
 SET_PORTC 0x00
 bsf  LATB, 0
 bcf  LATB, 1
 ENDM


SET_SEGMENT_TO_7 MACRO
 SET_PORTC 0xFB
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM


SET_SEGMENT_TO_8 MACRO
 SET_PORTC 0x00
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM


SET_SEGMENT_TO_9 MACRO
 SET_PORTC 0x01
 bcf  LATB, 0
 bcf  LATB, 1
 ENDM


SET_SEGMENT_TO_CLEAR MACRO
 SET_PORTC 0xFF
 bsf  LATB, 0
 bsf  LATB, 1
 ENDM
I then wrote a little counter program to cycle through each of the numbers and blank entries listed above:

Start_Num_Loop
 SET_SEGMENT_TO_CLEAR
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_0
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_1
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_2
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_3
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_4
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_5
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_6
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_7
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_8
 call Delay           ; Call the Delay procedure to wait a bit
 SET_SEGMENT_TO_9
 call Delay           ; Call the Delay procedure to wait a bit


Anyway that will do for now, no time to make it show A-F, and to use a slider as an input... Next time!

Wednesday 23 February 2011

Crystal Oscillator and LED 8-Segment display

Another evening, and after originally thinking about ordering some Sockets and Cables for when I eventually get onto outputting DMX, instead I started rooting through my electronics toolbox and found another Crystal, and another of the sliding potentiometers, (100K resistance it turns out)...

So I took the crystal, added the same capacitors I had previously, and added them to the circuit board.  I had to change the oscillator setting in the program to "HS", re-make, program and run the old circuit and yup, the LED flashes a lot lot faster...


The image above shows the crystal and capacitors added to the circuit.  Since the HS Oscillator setting is a little too fast for what I'm doing at the moment I changed it back to "INTOSC_HS" which is meant to be the internal oscillator for program and HS for USB.  Either way it's back to the internal oscillator for now.

Looking at the slider I had, the connection pins fit in nicely to the bread board, but there are four exra pins which I think are meant to be used to fix the slider on to a PCB board... Since I was thinking of programming in the slider again to show how to read inputs I needed to bend those pins back as shownb below:


However thinking about connecting the slider up, I don't actually have any method of telling where the slider is, except for perhaps changing the flash rate of the led... So since I have an 8-segment LED display in the box of LED's, perhaps I should wire that up and use that to display some numbers or letters based on the slider location.

First I needed to find out how to how to wire the LED segment.  A little investigation shows a common +ve connected to pin 3 or 8, and I found all my 1K resistors, so some quick testing to check it out...


So LED's will be on when a pin is set to output and has a value of 0, a value of 1 being off.  The question is where to connect the pions to on the chip... At first I thought to use PORTC as the pins are all down the bottom of the chip, and there are only 7 pins available, (I'm not going to use the decimal point so 7 not 8).

After connecting the segments up to the chip I found that I couldn't figure out how to set two pins, (apparently they could be configured to be outputs if the USB is turned off in one register, but I still failed to get them to output)... In the end I connected two bits from Port B in instead, and then had more fun failing to get those to work as expected... I think I must be using the wrong assembly command to set bits directly as setting the whole PORTB value worked, but not using bcf and bsf...

I have a feeling that I realised the 'obvious' bit set and clear commands didn't do what I expected them to do when I was last trying to learn assembly.  Something to look at later, I've had enough for this evening.  So here's the board layout I had at the end of my fiddling, while the connections are not ideal, for now they're all fine.


At least it looks fairly neat and tidy... Yes I could have just thrown in any old wires, but I like wires all being the right length.. Maybe a bit OCDish, but at least you can follow the wires easily.  If it was wires all-over the place then it can very easily become very confusing!

Oh one thing I almost forgot to say... Trying to connect the board direct to power seems to fail now for some reason, so I must have messed up something somewhere, but it all still works when the programmer is connected with the RESET cleared... so probably something linked to that and maybe the Oscillator... Something to look at another day!

Tuesday 22 February 2011

Flashing LED

Well I'm going out to one of the weekly theatre set build evenings in an hour, so just enough time to update the program so that we can flash the LED...  A little lookign through the assembly commands, and looking back at some of my old applications which were probably based on the PICkit examples, I did the following:

1) Added two new variables so we can have a loop which loops a certain number of times before we next change the LED.  Since the Processor will be running many many commands a second, we need to wait a number of oscillator ticks before changing the LED state.  So adding two variables after the UDATA_ACS line:

  UDATA_ACS
CNT_INNER RES 1 ; Inner Loop Count
CNT_OUTER RES 1 ; Outer Loop Count


2) Added code to the Mains ection of the program which initializes the LED, (we have that code already), then to turn the LED on, followed by a call to a Delay procedure to wait a bit.  This is followed by turning the LED off and another delay procedure call...

Main:
Initialize
 clrf WREG            ; Clear the W-Register
 movwf TRISA          ; W-REG to PORTA to set as all outputs

Turn_LED_ON
 movlw 0xFF           ; Set all bits in the WREG
 movwf PORTA          ; Update PORTA to turn the LED on
 call Delay           ; Call the Delay procedure to wait a bit

Turn_LED_OFF
 clrf WREG            ; Clear the WREG
 movwf PORTA          ; Update PORTA to turn the LED off
 call Delay           ; Call the Delay procedure to wait a bit

 goto Turn_LED_ON     ; Go back to the LED ON for an Infinite loop

3) Of course we then need to have the Delay procedure somewhere, so I'll place it after the command to go back to the turning the LED on label...

Delay
 movlw 0x40            ; Initialize outer loop counter (0x40 - 128)
 movwf CNT_OUTER,A     ; Set outer loop variable to the counter
DelayOuter
 movlw 0xFF            ; Initialize inner loop counter (0xFF - 255)
 movwf CNT_INNER,A     ; Set inner loop variable to the counter
DelayInner
 decfsz CNT_INNER,F,A  ; Decrease Inner counter, skip next on 0
 goto DelayInner       ; Go to the next Inner count, (NOP on 0 CNT_INNER)
DelayInner_End
 decfsz CNT_OUTER,F,A  ; Decrease Outer counter, skip next on 0
 goto DelayOuter       ; Go to the next Outer count, (NOP on 0 CNT_OUTER)
DelayOuter_End
 return                ; Return back to the place which called this proc


Compiling it, it succeeded!  So program the chip, then release from reset, and yay a flashing LED...

Monday 21 February 2011

Trying to make a simple program

So I have a circuit, a programmer... I've installed the PICkit software and MPLAB IDE from the Microchip site... Now its time to try and get a simple program to compile and run.

Since I have a different laptop from the time I last tried this, I'm starting from scratch.  Running the MPLAB IDE software, creating a project seems to work quite well although I have to admit I have a blank project and I don't know where to go...

I had some vague memory about there being a number of sample programs stored in the Microchip Program files folder... A little investigation found a base assembly file and include file for the 18F2455 chip, so copying those into my project folder and adding to the project all seemed ok, except I get some language plugin exception message and it fails to build still with no further message of any use.

I eventually found that I must have set the Project->"Select Language Toolkit" to a junk value at one point as the MPASMWIN.exe link which existed tried to point to a file in my project.  Putting it back to the file in the "C:\Program Files (x86)\Microchip\MPASM Suite\" folder fixed that problem and created a load of other errors...

Ahhh, errors fixed by finding a project option to generate code in "Relocatable Mode" instead of "Absolute mode".  I had received a number of dialog boxes asking which option I wanted, and not ahving a clue what each one was I clicked absolute... I guess I needed to choose relocatable!  The option was changable in the "Project -> Build Options -> Project" menu, then under the MPASM tab selecting the relocatable option.

Trying to program the chip using the debugger produces an error about being unable to find a Vdd of 5V... I wonder if that is because the board is currently powered by the USB...  Looking through the "Typical ICSP Application Circuit" information in the PICkit documentation explained the circuitry I have connected to the MCLR pin in my old circuit... However adding the resistors and capacitors didn't seem to make any difference to this message, although since the user guide mentions it for ICSP circuitry I think it's best to keep it in!  The 470 & 10K Ohm resistors, and the 100pF capacitor are seen in Figure 3-1 in the PICkit user guide.

While I was changing the bread board circuit, I've also added another LED and resistor to pin 2.  Pin 2 is marked as being "RA0", so it should be bit 0 of Port A... I'll be needing to use that later when I get the LED to flash on and off.

So here's the changes to the circuitry:


And here's a modified image, attempting to show the hidden connections which are being used within the breadboard.  Hopefully this can help understand how the holes are all electronically linked.


The blue line shows the output from Pin 2 carried accross to the LED on the left.  This passes under the (blue) capacitor which connects to the first and third row.

So back to the program... I have a base program, but that is expecting a crystal oscillator which I don't think I have spare, (although I thought I bought two of them a few years ago, maybe I'll find it soon enough, or borrow the one from my other circuit).  Looking through the base sample program, the setting line which sets the Oscilliator is currently "CONFIG FOSC = XT_XT".

Not knowing what options are available for this configuration setting I checked the include file added earlier.  That has the following lines talking about internal Oscilliator's:

;     FOSC = INTOSCIO_EC   Internal oscillator, port function on RA6, EC used by USB (INTIO)
;     FOSC = INTOSC_EC     Internal oscillator, CLKO function on RA6, EC used by USB (INTCKO)
;     FOSC = INTOSC_XT     Internal oscillator, XT used by USB (INTXT)
;     FOSC = INTOSC_HS     Internal oscillator, HS oscillator used by USB (INTHS)

I have no idea which one (if any!) I can use, so I'll start by setting the config value to "INTOSCIO_EC".  Of course I've not actually got a program which does anything yet...  So lets at first try to turn on the LED pin to determine if anything is going to happen.

After a bit of playing, I managed to get the LED to light up using the following code in the section which starts "Main:":

Main:
    clrf    WREG
    movwf   TRISA  ; Configure PORTA as all outputs
    movlw   0xFF
    movwf   PORTA  ; Set Port A to all values as true (on)

    goto $

This code first clears the W-register, then uses that empty value to clear the value of TRISA... Now based on the data sheet, the TRISA register controls what the Port A pins are to be used as.  Setting each bit to 1 results in the pin being an analog input, (the default), and 0 as an output.  Obviously we need the pin to be an output as we want to light an LED...

Next we set the W-Register to have a value of 0xFF which is 8 bits set to 1/ON.  Technically we only need the one bit for RA0 to be set, but since it's late I cba to find out which way round it should be!  Moving the W-REG value to PORTA is the final bit of code, (well goto $ apparently sets the processor into an infinite loop doing nothing).

After a few fiddles, I found out I wanted to do the "Programmer->Program" option, followed by "Programmer->Release from Reset" to get the program running.  Lo and behold the LED does actually light up, and despite being clear, it is actually a red LED.

Woo there's a program and it works!

Sunday 20 February 2011

Creating the base Microchip circuit

So, since I have two breadboards I decided to start from scratch using one of the PIC18F2455 chips.  Of course I started off with a breadboard which had a few wires in it which needed to be checked and changed where required.  I like to have red wires being the main +ve voltage source and black for ground, but some Vsource wires were black (tut tut tut)...

First of all I plugged in the Microchip across one of the gaps, (the breadboard links all the main section holes across horizontally between each gap).  In order to do this I had to push the pins in a bit to make them 90 degree's from the chip, (by default they splay out a bit).  Do this by placiong the pins against a flat edge (like on a table) and push them in together, don't do it by pushing each pin in individually as that will tend to result in pins not all being pushed in the same amount.  Once they were flat I put the chip into the breadboard:


The next thing to do is to wire the chip up so that I can plug in the PICkit 2 device... While I could put wires from the PICkit device into any slot on the board, I like having them all next to each other so I can plug the device in easily.

The PICkit device has 6 connections, of which one is not used.  The remaining five pins, and the corresponding pin numbers on the main microchip are as follows:
  1. Vpp/MCLR - Pin 1
  2. VDD Target - Pin 20
  3. VSS (Ground) - Pin's 8 & 19
  4. ICSPDAT/PGD - Pin 28
  5. ICSPCLK/PGC - Pin 27
This is found by finding the appropriate pins on the microchip according to the PDF datasheet, a document which is available HERE, (look in the downloads section for the Data Sheet).  This document does feel a little overwhelming when you look at it as it is 435 pages long, however the information inside it is pretty essential to figure out what is needed.  The pin outs are shown on the fourth page, (marked as page 2 in the document).


The picture above shows how I placed the connections.  The Vss and Vdd lines have been passed up to the top bar as well for any main Vsource/ground connections.

In order to have a method of telling if the miocroprocessor is powered, I then added a simple LED and resistor between the Vdd and Vss rails on the left hand side of the board.  The resistor I used was a 1K resistor, (which oddly I seem to be running short on as they seem to be used a lot).  This results in an LED lighting up when the circuit has power, (either through an external power source, or through power supplied by the PICkit USB interface.


The image above shows the LED being on with external power supplied to the base breadboard.  Of course the microprocessor isn't doing anything here, although it is powered.  In order to check that the connection to the PICkit works correctly we need to disconnect that external power and connect the PICkit device...



Then running the PICkit software, and clicking the Verify button checks the connection and passes back a little information about the processor and its current memory.  Since the device is correctly identified and Verified, I think I can assume that the PICKit connection is working correctly:


The next thing would be to set up an Oscillator so that the chip has its own clock source.  Eventually we should be using an external crystal which should help to provide the signal, however based on the Data Sheet, there should be an internal clock source, however using this will mean that USB won't work until we have an external source... But since that's a while away, I think we can forget about that for now.  Provided of course I can get the internal oscillator to work...

However that is going to have to wait for later as I'm hungry now and want a break!  So next up should be a simple application to flash an LED... Which means I guess we'll need another LED adding to that basic circuit...

Circuit design program - KICAD

As described in the last post, I started by wanting to display a decent circuit diagram for the circuit I had working back in July 2009, before I start to figure out what to do and where to go with the system.  This way I will at least have a record of all that work I did two years ago before I take it apart to try and figure out what everything means!


So I found what appears to be a promising Open Source GPL software package called "KICAD".  Now I've not used many CAD programs before, and I think the software used at University was something like "Rational Rose", however since I only used that very briefly I don't really have much of a working knowledge about how Circuit designers work.  Like most open source software though I have to admit that I am expecting a steep learning curve, (since the app programmers tend to be busy writing code to do what they want, and they tend not to be that great at User interface design, at least that's how I tend to program when writing open source software anyway and how most other GPL software I've seen tends to be laid out).

The KICAD download is actually a decent size, (~100 MB), and the screen shots on the base web page all look rather impressive.  After downloading the Windows version for my laptop, the installation was pretty easy, (next...next...next), the final screen did provide a link to a 3D app required to show electronic components, but since I'm not interested in that right now I thought I'd skip that for now, I can always do that later.

Running the main program creates a base project in the application program files directory... So the first thing I did was a file-new to create a project in a directory I much prefer, (under  My Documents).  Shame that the app doesn't default to the documents or application work directories, but not exactly a problem!

Since I'm wanting to create a Circuit Schematic I guess I need to click the EESchema Editor button...  And since I want to start with a PIC18F2455, I guess we should start there... So where's that Add component button... ahh yes a tiny button on the right of the screen...

Searching the component list for "PIC" there are three PIC components listed, none of which are the one I need.  So then how do I create a new component for the processor I want...

The Component Library Editor looks like it may be what I want...  Some help file searching, (a nice long descriptive PDF file, but unfortunately no nice index), shows that if you want a line over the top of a pin the pin must start with "~"...  No initial idea how to draw the Pin however... Ahh a "Place" menu option allowing the placement of a Pin...  So Pin 1 on the PIC 18F2455 is described as "MCLR/Vpp/RE3" with the MCLR having a line over the top, but a ~ puts a line over the whole pin description...  Ahh cool a second ~ ends the line over the top of the pin, that's good!

I think I'm getting the hang of this editing components stuff... Added 28 pins, and set what appears to be the correct text labels as listed by the microprocessor PDF specification file...  I can't seem to find a method of sub-scripting text which would be useful.  It'd also be nice if pressing enter on the pin entry window would close the window, (Ok button being the form default button).



So exiting the editor and going back to the Schema editor I added a component, I entered PID and pressed enter, (previously I'd clicked the "Search by Keyword" function)...  Annoyingly a new list of PIC processors opened up...  There were only two 18F diagrams, however annoyingly they included the PIC18F2550 which is the 32K version of the one I did above.  Also while I had assumed the pin outs should all be displayed in pin order like on the chip, the sample actually includes the outputs on one side organised into 8-bit entries, which is a lot more useful for seeing what is happening.

So using the original library chip I'll start creating that circuit diagram...

After playing around a little bit, I have to admit it is a little more intuitive than I expected, however that isn't stopping me from having a load of learning curve issues... Like how do I add a resistor... Turns out I add a component and type in "R".  A capacitor is "C", the crystal appears to be "Crystal", although I'm not certail I have the right symbol really.  Adding a Ground connection then it is adding a power component "GND".

When selecting multiple items by drag-selecting a selection box over items, all items covered are selected.  Push CTRL at the same time and only the end points covered are selected, (allowing componenets to be moved while keeping connections to other wires).  SHIFT-Selecting makes a copy of what is covered.

One thing which bugs me quite a bit is that I keep rolling my mouse wheel trying to move up or down the page, however instead it zooms in, CTRL/SHIFT can be used with the wheel to scroll sideways/updown.

I'm actually not sure which crystal I bought two years ago... Looking at the specification sheet, and also based on the capacitor values I'm using, I think it must be an 8MHz Crystal resonator...

Looking at the connections I put into the MCLR pin, it reminds me that I don't have a set of any Diodes, (well other than led's)...  Not sure if I need them, or why I have the connections set around the MCLR pin, I guess it was needed to run the system from an external power source.

Anyway after a good few hours working on it, spending some time re-accustomizing myself with some things like how to tell what resistance a resistor is, and searching for and re-reading through various specifications and help files about the Chip, LCD screen, PICkit 2 and the KICAD application help file...  Here's what I think my last circuit looks like, (remember it may not be the best circuit I am still really a beginner here).



I guess I'm failing miserably to help anyone who doesn't know much about electronics... Ahh well with luck, my progress or lack of progress will perhaps be able to help someone one day who knows enough to want to know a few pitfalls I've made...  Never mind, maybe one day I can use all this as a base to a book, although I have a feeling that is a wild dream that will never happen.

Anyway in summary about KICAD... Well it looks good, it has a number of oddities which took a while to get used to, but for an open-source app I actually think it is pretty good.  I'm considering it good enough though that for the moment I'm not going to look for any other circuit schematic designer for a while anyway.

So where did I get to last time?

Since I've been woken up by some nice council people doing road works outside my house, I'll continue forward...  But first I really need to remember where I got to when I last tried to learn to program these microchips...

I used the PIC18F2455 chip as it was the cheapest of all the chips that I wanted to use, (I initally started using the 16F 40 pin chip I had, however I'm going to stick with the 18F2455 for my reproductions).  This chip has 28 pins, and a flash program memory of 24K, (12288 single word instructions according to the spec which should be plenty for any initial programs).

In my last set of programming I had included an LCD 16x2 display panel, a slider potentiometer and a few LED's to show that the processor was working.  I also attempted to connect the USB, however never actually managed to get the USB connection to work.

Lets start with a picture of the circuit.  The program I created just displays my name on the top line of the LCD, with a display showing the position of the slider, 0->255 as well as 0000 to FF80...


I guess one useful thing would be to try and create an electronics diagram to show the full circuit used above.  While it's probably not understandable at the moment, it would actually be useful to record what the circuit is currently meant to be!

Of course, I could try to draw the circuit on a piece of paper with that old technology called a pen, however ideally I want to try and find a nice free circuit diagram maker online.

Some initial Google searching pointed out a few sites which may be of use, but nothing that looks particularly free to use.  One site seems to say that OrCAD Capture is "Pretty much an industry standard for circuit schematics"... Unfortunately it also looks a tad expensive, not that I can actually find any information on how much it would cost.

One board post pointed out an open source GPL appication called KiCAD, despite a number of french words on the site leading me to wonder if I'm going to end up with a french language software, it does actually look like it might be what I want, so I'll give it a try...  And so I downloaded the "KiCad-2010-05-05-BZR2356-final-WinXP_full_with_components_doc_autoinstall.exe" file from the FTP site linked to KiCAD.

I'll have a play with this software, then continue writing...

Saturday 19 February 2011

Other Purchasing

Along with the choice of chip to program, I knew I'd also need a number of items to actually make the chip work.  This involved a number of trips to Maplin, and an order from Farnell to get a number of the required electronic components.  Quite often I went to Maplin, then realised a few days later that I was missing another item or two.  Some items I got were fairly useless, others have been rather essential so far.

Lets start with the obvious item required... First I needed a breadboard to save lots of Solder:



The picture is one of the two breadboards I got.  While I only needed the one, it is nice to be able to create two circuts.  The wires on the picture come from some of my initial programming attempts to program the 16F chip I received from the Microchip samples.

Bread board is good because certain lines of holes are all connected to each other.  You plug in the chip across one of the gaps, then use the holes next to the pins required, plugging in wires to those holes to make up the circuits required.



I already had a nice variable power supply, it can be set to output varying voltage levels through a number of connectors.  While my programmer, (I'll describe that later), can be used to power the circuit board, it is always nice to have a transformer which can be used to run the board directly.


A nice little toolkit, including some nice little pliars, and varying screwdrivers.  The Pliars are useful for holding annoyingly little cables, the screw drivers have been useful for changing variable resistors.  Overall the most useful and most used item here are the wire clippers on the left.



The picture above shows a few electronics sets I bought... A box of various LED's, (mini lights which can be used to show the state of various output pins from Microchip pins).  A pack of many resistors, hopefully all I will ever need, (and yes we will need quite a few!), and similarly a pack of many capacitors as well, (and once again we need some of them).  The picture also shows a number of wires, (the solid core wires as they pin into the breadboard well, not the mult-core wires which are better to bend and move as they are more flexible).  Finally there is also a wire stripper tool there which is great for stripping the edges off the various wires allowing them to be plugged into the breadboard ;-).

Other items got to help with the electronics includes a crystal, (to control the clock speed of the processor), A keypad (to test input via a keypad), a 16 character by 2 line LED display screen, various potential divider resistors and a slider potentiometer.



A voltage meter (above) was also bought to help see the various circuit variables.  I went a bit further than just the cheapest voltmeter, getting one with various extra functions including resistance, current and frequency.  Since the price wasn't massively more for the increased functionality, I think it was best to get the extra functions.



Finally I needed a PIC programmer.  A device to used to copy the program code written on a PC, compiled into bytes which the microprocessor can then understand and run.  I went for the PICkit 2 programmer, ordered from the Microchip site, it even came with a sample 44-pin test board containing various buttons, LED's and sample programs.

Overall the PICKit was probably one of my better buys.  The conjunction of the programmer and test board really helped creating and testing some basic programs.

The wires coming out of the PICkit programmer were put together using some wires I saw containing pre-set pins on the ned of each wire.  Since I plug them into and out from the breadboard quite a bit.  The tape just holds the wires at the right distance apart.  In reality I should find some pins I can plug into the breadboard just like the sample test board.

Initial Purchasing - Microchip Sampling

Well I have to admit, I am bored today...  We finished the last show last week, and this is now the first day in a while that I've had completely free.  I sat watching TV this morning, rather bored at the lack of anything worth watching and also bored of wasting my life doing nothing, and then started digging through my drawers to find all the old items I purchased, and so I'm now trying to remember back to all the items I wanted to say when I was last doing this project.

Lacking anywhere in particular to start, I'll try and talk a little about Microprocessors, they are afterall integral to the whole project!

So what is a Microprocessor?  Well I guess I could go to the Wikipedia page about them and copy out information, but instead I'll describe what I know about them...

The Microprocessor is going to be a Microchip which acts as the main CPU, (that's Central Processing Unit) for the device we want to create.  This is the main chip which will hold the computer program, control all of the electronics.

When I started with this, about the only thing I knew about various Microchips was the word "PIC".  During my time at university, a number of friends in the Engineering department kept praising this type of Microprocessor, along with talk about various 'programmers' and 'samples'.

In fact when I first decided to look into this project, the idea of people at uni receiving a number of free sample Microprocessors resulted in me getting a little ahead of myself.  Some scanning through google and various web sites led me to the Microchip Samples website.  Being a little ahead of myself, and eager to quickly get into programming something, I made the mistake of randomly selecting four Microchips for free samples.

In hind-sight I really should have thought better for my selection of microchips.  While I can't remember the exact reasoning behind each choice for the chips, I do remember it being a little random, and really full of confusion.  I looked through the list of chips having no clue what-so-ever which chips I wanted to play with.

Surprisingly quickly after ordering my four random chips, I found a nice small box drop through my post containing the four chips, each in their own small tube.  I don't have the box any more but the chips in their tubes are displayed below:

Sadly, once I got programming, (more of that later hopefully), I found that the only chip I found usable was the PIC16F874A chip.  That chip is actually the large 40-pin chip closest to the camera above, and it provided basic process stuff which I managed to get working, although I can't exactly remember why.

Similarly, I can't actually remember what the problem was with the other chips.  I think the 18 pin one may have had an issue with the programmer I got as I needed a certain programming interface, however I'm not sure.  The following were the other three chips I got just in case your interested (yeah right).

 * PIC16F648A - I/P - 18 pin
 * PIC16F873A - I/SP - 28 pin
 * PIC18F2580 - I/SP - 28 pin

Really I should have looked for a chip which included a USB interface as one of my samples.  Once I started investigating more, and thinking more about what I would need for the DMX interface I realised that I would want one Microchip which could handle the USB connection as well as running the DMX signal itself.

Well at the moment that is what I am thinking anyway... Considering I'm currently not certain that I can have one singal chip controlling the output signal as well as reading in the USB buffer signal as well as reading in any input devices and outputting anything to any output devices.  However that being said, only time will tell if one chip will be enough.

After some of my initial investigations, I found the PIC18F2455 chip.  This family of chips include the ability to link to a USB2.0 interface, and (I believe) includes special code within the chip to read in and respond to USB requests using a shared memory buffer.  As a result of this, I decided to buy a few of these chips in the hope that they will be able to do what I want.

Since I was a little worried about blowing any of the chips I bought, and I guess also because each chip is only £2-£3, I settled on buying two of each of the family of chips.  Of course once I'd decided that, I came across another unfamiliarity with technical terms...  What type of chip I should buy, considering there seemed to be a number of options, (PDIP, TQFP, SOIC and QFN)...

After a little investigation, PDIP appeared to be the standard chip I had come to expect.  TQFP was a tiny 44-pin version of the chip containing legs which could be soldered onto a circuit board, (it is tiny, like 1cm square).  SOIC is the 28 pin version of the chip for soldering to a circuit board.

Since I'm just attempting to start programming, I was going to be using breadboard to create circuits on, so the chips I needed were most definitely the PDIP versions of the chips which would actually fit into the breadboard, and require no soldering, (not to mention that the TQFP chips have such small legs that it is probably almost impossible to manually solder them to circuit boards).

I put in an order for two each of all the chips, (there are two 28 pin versions, and two 40 pin versions, for each of the types the difference between the chips is the Program memory size being 32K for one chip and 24K for the other chip).  After finding out that I was only a few quid short of the price required to not pay Postage and Packing, I also added on one 28 pin SOIC version, and one 44-pin TQFP just so I can see how the chips look, for effectively no extra cost, (as without them the P&P cost their price [ish]).

When the chips arrived, I was surprised to find them in one huge box which was much longer than required.  Inside, each chip type came in a long tube containing the two chips in each of them, but it was a nice christmas-like day opening the air-tight packet containing the 44-pin chip.


The picture above shows the box the 10 microchips came in, along with a standard pen so you can get an idea of the size of the box!  Opening the box, (see below), showed there were 4 clear see-through bags containing one tube with 2 chips in it per bag, (one per chip type ordered).  There was one silver bag (which may have been air tight I can't remember) which contained a tube with the 28-pin SOIC chip, and another (definitely air-tight) silver bag containing the 44-pin TQFP chip.


Overall it really felt like a waste of packing space, especially as the original samples came in a nice and small box of the size I was actually expecting!