PIC programming LCD countdown timer

Discussion in 'Embedded Systems and Microcontrollers' started by bluebrakes, Jan 27, 2010.

  1. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    I was wondering if someone could help me write the bare bones to my 16f628a LCD driven countdown timer.

    Essentially there are three buttons one to change the increment in minutes only (up to 60mins), a set digit button and finally a start/reset button. I figured the internal timer is good enough for this project, as timing precision isn't exactly critical.

    LED1 will flash with every button press and when the timer is up.

    LED2 and LED 3 will turn on when the timer is up.


    I built this project as the next step in my learning curve, but I'm still getting to grips with the pic programming. Any snippets of code would be greatly appreciated. :)
     
  2. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    ; ========== 16F628A LCD COUNTDOWN TIMER =================
    ; Description: ..........
    ;
    ; 16F628A driven LCD countdown timer for a period
    ; of up to 60 minutes.
    ;
    ; Switch One increments the digits of the timer.
    ; Switch Two sets the digits of the timer.
    ; Switch Three starts/resets the timer.
    ;
    ;
    ;==========================================================
    LIST p=16F628 ; TELLS THE PROGRAMMER WHAT CHIP WE'RE USING.
    include "P16F628.inc" ; INCLUDES DEFAULTS FOR THE CHIP.
    ERRORLEVEL 0, -302 ;suppress bank selection messages
    __config 0x3D18 ;sets the configuration settings (oscillator type etc.)
    ;__config _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_OFF

    cblock 0x20 ;start of general purpose registers
    count ;used in looping routines
    count1 ;used in delay routine
    counta ;used in delay routine
    countb ;used in delay routine
    tmp1 ;temporary storage
    tmp2
    templcd ;temp store for 4 bit mode
    templcd2
    endc
    ;=====================================
    ; LCD SETUP, DATA LINES, CONTROL LINES
    LCD_PORT Equ PORTA
    LCD_TRIS Equ TRISA
    LCD_RS Equ 0x04 ;LCD handshake lines
    LCD_RW Equ 0x06
    LCD_E Equ 0x07
    ; END OF LCD SETUP
    ;=====================================
    ;=============================
    ; Additional LEDs and Switches
    LEDPORT Equ PORTB ;set constant LEDPORT = 'PORTA'
    SWPORT Equ PORTB ;set constant SWPORT = 'PORTA'
    LEDTRIS Equ TRISB

    SW1 Equ 0x00 ; Identifies Switch One on Schematic diagram
    SW2 Equ 0x01 ; Identifies Switch Two on Schematic diagram
    SW3 Equ 0x02 ; Identifies Switch Three on Schematic diagram

    LED1 Equ 0x04 ; Identifies LED One on the Schematic diagram
    LED2 Equ 0x05 ; Identifies LED Two on the Schematic diagram
    LED3 Equ 0x06 ; Identifies LED Three on the Schematic diagram

    ; end of LEDs and switches
    ;=============================
    org 0x0000 ;org sets the origin, 0x0000 for the 16F628
    movlw 0x07
    movwf CMCON ;turn comparators off (make it like a 16F84)
    Initialise clrf count
    clrf PORTA
    ; clrf PORTB

    SetPorts bsf STATUS, RP0 ;select bank 1
    movlw b'00001111' ; 4 outputs (RB4-RB7), 4 inputs (RB0-RB3)
    movwf SWTRIS
    bcf STATUS, RP0 ;select bank 0
    clrf LEDPORT ;set all outputs low
    clrf SWPORT


    movwf LCD_TRIS
    bcf STATUS, RP0 ;select bank 0
    call Delay100 ;wait for LCD to settle

    call LCD_Init ;setup LCD

    clrf count ;set counter register to zero
    Message movf count, w ;put counter value in W
    call Text ;get a character from the text table
    xorlw 0x00 ;is it a zero?
    btfsc STATUS, Z
    goto NextMessage
    call LCD_Char
    call Delay255
    incf count, f
    goto Message
    NextMessage call LCD_Line2 ;move to 2nd row, first column
    clrf count ;set counter register to zero
    Message2 movf count, w ;put counter value in W
    call CrdText ;get a character from the credit text table
    xorlw 0x00 ;is it a zero?
    btfsc STATUS, Z
    goto EndMessage
    call LCD_Char
    incf count, f
    goto Message2
    EndMessage

    Stop goto Stop ;endless loop


    ;Subroutines and text tables
    ;LCD routines
    ;Initialise LCD
    LCD_Init movlw 0x20 ;Set 4 bit mode
    call LCD_Cmd
    movlw 0x28 ;Set display shift
    call LCD_Cmd
    movlw 0x06 ;Set display character mode
    call LCD_Cmd
    movlw 0x0d ;Set display on/off and cursor command
    call LCD_Cmd
    call LCD_Clr ;clear display
    retlw 0x00
    ; command set routine
    LCD_Cmd movwf templcd
    swapf templcd, w ;send upper nibble
    andlw 0x0f ;clear upper 4 bits of W
    movwf LCD_PORT
    bcf LCD_PORT, LCD_RS ;RS line to 0
    call Pulse_e ;Pulse the E line high
    movf templcd, w ;send lower nibble
    andlw 0x0f ;clear upper 4 bits of W
    movwf LCD_PORT
    bcf LCD_PORT, LCD_RS ;RS line to 0
    call Pulse_e ;Pulse the E line high
    call Delay5
    retlw 0x00
    LCD_CharD addlw 0x30
    LCD_Char movwf templcd
    swapf templcd, w ;send upper nibble
    andlw 0x0f ;clear upper 4 bits of W
    movwf LCD_PORT
    bsf LCD_PORT, LCD_RS ;RS line to 1
    call Pulse_e ;Pulse the E line high
    movf templcd, w ;send lower nibble
    andlw 0x0f ;clear upper 4 bits of W
    movwf LCD_PORT
    bsf LCD_PORT, LCD_RS ;RS line to 1
    call Pulse_e ;Pulse the E line high
    call Delay5
    retlw 0x00
    LCD_Line1 movlw 0x80 ;move to 1st row, first column
    call LCD_Cmd
    retlw 0x00
    LCD_Line2 movlw 0xc0 ;move to 2nd row, first column
    call LCD_Cmd
    retlw 0x00
    LCD_Line1W addlw 0x80 ;move to 1st row, column W
    call LCD_Cmd
    retlw 0x00
    LCD_Line2W addlw 0xc0 ;move to 2nd row, column W
    call LCD_Cmd
    retlw 0x00
    LCD_CurOn movlw 0x0d ;Set display on/off and cursor command
    call LCD_Cmd
    retlw 0x00
    LCD_CurOff movlw 0x0c ;Set display on/off and cursor command
    call LCD_Cmd
    retlw 0x00
    LCD_Clr movlw 0x01 ;Clear display
    call LCD_Cmd
    retlw 0x00
    LCD_HEX movwf tmp1
    swapf tmp1, w
    andlw 0x0f
    call HEX_Table
    call LCD_Char
    movf tmp1, w
    andlw 0x0f
    call HEX_Table
    call LCD_Char
    retlw 0x00
    Delay255 movlw 0xff ;delay 255 mS
    goto d0
    Delay100 movlw d'100' ;delay 100mS
    goto d0
    Delay50 movlw d'50' ;delay 50mS
    goto d0
    Delay20 movlw d'20' ;delay 20mS
    goto d0
    Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
    d0 movwf count1
    d1 movlw 0xC7 ;delay 1mS
    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
    Pulse_e bsf LCD_PORT, LCD_E
    nop
    bcf LCD_PORT, LCD_E
    retlw 0x00
    ;end of LCD routines
    HEX_Table ADDWF PCL , f
    RETLW 0x30
    RETLW 0x31
    RETLW 0x32
    RETLW 0x33
    RETLW 0x34
    RETLW 0x35
    RETLW 0x36
    RETLW 0x37
    RETLW 0x38
    RETLW 0x39
    RETLW 0x41
    RETLW 0x42
    RETLW 0x43
    RETLW 0x44
    RETLW 0x45
    RETLW 0x46


    ; ========================================
    ; Main text for countdown timer (LCD text)
    ; ========================================
    ; "Countdown timer"
    Text addwf PCL, f
    retlw 'C' ; Character 1
    retlw 'o' ; Character 2
    retlw 'u' ; Character 3
    retlw 'n' ; Character 4
    retlw 't' ; Character 5
    retlw 'd' ; Character 6
    retlw 'o' ; Character 7
    retlw 'w' ; Character 8
    retlw 'n' ; Character 9
    retlw ' ' ; Character 10
    retlw 'T' ; Character 11
    retlw 'i' ; Character 12
    retlw 'm' ; Character 13
    retlw 'e' ; Character 14
    retlw 'r' ; Character 15
    retlw 0x00
    ;========================================

    ; ==================================================
    ; Credits Text for program (LCD text)
    ; ==================================================
    ; "By DC"
    CrdText addwf PCL, f
    retlw 'B' ; Character 1
    retlw 'y' ; Character 2
    retlw ' ' ; Character 3
    retlw 'D' ; Character 4

    retlw 0x00
    ;===================================================

    Text2 ADDWF PCL, f
    RETLW 'R'
    RETLW 'e'
    RETLW 'a'
    RETLW 'd'
    RETLW 'y'
    RETLW '.'
    RETLW '.'
    RETLW '.'
    RETLW 0x00
    end



    This is what I put together last night so far....

    Anyone got any tips or suggestions on how to progress...
     
  3. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Have you run it in MPLab Sim? If so what was wrong? I like the code coverage feature in Sim which shows you which lines have been run - it can show up some problems pretty quickly.
    Also can I recommend enclosing code in code tags in the forum. Just click "go advanced", highlight the section and click the "#" icon. It keeps the formatting and makes it a lot easier to read.
     
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    In which part of your project do struggle?
     
  5. delmasli

    New Member

    Sep 17, 2009
    17
    0
    Schematic seem not so difficult but I cannot say same for the code. Try to write this code in "Structured or Generic Programming Style" at C. Assembler seems somehow complicated and not easy to resolve (for me) if the code line count is more than 100.
     
  6. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    Thanks for the quick response guys.

    I never did understand how the simulator works on MPLABs software.... can anyone suggest a website with a good tutorial of how to use it?

    I guess the problem for me is getting the timer routine to tie in with the rest of the code. I'm using the internal clock of the 16f628 for this, what code would people suggest for the minute timer sub routine?
     
  7. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    I don't know any MPlab tutorials but there must be some out there. It was similar to other stuff I've used.
    There are a few ways of doing this:
    For the 1 second tick you could write a 1 second loop and knock a bit off for your overheads - LCD etc. You could instead use Timer1 interrupts to get a regular tick which would be independant of your other code which would make getting good accuracy easier but make the code harder.
    For the counter you could either convert the minutes and seconds into a 16 bit number held in 2 registers and then convert back to display it or deal with it in 4 registers, each holding decimal values for the minutes, 10s of minutes, seconds and 10s of seconds.
    There are plenty of other ways too.
    I'd also suggest looking at AN526 on the microchip site which has 16 bit math and binary to decimal conversion routines.
     
  8. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    Can anyone see where i'm going wrong...

    I'm doing bit by bit and testing the code, but now the screen comes up with nothing... (PIC is OK, as I put another program on it and it works).

     
  9. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    At first glance I see a couple of potential problems:
    Is everything supposed to be portB?
    and

    Max value 255 for files. You will have to find some other way to to get 1 second - possibly the easiest way is to call delay 4 times at 250ms.
     
  10. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    you are the best...

    I can't believe i never noticed that.

    As for the delay, I never knew that.

    The timer is starting to take some real shape now. I'm working on the bleeper routine at this very minute. I bought a piezo buzzer today (perfect as it only draws 10mA), so i should be able to connect it straight up.
     
  11. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    Ok guys i've hit a brick wall...

    Below is next step to the program, the actual countdown timer.
    The problem i'm facing is when the 'StartTimer' routine is present in the program, the PIC keeps repeating the intro routine over and over. If i remove the 'StartTimer' routine, everything works as it should. There is clearly a conflict somewhere, but i just can't see it.

    here is the code...

    Code ( (Unknown Language)):
    1.  
    2. call Delay100 ;wait for LCD to settle
    3. call LCD_Init ;setup LCD
    4. ; ***************************************
    5. ; BEGINNING OF PROGRAM
    6. clrf count ;set counter register to zero
    7. call SngBeep
    8. Message movf count, w ;put counter value in W
    9. call Text ;get a character from the text table
    10. xorlw 0x00 ;is it a zero?
    11. btfsc STATUS, Z
    12. goto NextMessage
    13. call LCD_Char
    14. call Delay100 ; puts a delay in between characters.
    15. incf count, f
    16. goto Message
    17. NextMessage call LCD_Line2 ;move to 2nd row, first column
    18. clrf count ;set counter register to zero
    19. Message2 movf count, w ;put counter value in W
    20. call CrdText ;get a character from the credit text table
    21. xorlw 0x00 ;is it a zero?
    22. btfsc STATUS, Z
    23. goto StartProg
    24. call LCD_Char
    25. call Delay100 ; puts a delay in between characters.
    26. incf count, f
    27. goto Message2
    28. StartProg ; Start of countdown program
    29. call Delay255 ; Puts a delay before starting program
    30. call Delay255 ; Puts a delay before starting program
    31. call Delay255 ; Puts a delay before starting program
    32. call Delay255 ; Puts a delay before starting program
    33.  
    34. call LCD_Clr ; Clears LCD screen
    35. call LCD_CurOff ; Turns off the LCD cursor
    36. clrf NumL ; Clears the memory of the variable
    37. clrf NumH ; Clears the memory of the variable
    38.  
    39. clrf count ;set counter register to zero
    40. Message3 movf count, w ;put counter value in W
    41. call SetText ;get a character from the credit text table
    42. xorlw 0x00 ;is it a zero?
    43. btfsc STATUS, Z
    44. goto stage2
    45. call LCD_Char
    46. incf count, f
    47. goto Message3
    48. stage2 movlw d'2'
    49. call LCD_CurOn ; turn the LCD cursor on
    50. call LCD_Line2W ; move to 2nd row, third column
    51.  
    52. call Convert ;convert to decimal
    53. movf Tens, w
    54. call LCD_CharD
    55. movf Ones, w
    56. call LCD_CharD
    57. movlw ' ' ;display a 'space'
    58. call LCD_Char
    59. movlw 'M'
    60. call LCD_Char
    61. movlw 'i'
    62. call LCD_Char
    63. movlw 'n'
    64. call LCD_Char
    65. movlw 's'
    66. call LCD_Char
    67. call SngBeep
    68. incfsz NumL, f
    69. goto Loop1
    70. incf NumH, f
    71. ;Next call Delay255 ;wait so you can see the digits change
    72.  
    73.  
    74. ; Loop waits for a button press.
    75. Loop1 btfss SWPORT, SW1 ; Increase time button
    76. call Switch1 ; Call sub routine when SW1 is pressed
    77. btfss SWPORT, SW2 ; Reset time button
    78. call Switch2 ; Call sub routine when SW2 is pressed
    79. btfss SWPORT, SW3 ; Start Timer button
    80. call Switch3
    81. Goto Loop1
    82.  
    83. Switch1 goto stage2
    84. retlw 0x00
    85.  
    86. Switch2 clrf NumL ; Clears the memory of the variable
    87. clrf NumH ; Clears the memory of the variable
    88. goto stage2
    89. retlw 0x00
    90.  
    91. Switch3 call SngBeep
    92. goto StartTimer
    93. retlw 0x00
    94.  
    95. StartTimer call LCD_Clr
    96. call LCD_CurOff
    97. clrf count ;set counter register to zero
    98. TimerMessage movf count, w ;put counter value in W
    99. call TimStart ;get a character from the credit text table
    100. xorlw 0x00 ;is it a zero?
    101. btfsc STATUS, Z
    102. goto stage3
    103. call LCD_Char
    104. incf count, f
    105. goto TimerMessage
    106.  
    107. stage3 call LCD_Line2W ; move to 2nd row, third column
    108.  
    109. call Convert ;convert to decimal
    110. movf Tens, w
    111. call LCD_CharD
    112. movf Ones, w
    113. call LCD_CharD
    114. movlw ' ' ;display a 'space'
    115. call LCD_Char
    116. movlw 'M'
    117. call LCD_Char
    118. movlw 'i'
    119. call LCD_Char
    120. movlw 'n'
    121. call LCD_Char
    122. movlw 's'
    123. call LCD_Char
    124. call SngBeep
    125. decfsz NumL, f
    126. goto Part2
    127. decf NumH, f
    128. Part2 call Delay255
    129. goto stage3
    130.  
    131. Stop goto Stop ;endless loop
    132. ; ***************************************
    133. ;Subroutines and text tables
    134. ;LCD routines
    135. ;Initialise LCD
    136. LCD_Init movlw 0x20 ;Set 4 bit mode
    137. call LCD_Cmd
    138. movlw 0x28 ;Set display shift
    139. call LCD_Cmd
    140. movlw 0x06 ;Set display character mode
    141. call LCD_Cmd
    142. ; movlw 0x0c will turn off cursor, replacing c with d will turn it on.
    143. movlw 0x0c ;Set display on/off and cursor command
    144. call LCD_Cmd
    145. call LCD_Clr ;clear display
    146. retlw 0x00
    147. ; command set routine
    148. LCD_Cmd movwf templcd
    149. swapf templcd, w ;send upper nibble
    150. andlw 0x0f ;clear upper 4 bits of W
    151. movwf LCD_PORT
    152. bcf LCD_PORT, LCD_RS ;RS line to 0
    153. call Pulse_e ;Pulse the E line high
    154. movf templcd, w ;send lower nibble
    155. andlw 0x0f ;clear upper 4 bits of W
    156. movwf LCD_PORT
    157. bcf LCD_PORT, LCD_RS ;RS line to 0
    158. call Pulse_e ;Pulse the E line high
    159. call Delay5
    160. retlw 0x00
    161. LCD_CharD addlw 0x30
    162. LCD_Char movwf templcd
    163. swapf templcd, w ;send upper nibble
    164. andlw 0x0f ;clear upper 4 bits of W
    165. movwf LCD_PORT
    166. bsf LCD_PORT, LCD_RS ;RS line to 1
    167. call Pulse_e ;Pulse the E line high
    168. movf templcd, w ;send lower nibble
    169. andlw 0x0f ;clear upper 4 bits of W
    170. movwf LCD_PORT
    171. bsf LCD_PORT, LCD_RS ;RS line to 1
    172. call Pulse_e ;Pulse the E line high
    173. call Delay5
    174. retlw 0x00
    175. LCD_Line1 movlw 0x80 ;move to 1st row, first column
    176. call LCD_Cmd
    177. retlw 0x00
    178. LCD_Line2 movlw 0xc0 ;move to 2nd row, first column
    179. call LCD_Cmd
    180. retlw 0x00
    181. LCD_Line1W addlw 0x80 ;move to 1st row, column W
    182. call LCD_Cmd
    183. retlw 0x00
    184. LCD_Line2W addlw 0xc0 ;move to 2nd row, column W
    185. call LCD_Cmd
    186. retlw 0x00
    187. LCD_CurOn movlw 0x0d ;Set display on/off and cursor command
    188. call LCD_Cmd
    189. retlw 0x00
    190. LCD_CurOff movlw 0x0c ;Set display on/off and cursor command
    191. call LCD_Cmd
    192. retlw 0x00
    193. LCD_Clr movlw 0x01 ;Clear display
    194. call LCD_Cmd
    195. retlw 0x00
    196. LCD_HEX movwf tmp1
    197. swapf tmp1, w
    198. andlw 0x0f
    199. call HEX_Table
    200. call LCD_Char
    201. movf tmp1, w
    202. andlw 0x0f
    203. call HEX_Table
    204. call LCD_Char
    205. retlw 0x00
    206.  
    207. SngBeep bsf LEDPORT, LED1
    208. call Delay100
    209. bcf LEDPORT, LED1
    210. ; ***************************************
    211. ; DELAY ROUTINES
    212.  
    213. Delay255 movlw 0xff ;delay 255 mS (0xff in hexadecimal)
    214. goto d0
    215. Delay100 movlw d'100' ;delay 100mS
    216. goto d0
    217. Delay50 movlw d'50' ;delay 50mS
    218. goto d0
    219. Delay20 movlw d'20' ;delay 20mS
    220. goto d0
    221. Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
    222. d0 movwf count1
    223. d1 movlw 0xC7 ;delay 1mS
    224. movwf counta
    225. movlw 0x01
    226. movwf countb
    227. Delay_0
    228. decfsz counta, f
    229. goto $+2
    230. decfsz countb, f
    231. goto Delay_0
    232. decfsz count1 ,f
    233. goto d1
    234. retlw 0x00
    235.  
    236. ; END OF DELAY ROUTINES
    237. ; ***************************************
    238. ; PULSE THE LCD E LINE
    239. Pulse_e bsf LCD_PORT, LCD_E
    240. nop
    241. bcf LCD_PORT, LCD_E
    242. retlw 0x00
    243.  
    244. ; ***************************************
    245. ;end of LCD routines
    246.  
    247.  
    248. HEX_Table ADDWF PCL , f
    249. RETLW 0x30
    250. RETLW 0x31
    251. RETLW 0x32
    252. RETLW 0x33
    253. RETLW 0x34
    254. RETLW 0x35
    255. RETLW 0x36
    256. RETLW 0x37
    257. RETLW 0x38
    258. RETLW 0x39
    259. RETLW 0x41
    260. RETLW 0x42
    261. RETLW 0x43
    262. RETLW 0x44
    263. RETLW 0x45
    264. RETLW 0x46
    265.  
    266.  
    267. ; ***************************************
    268. ; Main text for countdown timer (LCD text)
    269.  
    270. ; Countdown timer
    271. Text addwf PCL, f
    272. retlw 'C' ; Character 1
    273. retlw 'o' ; Character 2
    274. retlw 'u' ; Character 3
    275. retlw 'n' ; Character 4
    276. retlw 't' ; Character 5
    277. retlw 'd' ; Character 6
    278. retlw 'o' ; Character 7
    279. retlw 'w' ; Character 8
    280. retlw 'n' ; Character 9
    281. retlw ' ' ; Character 10
    282. retlw 'T' ; Character 11
    283. retlw 'i' ; Character 12
    284. retlw 'm' ; Character 13
    285. retlw 'e' ; Character 14
    286. retlw 'r' ; Character 15
    287. retlw 0x00
    288.  
    289.  
    290. ; ***************************************
    291. ; Credits Text for program (LCD text)
    292.  
    293. ; By Dominic Rawle
    294. CrdText addwf PCL, f
    295. retlw 'B' ; Character 1
    296. retlw 'y' ; Character 2
    297. retlw ' ' ; Character 3
    298. retlw 'D' ; Character 4
    299. retlw 'o' ; Character 5
    300. retlw 'm' ; Character 6
    301. retlw 'i' ; Character 7
    302. retlw 'n' ; Character 8
    303. retlw 'i' ; Character 9
    304. retlw 'c' ; Character 10
    305. retlw ' ' ; Character 11
    306. retlw 'R' ; Character 12
    307. retlw 'a' ; Character 13
    308. retlw 'w' ; Character 14
    309. retlw 'l' ; Character 15
    310. retlw 'e' ; Character 16
    311. retlw 0x00
    312.  
    313. ; ***************************************
    314.  
    315. SetText ADDWF PCL, f
    316. retlw 'S' ; Character 1
    317. retlw 'e' ; Character 2
    318. retlw 't' ; Character 3
    319. retlw ' ' ; Character 4
    320. retlw 'T' ; Character 5
    321. retlw 'i' ; Character 6
    322. retlw 'm' ; Character 7
    323. retlw 'e' ; Character 8
    324. retlw 'r' ; Character 9
    325. retlw 0x00
    326. ; ****************************************
    327. TimStart ADDWF PCL, f
    328. retlw 'T' ; Character 1
    329. retlw 'i' ; Character 2
    330. retlw 'm' ; Character 3
    331. retlw 'e' ; Character 4
    332. retlw 'r' ; Character 5
    333. retlw ' ' ; Character 6
    334. retlw 'S' ; Character 7
    335. retlw 't' ; Character 8
    336. retlw 'a' ; Character 9
    337. retlw 'r' ; Character 10
    338. retlw 't' ; Character 11
    339. retlw 'e' ; Character 12
    340. retlw 'd' ; Character 13
    341. retlw 0x00
    342.  
    343. ; ****************************************
    344. TimStop ADDWF PCL, f
    345. retlw 'T' ; Character 1
    346. retlw 'i' ; Character 2
    347. retlw 'm' ; Character 3
    348. retlw 'e' ; Character 4
    349. retlw 'r' ; Character 5
    350. retlw ' ' ; Character 6
    351. retlw 'S' ; Character 7
    352. retlw 't' ; Character 8
    353. retlw 'o' ; Character 9
    354. retlw 'p' ; Character 10
    355. retlw 'p' ; Character 11
    356. retlw 'e' ; Character 12
    357. retlw 'd' ; Character 13
    358. retlw 0x00
    359. ; ******************************************************************
    360. ;This routine downloaded from [URL]http://www.piclist.com[/URL]
    361. Convert: ; Takes number in NumH:NumL
    362. ; Returns decimal in
    363. ; TenK:Thou:Hund:Tens:Ones
    364. swapf NumH, w
    365. iorlw B'11110000'
    366. movwf Thou
    367. addwf Thou,f
    368. addlw 0XE2
    369. movwf Hund
    370. addlw 0X32
    371. movwf Ones
    372. movf NumH,w
    373. andlw 0X0F
    374. addwf Hund,f
    375. addwf Hund,f
    376. addwf Ones,f
    377. addlw 0XE9
    378. movwf Tens
    379. addwf Tens,f
    380. addwf Tens,f
    381. swapf NumL,w
    382. andlw 0X0F
    383. addwf Tens,f
    384. addwf Ones,f
    385. rlf Tens,f
    386. rlf Ones,f
    387. comf Ones,f
    388. rlf Ones,f
    389. movf NumL,w
    390. andlw 0X0F
    391. addwf Ones,f
    392. rlf Thou,f
    393. movlw 0X07
    394. movwf TenK
    395. ; At this point, the original number is
    396. ; equal to
    397. ; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
    398. ; if those entities are regarded as two's
    399. ; complement binary. To be precise, all of
    400. ; them are negative except TenK. Now the number
    401. ; needs to be normalized, but this can all be
    402. ; done with simple byte arithmetic.
    403. movlw 0X0A ; Ten
    404. Lb1:
    405. addwf Ones,f
    406. decf Tens,f
    407. btfss 3,0
    408. goto Lb1
    409. Lb2:
    410. addwf Tens,f
    411. decf Hund,f
    412. btfss 3,0
    413. goto Lb2
    414. Lb3:
    415. addwf Hund,f
    416. decf Thou,f
    417. btfss 3,0
    418. goto Lb3
    419. Lb4:
    420. addwf Thou,f
    421. decf TenK,f
    422. btfss 3,0
    423. goto Lb4
    424. retlw 0x00
    425. end
    Edit: Thanks Ke5nnt, ref the code tag.
     
    Last edited: Jan 31, 2010
  12. ke5nnt

    Active Member

    Mar 1, 2009
    384
    15
    Here are a couple things from reading your thread:

    When entering code in the forums, it makes it easier/cleaner to wrap in in code tag, e.g. [ code ] insert code here [ /code ] (without spaces of course).

    If you're having trouble with delay routines for longer delays (the one second delay for instance) there is a great tool you can use HERE.

    Just enter your clock speed in MHz and the time in seconds. If using a 32KHz clock enter 0.032 and enter 1 in the delay line and it generates code in Assembly. Using those figures, a one second delay would be:
    Code ( (Unknown Language)):
    1.  
    2. 1secDLY movlw    0x3F
    3.     movwf    d1 (or the name of your file, I use "count1")
    4.     movlw    0x07
    5.     movwf    d2 (or the name of your file, I use "count2")
    6. Delay_0
    7.     decfsz    d1, f
    8.     goto    $+2
    9.     decfsz    d2, f
    10.     goto    Delay_0
    11.         return
    Then you can "call 1secDLY"...

    I'll continue to look at your code and see if I can spot something causing your repeat problem.
     
  13. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    thanks. Much appreciated.
     
  14. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    I gave it a quick run through MPLab Sim and got the attached error:
    It probably means you have nested calls too deep or there is a call without a return somewhere. The stack can only hold 8 addresses and when it gets full unexpected things happen.
    Your code is progressing at an impressive rate, but I think you might have to take a while to look at the sim.
     
  15. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    Thanks Mark.

    I found something quite interesting about this...

    I removed a single line of code, the same thing happens but it displays an extra character before going back to the intro routine.

    Would this be something to do with the quantity of the code and that the PIC has reached it's maximum instruction length?
     
  16. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    That's to be expected with the stack overflow problem. Every time a call is made, the address that the call was made from is put onto the stack.
    The return statement moves the program counter back to that point. If more that 8 calls have happened without returns then the first item on the stack is overwritten. That means that at some point the program counter is going to be set to the wrong value and the code jumps to the wrong point.

    There is also a type of problem that is caused by data tables that cross the page boundaries that you could be running into. The problem is that PCL is 8 bit and adding something to PCL that causes it to go over 255 (0xFF).
    If you click view and then disassembly listing, the first column is the location of the instruction on the chip. Any table that encompasses 0xFF or 0x1FF, etc will have problems.
     
  17. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Other code that crosses a boundary should be OK I think.
    You can use ORG 0x0100 to move the start of a table to just after the page boundary.
     
  18. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    is there any alternatives i could use to avoid this altogether?

    i've been trying to strip down the number of calls in the code. This has helped alot but still hasn't solved the problem entirely.

    How do I know when i've reached the maximum storage capacity of the PIC anyway?
     
  19. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Unfortunately not on this PIC. I think I heard the PIC18s don't have this problem.
    You are OK on storage so far - click 'view', 'Memory usage gauge'.
    Data memory gauge doesn't work for me but program usage does.
     
  20. bluebrakes

    Thread Starter Active Member

    Oct 17, 2009
    245
    7
    So as i understand it, my problem is that the PIC is getting confused due to the number of calls being made on subroutines.

    So for the subroutines that consist of a matter of a couple of lines, should i get rid of these and put the code directly in place to cut down that way?

    It would make it a bit more complex to read to but if it solves the problem i'm up for anything.
     
Loading...