1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
| ; 16F876 PWM example code
;
; Device 16F876
LIST P=16F876, W=2, X=ON, R=DEC
#INCLUDE P16F876.INC
__CONFIG 0x393A
cblock 0x20 ;start of general purpose registers
count ;used in delay routine
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
temp ;temp storage
endc
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#define DEBUG 0
greenLED equ b'10000000' ;128,RB7
redLED equ b'01000000' ;64, RB6
horn equ b'00100000' ;32, RB5
right equ b'00001000' ;8, RA3
left equ b'00000100' ;4, RA2
back equ b'00000010' ;2, RA1
forward equ b'00000001' ;1 RA0[/i]
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
RL Equ 0x00 ;pin for left motor reverse
FL Equ 0x03 ;pin for left motor forward
RR Equ 0x04 ;pin for right motor reverse
FR Equ 0x05 ;pin for right motor forward
;pins 1 and 2 are the 2 PWM channels
ORG 0x0000
NOP ;for bootloader compatibility
NOP
NOP
GOTO START
ORG 0x0010
START CALL Initialise
;
; --------------------------------
; set ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
;
movlw 7
movwf CMCON ; CMCON=7 set comperators off
;
; ----------------
; INITIALIZE PORTS
; ----------------
;
movlw b'00000000' ; set up portA
movwf PORTA
movlw b'00000100' ; RB2(TX)=1 others are 0
movwf PORTB
bsf STATUS,RP0 ; RAM PAGE 1
movlw 0x00
movwf TRISA ; portA all pins output
movlw b'00000010' ; RB1(RX)=input, others output
movwf TRISB
; ------------------------------------
; set BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
movlw 0x19 ; 0x19=9600 bps (0x0C=19200 bps)
movwf SPBRG
movlw b'00100100' ; brgh = high (2)
movwf TXSTA ; enable Async Transmission, set brgh
bcf STATUS,RP0 ; RAM PAGE 0
movlw b'10010000' ; enable Async Reception
movwf RCSTA
;
; ------------------------------------
; PROVIDE A setTLING TIME FOR START UP
; ------------------------------------
;
clrf dataL
settle decfsz dataL,F
goto settle
movf RCREG,W
movf RCREG,W
movf RCREG,W ; flush receive buffer
;
; ---------
; MAIN LOOP
; ---------
;
clrf PORTA
movlw redLED
movwf PORTB
call message ; prints out a message if DEBUG is 1
call check_init ; wait for INIT message from WRT54GL
bsf PORTB,7
loop call receive_delay ; wait for a char
call add_green ;set greenLED on
call process_input ;make sure that forward and backward aren't both high! or that greenLED and redLED aren't both high! or that left and right aren't both high!
call send ; send the char
goto loop
process_input
; Make sure that Forward & Backward cannot be ON at the same time
; Make sure that Left & Right cannot be ON at the same time
; Output result to PORTB
###############################################################################
MOVWF temp
BTFSC temp,0 ;//Execute next line if temp,0 is HIGH
BCF temp,1
BTFSC temp,2 ;//Execute next line if temp,2 is HIGH
BCF temp,3
BTFSC temp,6 ;//Execute next line if temp,6 is HIGH
BCF temp,7
MOVF temp,0
andlw b'00001111'
movwf PORTA
movf temp,0
andlw b'11110000'
movwf PORTB
movf temp,0[/b] return
add_green
movwf temp
btfss temp,7 ;If greenLED is LOW execute next line
bsf temp,7
movf temp,0
return
###############################################################################
;
; -------------------------------------------
; RECEIVE CHARACTER FROM RS232 AND STORE IN W
; -------------------------------------------
; This routine does not return until a character is received.
;
receive btfss PIR1,RCIF ; (5) check for received data
goto receive
data_received
movf RCREG,W ; save received data in W
return
check_init
; waits to receive 'jbpro' from the router meaning that the software is up and running
; after the message is received, the greenLED is turned on and microcontroller can drive the car
call receive_delay
sublw 'j'
btfss STATUS, Z
goto check_init
call receive_delay
sublw 'b'
btfss STATUS, Z
goto check_init
call receive_delay
sublw 'p'
btfss STATUS, Z
goto check_init
call receive_delay
sublw 'r'
btfss STATUS, Z
goto check_init
call receive_delay
sublw 'o'
btfss STATUS, Z
goto check_init
#if DEBUG
;prints message and goes in to an endless loop of flashing greenLED
call message
Loop
; movlw greenLED
movlw 0xff
movwf PORTA ;set all bits on
call Delay ;this waits for a while!
movlw 0x00
movwf PORTA
call Delay
goto Loop ;go back and do it again
#endif
return
receive_delay
;299993 cycles
movlw 0x5E
movwf d1
movlw 0xEB
movwf d2
delay_0
btfsc PIR1,RCIF ;check for serial data
goto got_data ;if we do, goto got_data!
decfsz d1, f
goto $+2
decfsz d2, f
goto delay_0
movlw 0x00
return
got_data ;move data in to W
btfsc PIR1,RCIF
movf RCREG,W
return
#if DEBUG
Delay movlw d'250' ;delay 250 ms (4 MHz clock)
movwf temp
d11 movlw 0xC7
movwf d1
movlw 0x01
movwf d2
Delay_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_0
decfsz temp ,f
goto d11
retlw 0x00
#endif
;
; -------------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING
; -------------------------------------------------------------
;
send
#if DEBUG
movwf TXREG ; send data in W
TransWt bsf STATUS,RP0 ; RAM PAGE 1
WtHere btfss TXSTA,TRMT ; (1) transmission is complete if hi
goto WtHere
bcf STATUS,RP0 ; RAM PAGE 0
#endif
return
;
; -------
; MESSAGE
; -------
;
message
#if DEBUG
movlw '1'
call send
movlw '6'
call send
movlw 'F'
call send
movlw '6'
call send
movlw '2'
call send
movlw '8'
call send
movlw ' '
call send
movlw 'a'
call send
movlw 'l'
call send
movlw 'i'
call send
movlw 'v'
call send
movlw 'e'
call send
movlw 0x0D ; CR
call send
movlw 0x0A ; LF
call send
#endif
return
Initialise:
BANKSEL ADCON1 ;turn off A2D
MOVLW 0x06
MOVWF ADCON1
BANKSEL PORTA
BANKSEL TRISC
MOVLW 0 ;set PORTC as all outputs
MOVWF TRISC
BANKSEL PORTC
MOVF CCP1CON,W ;set CCP1 as PWM
ANDLW 0xF0
IORLW 0x0C
MOVWF CCP1CON
MOVF CCP2CON,W ;set CCP2 as PWM
ANDLW 0xF0
IORLW 0x0C
MOVWF CCP2CON
MOVLW 126 ;set highest PWM value
BANKSEL PR2 ;over this (127) is permanently on
MOVWF PR2
BANKSEL TMR2
MOVF T2CON,W ;set prescaler to 16
ANDLW 0xF8 ;PWM at 2500HZ
IORLW 0x02
MOVWF T2CON
MOVF T2CON,W ;set postscaler to 1
ANDLW 0x07
IORLW 0x00
MOVWF T2CON
CLRF CCPR1L ;set PWM to zero
CLRF CCPR2L
BSF T2CON, TMR2ON ;and start the timer running
RETURN
SpeedL: ;use value in W to set speed (0-127)
MOVWF temp
BTFSC temp, 7 ;if more than 128 set speed in reverse
CALL ReverseL ;so '1' is very slow forward
BTFSS temp, 7 ;and '129' is very slow reverse
CALL ForwardL
ANDLW 0x7F
MOVWF CCPR1L
RETURN
SpeedR:
MOVWF temp
BTFSC temp, 7
CALL ReverseR
BTFSS temp, 7
CALL ForwardR
ANDLW 0x7F
MOVWF CCPR2L
RETURN
ReverseL:
BSF PORTC, RL ;set pins for reverse
BCF PORTC, FL
RETURN
ReverseR:
BSF PORTC, RR
BCF PORTC, FR
RETURN
ForwardL:
BCF PORTC, RL ;set pins for forward
BSF PORTC, FL
RETURN
ForwardR:
BCF PORTC, RR
BSF PORTC, FR
RETURN
;Delay routines
Long_Delay
movlw d'50' ;delay 5 seconds
call Delay100W
return
Delay100W movwf count ;delay W x 100mS
d2 call Delay100 ;maximum delay 25.5 seconds
decfsz count ,f
goto d2
return
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
Delay10 movlw d'10' ;delay 10mS
goto d0
Delay1 movlw d'1' ;delay 1mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xE7
movwf counta
movlw 0x04
movwf countb
Delay_0 decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
return
;end of Delay routines
END |