1 | /******************************************************************************/
|
2 | /* Files to Include */
|
3 | /******************************************************************************/
|
4 | #ifdef __XC32
|
5 | #include <xc.h> /* Defines special funciton registers, CP0 regs */
|
6 | #endif
|
7 |
|
8 | #include <plib.h> /* Include to use PIC32 peripheral libraries */
|
9 | #include <stdint.h> /* For uint32_t definition */
|
10 | #include <stdbool.h> /* For true/false definition */
|
11 |
|
12 | #include "system.h" /* System funct/params, like osc/periph config */
|
13 | #include "user.h" /* User funct/params, such as InitApp */
|
14 |
|
15 | /******************************************************************************/
|
16 | /* Global Variable Declaration */
|
17 | /******************************************************************************/
|
18 |
|
19 | /* i.e. uint32_t <variable_name>; */
|
20 |
|
21 | /******************************************************************************/
|
22 | /* Main Program */
|
23 | /******************************************************************************/
|
24 |
|
25 |
|
26 | /*
|
27 | Jarvis Schultz and Jake Ware
|
28 | 2-3-2010
|
29 |
|
30 | Stepper Motor Control Code
|
31 |
|
32 | The primary purpose of this code is to drive a stepper motor. The stepper
|
33 | motor that we are working with is a 5V Bipolar stepper motor from Portescap
|
34 | (26M048B1B). The drive circuitry is basically one-half of an h-bridge attached
|
35 | to each of the four leads of the motor. Pins D0-D3 are used to control the
|
36 | transistors of the h-bridge. The motor driving is done with a timer interrupt
|
37 | service routine, and a companion code was written in processing that allows
|
38 | the user to communicate with the PIC and perform various motor control functions.
|
39 | In processing, the user has the following capabilities:
|
40 |
|
41 | 1) The ability to transmit some motor speed to the PIC, and the PIC will
|
42 | drive the motor at that speed until the user changes it (they
|
43 | can transmit a positive or a negative speed to change direction).
|
44 | 2) The ability to transmit a motor speed and number of steps to the PIC,
|
45 | and the PIC will drive the motor at the desired speed until the desired
|
46 | number of steps has been reached
|
47 | 3) The ability to send a command to stop the motor right where it is.
|
48 | */
|
49 |
|
50 |
|
51 | /** Includes ***************************************************/
|
52 | //#include "HardwareProfile.h"
|
53 | #include "stdlib.h"
|
54 | #include "string.h"
|
55 | #include "stdio.h"
|
56 |
|
57 | /** Global Variables ******************************************/
|
58 | int mot_speed = 0; // This variable is the current motor speed in steps/ second
|
59 | int number_steps = 0; // This variable is used for tracking how many steps the motor has taken
|
60 | int motor_phase = 0; // This variable can be any integer between 0 and 3, and will be used for
|
61 | // switching the control wires in the correct order
|
62 | char RS232_Out_Buffer[32]; // This array is used for temporarily storing data before sending
|
63 | // it to the PC; we will be sending current motor steps to the PC
|
64 | char RS232_In_Buffer[20] = "zzzzzzzzzzzzzzzzzzzz"; // This is an array that is initialized with
|
65 | // useless data in it; it is used for temporary
|
66 | // storage of data brought in from the PC on UART2
|
67 | int max_steps = 0; // This variable is used for position control, we initialize it at a random value
|
68 | int i = 1; // This is for marking the position in the RS232_In_Buffer that we are writing into.
|
69 |
|
70 |
|
71 | /** Defines ***************************************************/
|
72 | //#define phase_a
|
73 | //#define phase_b
|
74 | //#define phase_c
|
75 | //#define phase_d
|
76 | #define T3options T3_ON | T3_PS_1_256 | T3_SOURCE_INT // These are the setup options for timer three
|
77 | #define BAUDRATE 19200 //This is the rate that we will communicate over RS232 at
|
78 |
|
79 | //Outputs
|
80 |
|
81 |
|
82 | #define SLEEP LATEbits.LATE9 // PIN 19 // SLEEP Driver PUT of Power OFF when is "0": wait 1 ms for wake up
|
83 | #define STEP LATAbits.LATA10 // PIN 29 RA10 // STEP PIN DRIVER
|
84 | #define DIR LATAbits.LATA9 // PIN 28 RA9 // DIR PIN DRIVER
|
85 |
|
86 | //Communikation Ports
|
87 | // PIN 52 U1 RX (UC Side) Pin 53 U1 TX (UC SIDE) // Serial Port 1 "ZIGBEE"
|
88 | // Seriel Port 2 "MP3 PLAYER"
|
89 |
|
90 | // Interface Ports
|
91 | #define ON_OFF LATBbits.LATB7 //RB7 PIN27 // ON/ OFF Button
|
92 | #define SETUP LATBbits.LATB12 // RB12 PIN 41// SETUP BUTTON
|
93 | #define RFID LATBbits.LATB6 // RB6 PIN 26// MOTher MODUL RFID ID Button
|
94 |
|
95 | #define ON_OFF_LED LATBbits.LATB15 // PIN 44 // ON/OFF Status LED
|
96 | #define AUTO_MODE_LED LATBbits.LATB14 // PIN 43 // MOTHER MODUL or Automatic Mode Status LED
|
97 | #define RFID_CHECK_LED LATBbits.LATB13 // PIN 42 //RFID CHECK LED
|
98 |
|
99 |
|
100 | // Sensor Ports PUMP
|
101 | #define LOW_S LATEbits.LATE19 //RE9 PIN 19// LOW Calibration Switch
|
102 | #define HIGH_S LATEbits.LATE8 //RE8 PIN 18// High Calibration Switch
|
103 | #define Int_S_P LATAbits.LATA0 //RA0 PIN 17// Interrupt Switch Pressure Sensor
|
104 |
|
105 | // Heart Beat Output
|
106 | #define HEART LATBbits.LATB3 //RB3 PIN 22 // Output Port of the Heartbeat
|
107 |
|
108 |
|
109 |
|
110 | // RFID Reader PIns // Soft uArt
|
111 |
|
112 | #define SOFT_TX LATBbits.LATB2 //RB2//pin 23 TX
|
113 | #define SOFT_RX LATBbits.LATB1 //RB1//pin24 RX
|
114 |
|
115 |
|
116 |
|
117 | /** Function Declarations *************************************/
|
118 |
|
119 | // MP3 Player UART
|
120 |
|
121 | //Stepp Motor UART
|
122 | void initUART1(int pbClk); // Function for initializing UART1
|
123 | int GetSteps(void); // This function returns the current motor position in steps
|
124 | void SetSteps(int set_steps); // This function manually changes the number stored in the number of steps variable
|
125 | void SetSpeed(int motor_speed); // This function sets the motor speed at the desired speed and begins driving the motor
|
126 | void sendDataRS232(void); // Used for sending the current motor position to the PC using UART2
|
127 |
|
128 |
|
129 | /** Main Function: ********************************************/
|
130 | int main()
|
131 | {
|
132 |
|
133 | char data; // This variable is the current character in the RS232_In_Buffer
|
134 | char state; // This variable is the variable that determines which of the three cases the user has sent to the PIC
|
135 | char speedsign; // This variable determines which direction the motor should go
|
136 | int speed; // This is the speed of the motor that the user has sent to the PIC (in steps/ second)
|
137 | int steps; // If the user has sent a desired number of steps, this is the variable where it gets stored
|
138 |
|
139 | int dir; // This corresponds to the speedsign variable, but speedsign is a char, and this is an int
|
140 | int PbClk; // Frequency of the peripheral bus clock
|
141 | unsigned int count = 0; // This variable is for timing the sending of motor counts to PC
|
142 | int j = 1; // This is used for stepping through the RS232_In_Buffer array
|
143 | int imark; // This variable is for saving the location of a particular entry in the RS232_In_Buffer
|
144 | int n;
|
145 | // Let's set the integer pbClk to be the value of the frequency
|
146 | // of the peripheral bus clock
|
147 | PbClk = SYSTEMConfigPerformance(SYS_FREQ);
|
148 |
|
149 | // Let's set the pins D0-D3 to be low digital outputs:
|
150 | LATD |= 0b0000000000000000;
|
151 | TRISD &= 0b1111100111110000;
|
152 |
|
153 | LATA |= 0b0000000000000000;
|
154 | TRISA &= 0b1111111111110000;
|
155 |
|
156 | LATB |= 0b0000000000000000;
|
157 | TRISB &= 0b0000111111110100;
|
158 |
|
159 | LATE |= 0b0000000000000000;
|
160 | TRISE &= 0b1111110111110000;
|
161 |
|
162 | ON_OFF_LED = 1;
|
163 | AUTO_MODE_LED =1;
|
164 | RFID_CHECK_LED =1;
|
165 |
|
166 |
|
167 |
|
168 | // Initialize the LED's:
|
169 | //mInitAllLEDs();
|
170 |
|
171 | // Allow vector interrupts
|
172 | INTEnableSystemMultiVectoredInt();
|
173 |
|
174 | // Initialize UART Communication
|
175 |
|
176 | initUART1(PbClk);
|
177 |
|
178 |
|
179 | //putsUART2("Program Started\r\n");
|
180 |
|
181 | ON_OFF_LED = 0;
|
182 | AUTO_MODE_LED =0;
|
183 | RFID_CHECK_LED =0;
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 | while(1)
|
193 | {
|
194 |
|
195 |
|
196 | putsUART1("Run");
|
197 |
|
198 | ON_OFF_LED = 0;
|
199 | AUTO_MODE_LED =0;
|
200 | RFID_CHECK_LED =0;
|
201 |
|
202 |
|
203 | // This checks to see how many times we have gone through this while loop,
|
204 | // if it is a multiple of 1000, we transmit the current step count
|
205 |
|
206 | ON_OFF_LED = 1;
|
207 | AUTO_MODE_LED =0;
|
208 | RFID_CHECK_LED =1;
|
209 | }
|
210 |
|
211 | }
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 | /** User Called Functions ************************/
|
220 | // Following function returns the number of
|
221 | // steps that the motor has taken:
|
222 | int GetSteps(void)
|
223 | {
|
224 | return number_steps;
|
225 | }
|
226 |
|
227 |
|
228 | // Next function allows to user to re-set a "home" position by
|
229 | // manually changing the number of steps:
|
230 | void SetSteps(int set_steps)
|
231 | {
|
232 | INTEnable(INT_T3, 0);
|
233 | number_steps = set_steps;
|
234 | INTEnable(INT_T3, 1);
|
235 | }
|
236 |
|
237 |
|
238 | // This function allows the user to specify the desired motor speed:
|
239 | void SetSpeed(int motor_speed) // motor speed in steps/s
|
240 | {
|
241 | if (motor_speed == 0)
|
242 | {
|
243 | // Turn off timer if motor is stopped:
|
244 | T3CONbits.ON = 0;
|
245 | // Also, let's turn off all of the phases:
|
246 | //phase_a = 0;
|
247 | //phase_b = 0;
|
248 | //phase_c = 0;
|
249 | //phase_d = 0;
|
250 | STEP = 0;
|
251 | }
|
252 | else
|
253 | {
|
254 | mot_speed = motor_speed;
|
255 | int Per;
|
256 | Per = (80000000/abs(mot_speed))/256-1; // set the value in the period register
|
257 | OpenTimer3(T3options, Per);
|
258 | mT3SetIntPriority( 7); // set Timer3 Interrupt Priority
|
259 | mT3ClearIntFlag(); // clear interrupt flag
|
260 | mT3IntEnable( 1); // enable timer3 interrupts
|
261 | }
|
262 | }
|
263 |
|
264 |
|
265 |
|
266 | // This function is used for sending the current number of steps
|
267 | // that the motor has taken back to the PC:
|
268 | void sendDataRS232()
|
269 | {
|
270 | sprintf(RS232_Out_Buffer,"%d\n",number_steps);
|
271 |
|
272 | putsUART1(RS232_Out_Buffer);
|
273 | }
|
274 |
|
275 |
|
276 |
|
277 | void initUART1(int pbClk)
|
278 | {
|
279 | // define setup Configuration 1 for OpenUARTx
|
280 | // Module Enable
|
281 | // Work in IDLE mode
|
282 | // Communication through usual pins
|
283 | // Disable wake-up
|
284 | // Loop back disabled
|
285 | // Input to Capture module from ICx pin
|
286 | // no parity 8 bit
|
287 | // 1 stop bit
|
288 | // IRDA encoder and decoder disabled
|
289 | // CTS and RTS pins are disabled
|
290 | // UxRX idle state is '1'
|
291 | // 16x baud clock - normal speed
|
292 | #define config1 UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN
|
293 |
|
294 | // define setup Configuration 2 for OpenUARTx
|
295 | // IrDA encoded UxTX idle state is '0'
|
296 | // Enable UxRX pin
|
297 | // Enable UxTX pin
|
298 | // Interrupt on transfer of every character to TSR
|
299 | // Interrupt on every char received
|
300 | // Disable 9-bit address detect
|
301 | // Rx Buffer Over run status bit clear
|
302 | #define config2 UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR
|
303 |
|
304 | // Open UART2 with config1 and config2
|
305 | OpenUART1( config1, config2, pbClk/16/BAUDRATE-1); // calculate actual BAUD generate value.
|
306 |
|
307 |
|
308 | }
|