Jepp, försöker att testa ut i smådelar nu, för att sen en vacker dag ha ett program liknande det jag hittade för två stegmotorer. Visserligen skrivet i PBP men jag limmar in det här iaf. Kan ju vara nån som får nån hjälp.
(Fråga inte varför det kom med radnummer, det fanns inte i originalet, men kom när jag klistrade in det i World för att spara.)
Kod: Markera allt
1. ' *****************************************************************************
2. ' * *
3. ' * File...... 8722 Scanner_RS232 *
4. ' * Purpose... Plotter/Scanner XY table with diagonal moves *
5. ' * Date...... April 2010 by Bill legge *
6. ' * *
7. ' *****************************************************************************
8.
9. ' 1. Outline: software for a XY plotter/scanner table, axis driven by stepper
10. ' motors that can move at the same time to achieve diagonal plotting/scanning
11. ' The main variables are:
12. ' * Current location of the plot head: X_position, Y_position
13. ' * Desired location: X_demand, Y_demand
14. ' * Speed of move
15. ' The X-demand, Y_demand and Speed words are input by RS232 @ 19200 Baud
16.
17. ' 2. MCU PIC18F8722. Board is Futurlec ET-BASE PIC8722 (ICD2) 10MHz Xtal
18. ' 3. ETT relay board, opto isolated, active low, jumpers select PIC or Mach3 drive
19. ' 4. ETT LED display, active low
20. ' 5. ETT button input, active low
21. ' 6. Chinese stepper dive, absolute max voltage is 24V, Use 20V. DB25 Pins:
22. ' 1 X Drive To Port D0
23. ' 2 Y Enable To Port D5. High = enable, low = disable
24. ' 3 Y Direction To Port D4. Low = move up, high = move down
25. ' 4 Z Direction Unused
26. ' 5 Z Step Unused
27. ' 6 Z Enable Unused
28. ' 7 X Direction To Port D1. Low = move right, high = move left
29. ' 8 Y Drive To Port D3
30. ' 9 Relay Unused input
31. ' 10 X Home To Port D6. Active low
32. ' 11 Y Home To Port D7. Active low
33. ' 12 Unused input
34. ' 13 Unused input
35. ' 14 X Enable To Port D2. High = enable, low = disable
36. ' 15 Unused Input
37. ' 16
38. ' 17
39. ' 18-25 Ground
40.
41. ' Mechanical
42. ' Motor settings 200 steps/rev*16 pulses/step = 3,200 pulses/rev
43. ' Belt pitch 2mm
44. ' Pulley 36 teeth. 1rev = 36*2mm = 72mm
45. ' X axis length 720mm = 10 revs = 32,000 pulses
46. ' Y axis length 360mm = 5 revs = 16,000 pulses
47. ' WORD [$ffff or 65,525] will hold maximum X or Y steps
48.
49. ' Motor Speeds
50. ' MCU Osc is 4*10MHz. Period = 0.025uS. Tcy = 4*Period = 0.1uS
51. ' Pulse periods: 800uS gives v.slow rotation and 100uS is maximum speed
52. ' Use pulse rates that are 'powers of 2' so division/multiplication is fast
53. ' Slug = 8192[Tcy] = 819.2uS = 819.2*3,200 = 2,621,440uS = 2.6S/rev (2^13)
54. ' Slow = 4096[Tcy] = 409.6uS = 409.6*3,200 = 1,310,720uS = 1.3S/rev (2^12)
55. ' Fast = 2048[Tcy] = 204.8uS = 204.8*3,200 = 655,360uS = 0.6S/rev (2^11)
56. ' Race = 1024[Tcy] = 102.4uS = 102.4*3,200 = 327,680uS = 0.3S/rev (2^10)
57.
58. ' Timer1 in 16 Bit Mode, used for X axis
59. ' Maximum count = $FFFF = 65,535
60. ' Maximum prescale = 8
61. ' Max count with max prescale = 65,535*8 = 524,280[Tcy]
62. ' = 52,428uS = 52.4mS
63.
64. ' Timer0 in 16 Bit Mode, used for Y axis
65. ' Maximum count = $FFFF = 65,535
66. ' Maximum prescale = 256
67. ' Max count with max prescale = 65,535*256 = 16,776,960[Tcy]
68. ' = 1,677,696uS = 1677mS = 1.677 Seconds = 0.596Hz
69.
70. ' Straight Line Plots
71. ' If the X or Y steps are zero, a special routine is used to avoid
72. ' division by zero
73.
74. ' *****************************************************************************
75. ' * *
76. ' * INCLUDE & DEFINES *
77. ' * *
78. ' *****************************************************************************
79.
80. clear
81. define OSC 40 ' Use HSPLL during compilation
82. DEFINE INTHAND Timer_ints
83. include "modedefs.bas" ' Include serout defines
84.
85. define HSER_RCSTA 90h ' RS232-1 TX is C7, RX is C6
86. define HSER_TXSTA 24h
87. define HSER_BAUD 19200
88. define HSER_CLROERR 1
89.
90. ' *****************************************************************************
91. ' * *
92. ' * VARIABLES *
93. ' * *
94. ' *****************************************************************************
95.
96. T0_delay var word BankA System ' Subtracted from 65,535 in asm
97. T1_delay var word BankA System ' Subtracted from 65,535 in asm
98. X_steps var word BankA System ' Steps to move = Demand - Current
99. Y_steps var word BankA System ' Steps to move = Demand - Current
100. lcount var byte BankA System ' Delay to make pulse out
101.
102. X_position var word ' Current X position
103. Y_Position var word ' Current Y position
104. X_demand var word ' Demanded X position
105. Y_demand var word ' Demanded Y position
106.
107. Temp_delay var long ' Holds temporaty pulse period calculations
108. Prescale var word ' Timer0/1 prescale to get long delays
109.
110. Slug con 8192 ' Delay = 8192[Tcy]. 2^13. 1rev = 2.62S
111. Slow con 4096 ' Delay = 4096[Tcy]. 2^12. 1rev = 1.31S
112. Fast con 2048 ' Delay = 2048[Tcy]. 2^11. 1rev = 0.65S
113. Race con 1024 ' Delay = 1024[Tcy]. 2^10. 1rev = 0.33S
114. Speed var word ' Selected before issuing D_move command
115.
116. X_drive var PORTD.0
117. X_dir var PORTD.1 ' Low = move right, high = move left
118. X_ena var PORTD.2 ' High = enable, low = disable
119. Y_drive var PORTD.3
120. Y_dir var PORTD.4 ' Low = move up, high = move down
121. Y_ena var PORTD.5 ' High = enable, low = disable
122.
123. Heartbeat var PORTH.0 ' Green LED on MCU board
124.
125. ' *****************************************************************************
126. ' * *
127. ' * INITIALISE *
128. ' * *
129. ' *****************************************************************************
130.
131. ADCON1 = %00001101 ' A0, A1 analog, rest digital
132. CMCON = %00000111 ' Comparators off, this frees up PORTF
133.
134. TRISC = %10000000 ' C0-C3 is output, C6 is HSER Tx, C7 is HSER Rx
135. TRISD = %11000000 ' D0-D5 is stepper out, D6,D7 are HOME inputs
136.
137. Speed = Slow ' 409.6uS pulses
138. goto Main ' Skip over ASM code
139.
140. ' *****************************************************************************
141. ' * *
142. ' * ASSEMBLER CODE *
143. ' * *
144. ' *****************************************************************************
145. ASM
146. Timer_ints
147. bcf INTCON,7 ; Disable all interrupts
148. btfss INTCON,TMR0IF ; Is Timer0 interrupt flag set?
149. bra Check_T1 ; No so branch to Timer1 interrupt
150. movff T0_delay+1,TMR0H ; Load Timer0 with delay_hb first
151. movff T0_delay,TMR0L ; Load Timer0 with delay_lb last
152. bcf INTCON,TMR0IF ; Clear Timer0 interrupt flag
153.
154. bsf PORTD,3 ; T0 is always Y axis
155. call Short_pulse ; Make output pulse
156. bcf PORTD,3 ; Low Y drive
157.
158. movf Y_steps,f ; Update STATUS register
159. btfsc STATUS,Z ; Is low byte zero?
160. decf Y_steps+1,f ; Yes so decrement high byte
161. decf Y_steps,f ; Decrament low byte
162.
163. Check_T1
164. btfss PIR1,TMR1IF ; Is Timer1 interrupt flag set?
165. bra Int_exit ; No so branch to end of ISR
166. movff T1_delay+1,TMR1H ; Load Timer0 with delay_hb first
167. movff T1_delay,TMR1L ; Load Timer0 with delay_lb last
168. bcf PIR1,TMR1IF ; Clear Timer1 interrupt flag
169.
170. bsf PORTD,0 ; T1 is always X axis
171. call Short_pulse ; Make output pulse
172. bcf PORTD,0 ; low X drive
173.
174. movf X_steps,f ; Update STATUS register
175. btfsc STATUS,Z ; Is low byte zero?
176. decf X_steps+1,f ; Yes so decrement high byte
177. decf X_steps,f ; Decrament low byte
178.
179. Int_exit
180. bsf INTCON,7 ; Enable all interrupts
181. retfie FAST ; Return automatic restore
182.
183. ; Pulse out subroutine
184. Short_pulse ; Delay = 3.n+7 [0.1uS]
185. movlw 0x62 ; $21 = 10uS, $62 = 30uS, $ff = 77.2uS
186. movwf lcount
187. Pulse_loop
188. decfsz lcount ; Decrement the file Count
189. goto Pulse_loop ; Loop if not zero
190. return
191. ;*************************************************************************
192. ;* MAIN ASM *
193. ;*************************************************************************
194. ENDASM
195.
196. ASM
197. _Main_ASM
198. comf T0_delay+1 ; So that the computed delay
199. comf T0_delay ; does not have to be subtracted
200. comf T1_delay+1 ; from 65,535, the overflow
201. comf T1_delay ; of Timer0 and Timer1 in 16 bit mode
202. ; Set up interrupt conditions
203. bcf RCON,7 ; Disable priority levels, IPEN=0
204. bsf INTCON,7 ; Enable all unmasked interrupts
205. bsf INTCON,6 ; Enable all unmasked peripheral interrupts
206. bcf INTCON,3 ; Disable PORTB interrupts
207. bcf INTCON2,2 ; Timer0 overflow low priority
208. bcf IPR1,0 ; Timer1 overflow low priority
209. ; Load timers, T0CON and T1CON set in PBP
210. movff T0_delay+1,TMR0H ; Load Timer0 with delay_hb first
211. movff T0_delay,TMR0L ; Load Timer0 with delay_lb after hi byte
212. movff T1_delay+1,TMR1H ; Load Timer1 with delay_hb first
213. movff T1_delay,TMR1L ; Load Timer1 with delay_lb after hi byte
214. bcf INTCON,TMR0IF ; Timer0 clear interrupt flag
215. bsf INTCON,TMR0IE ; Timer0 enable interrupt
216. bcf PIR1,TMR1IF ; Timer1 clear interrupt flag
217. bsf PIE1,TMR1IE ; Timer1 enable interrupt
218.
219. Main_loop
220. tstfsz X_steps+1 ; Is high byte zero?
221. goto Test_Y ; Not zero so test Y_steps
222. tstfsz X_steps ; Is low byte zero?
223. goto Test_Y ; Not zero so test Y_steps
224. bcf PIE1,TMR1IE ; Is zero so disable Timer1 interrupt
225. bcf PIR1,TMR1IF ; Is zero so clear Timer1 flag
226. movlw b'10000000' ; Stop timer1 running
227. movwf T1CON ; Kill Timer1 now
228. Test_Y
229. tstfsz Y_steps+1 ; Is high byte zero?
230. goto Main_loop ; Not zero so keep running
231. tstfsz Y_steps ; Is low byte zero?
232. goto Main_loop ; Not zero so do it all again
233. bcf INTCON,TMR0IE ; Timer0 disable interrupt
234. bcf INTCON,TMR0IF ; Timer0 clear interrupt flag
235. movlw b'00000000' ; Stop Timer0 running
236. movwf T0CON ; Kill timer0 now
237.
238. btfsc PIE1,TMR1IE ; Has Timer1 interrupt been killed?
239. goto Main_loop ; Not zero so keep running
240.
241. All_done
242. bcf INTCON,7 ; Disable all interrupts
243. return
244. ENDASM
245.
246. ' *****************************************************************************
247. ' * *
248. ' * MAIN *
249. ' * *
250. ' *****************************************************************************
251.
252. Main:
253. Speed = Slow
254. gosub RS232_input
255. gosub D_move
256. toggle Heartbeat
257. pause 100
258. goto Main
259.
260. ' *****************************************************************************
261. ' * *
262. ' * DIAGONAL MOVE. Move to X_demand, Y_demand and update X/Y_position *
263. ' * *
264. ' *****************************************************************************
265.
266. D_move:
267. if X_demand > 32000 then X_demand = 32000 ' X upper limit
268. IF Y_demand > 16000 THEN Y_demand = 16000 ' Y upper limit
269.
270. if X_demand>=X_position then
271. low X_dir ' Move right
272. X_Steps = X_demand - X_position
273. Else
274. High X_dir ' Move left
275. X_Steps = X_position - X_demand
276. endif
277. if Y_demand>=Y_position then
278. low Y_dir ' Move up
279. Y_Steps = Y_demand - Y_position
280. ELSE
281. HIGH Y_dir ' Move down
282. Y_Steps = Y_position - Y_demand
283. ENDIF
284.
285. if X_steps = 0 then ' Only Y_steps, only Timer0 needed
286. T0_delay = Speed ' Timer0 delay is fixed
287. T0CON = %10001000 ' Timer0 on, 16 bit, prescale=1
288. T1CON = %10000000 ' Timer1 off
289. goto D_move_done ' No X steps to do so end
290. endif
291.
292. IF Y_steps = 0 then ' Only X_steps, only Timer1 needed
293. T1_delay = Speed ' Timer1 delay is fixed
294. T1CON = %10000001 ' Timer1 on, 16 bit, prescale=1
295. T0CON = %00001000 ' Timer0 off
296. goto D_move_done ' No Y steps to do so end
297. endif
298.
299. if X_steps >= Y_steps then
300. T1_delay = Speed ' Timer1 delay is fixed
301. T1CON = %10000001 ' Timer1 on, 16 bit, prescale=1
302. Temp_delay = X_steps*Speed ' Calculate Timer0 delay
303. Temp_delay = Temp_delay/Y_steps ' Delay needed without prescale in [Tcy]
304. gosub Get_T0_prescale ' Now divide delay by prescale
305. goto D_move_done
306. else
307. T0_delay = Speed ' Timer0 delay is fixed
308. T0CON = %10001000 ' Timer0 on, 16 bit, prescale=1
309. Temp_delay = Y_steps*Speed ' Calculate Timer1 delay
310. Temp_delay = Temp_delay/X_steps ' Delay needed without prescale in [Tcy]
311. gosub Get_T1_prescale ' Now divide delay by prescale
312. goto D_move_done
313. endif
314.
315. D_move_done:
316. CALL Main_ASM ' Make the pulses
317. X_position=X_demand ' Move done so position = demand
318. Y_position=Y_demand ' Move done so position = demand
319. return
320.
321. ' *****************************************************************************
322. ' * *
323. ' * SUB-ROUTINES *
324. ' * *
325. ' *****************************************************************************
326.
327. Get_T0_Prescale:
328. select case Temp_delay
329. case is > 8388480
330. T0CON = %10000111
331. Prescale = 8 ; Divide by 2.2.2.2.2.2.2.2
332. case is > 4194240
333. T0CON = %10000110
334. Prescale = 7 ; Divide by 2.2.2.2.2.2.2
335. case is > 2097120
336. T0CON = %10000101
337. Prescale = 6 ; Divide by 2.2.2.2.2.2
338. case is > 1048560
339. T0CON = %10000100
340. Prescale = 5 ; Divide by 2.2.2.2.2
341. case is > 524280
342. T0CON = %10000011
343. Prescale = 4 ; Divide by 2.2.2.2
344. case is > 262140
345. T0CON = %10000010
346. Prescale = 3 ; Divide by 2.2.2
347. case is > 131070
348. T0CON = %10000001
349. Prescale = 2 ; Divide by 2.2
350. case is > 65535
351. T0CON = %10000000
352. Prescale = 1 ; Divide by 2
353. case else
354. T0CON = %10001000
355. Prescale = 0 ; Divide by 1
356. end select
357. Temp_delay = Temp_delay >> Prescale
358. T0_delay = Temp_delay.word0
359. return
360.
361. Get_T1_Prescale:
362. select case Temp_delay
363. case is > 262140
364. T1CON = %10110001
365. Prescale = 3 ; Divide by 2.2.2
366. case is > 131070
367. T1CON = %10100001
368. Prescale = 2 ; Divide by 2.2
369. case is > 65535
370. T1CON = %10010001
371. Prescale = 1 ; Divide by 2
372. case else
373. T1CON = %10000001
374. Prescale = 0 ; Divide by 1
375. end select
376. Temp_delay = Temp_delay >> Prescale
377. T1_delay = Temp_delay.word0
378. return
379.
380. ' *****************************************************************************
381. ' * *
382. ' * RS232 INPUT. Get X_demand, Y_demand from terminal *
383. ' * *
384. ' *****************************************************************************
385.
386. RS232_input:
387. hserout ["X-demand 0 to 32000",13]
388. hserout ["Y_demand 0 to 16000",13]
389. hserout ["Speed 2000(fast) to 8000(slow)",13]
390. hserout ["Enter X_demand, Y_demand, Speed",13]
391. hserin [dec X_demand,dec Y_demand,dec Speed]
392. hserout ["You entered ",dec X_demand," ",dec Y_demand," ",dec Speed,13]
393. RETURN
394.
395. end