cipi-cips
Member level 4
- Joined
- Jun 30, 2008
- Messages
- 76
- Helped
- 2
- Reputation
- 4
- Reaction score
- 1
- Trophy points
- 1,288
- Activity points
- 1,867
// USBMotorController.c
// includes ///////////////////////////////////////////////////////////////////////////////////////
#include<p18f4550.h>
#include"USBFunctions.h"
#include<timers.h>
#include<delays.h>
#include <stdio.h>
// chip config ////////////////////////////////////////////////////////////////////////////////////
// clock options, see 18F4550 data sheet figure 2-1 "clock diagram" for explanation
#pragma config PLLDIV = 5 // 20 MHz external clock / PLL prescaler value of 5 = 4 MHz required input to PLL circuit
#pragma config CPUDIV = OSC1_PLL2 // non-PLL postscale / 1 OR PLL postscale / 2 for CPU clock speed, depending on FOSC setting below
#pragma config USBDIV = 2 // USB clock source = 96 MHz PLL source / 2, (full-speed USB mode)
// if desired, could change this line to "FOSC = HS" & "oscillator postscaler" gate would be used
// (not the "PLL postscaler" gate), CPU speed would be 20MHz, USB circuitry would still receive 48Mhz clock
#pragma config FOSC = HSPLL_HS // use high-speed external osc crystal, & use PLL postscaler gate to feed CPU (CPU speed = 48 MHz)
// now the other less confusing options . . .
#pragma config FCMEN = OFF // fail-safe clock monitor disabled
#pragma config IESO = OFF // internal / external osc switchover bit disabled
#pragma config PWRT = OFF // power-up timer disabled
#pragma config BOR = OFF // brown-out reset disabled in hardware & software
#pragma config BORV = 3 // brown-out reset voltage bits, does not matter since brown-out is disabled
#pragma config VREGEN = ON // USB voltage regulator enabled (If using USB, capacitor goes on pin 18 (VUSB))
#pragma config WDT = OFF // watchdog timer disabled
#pragma config WDTPS = 32768 // watchdog timer postscale, does not matter since watchdog timer is disabled
#pragma config CCP2MX = ON // use RC1 (pin #16) as CCP2 MUX (this is the default pin for CCP2 MUX)
#pragma config PBADEN = OFF // RB0, RB1, RB2, RB3, & RB4 are configured as digital I/O on reset
#pragma config LPT1OSC = OFF // disable low-power option for timer 1 (timer 1 in regular mode)
#pragma config MCLRE = OFF // master clear disabled, pin #1 is for VPP and / or RE3 use
#pragma config STVREN = ON // stack full/underflow will cause reset
#pragma config LVP = OFF // single-supply ICSP disabled
#pragma config ICPRT = OFF // in-circuit debug/programming port (ICPORT) disabled, this feature is not available on 40 pin DIP package
#pragma config XINST = OFF // instruction set extension and indexed addressing mode disabled (this is the default setting)
#pragma config DEBUG = OFF // background debugger disabled, RA6 & RB7 configured as general purpose I/O pins
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF // code protection bits off
#pragma config CPB = OFF // boot block code protection off
#pragma config CPD = OFF // data EEPROM code protection off
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF // write protection bits off
#pragma config WRTC = OFF // config registers write protection off
#pragma config WRTB = OFF // boot block is not write protected
#pragma config WRTD = OFF // data EEPROM is not write protected
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF // table read protection bits off
#pragma config EBTRB = OFF // boot block table read protection off
// #defines ///////////////////////////////////////////////////////////////////////////////////////
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008 // these are necessary to accommodate the special linker file,
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018 // do not change these !!
#define PWM1 PORTDbits.RD7
#define PWM2 PORTDbits.RD6 // output pins
#define PWM3 PORTDbits.RD5
#define PWM4 PORTDbits.RD4
#define PWM5 PORTCbits.RC7
#define PWM6 PORTCbits.RC6
// global variables ///////////////////////////////////////////////////////////////////////////////
extern BYTE g_USBDeviceState;
extern BYTE g_fromHostToDeviceBuffer[65];
extern BYTE g_fromDeviceToHostBuffer[65];
// format for g_fromHostToDeviceBuffer[]
//
// byte - purpose
// -------------------------------------
// 0 - do NOT use this for data, this is initialized to zero in USBstuff.c, leave as is (part of USB protocol)
// 1 - servo position in degrees, valid range is 0 deg. - 180 deg.
// 2 - left DC motor, 0x00 => coast, 0x01 => forward, 0x02 => reverse, 0x03 => brake
// 3 - right DC motor, 0x00 => coast, 0x01 => forward, 0x02 => reverse, 0x03 => brake
// 4 - stepper direction, 0x00 => hold position, 0x01 => step clockwise, 0x02 => step counterclockwise
// 5 - unused
// 6 - unused
// 7 - unused
// 8 - usused
// 9 - unused
// 10 - unused
// 11 - unused
// 12 - unused
// 13 - unused
// 14 - usused
// 15 - unused
// 16 - unused
// 17 - unused
// 18 - unused
// 19 - unused
// 20 - usused
// 21 - unused
// 22 - unused
// 23 - unused
// 24 - unused
// 25 - unused
// 26 - usused
// 27 - unused
// 28 - unused
// 29 - unused
// 30 - unused
// 31 - usused
// 32 - unused
// 33 - unused
// 34 - unused
// 35 - unused
// 36 - unused
// 37 - usused
// 38 - unused
// 39 - unused
// 40 - unused
// 41 - unused
// 42 - unused
// 43 - usused
// 44 - unused
// 45 - unused
// 46 - unused
// 47 - unused
// 48 - unused
// 49 - usused
// 50 - unused
// 51 - unused
// 52 - unused
// 53 - unused
// 54 - unused
// 55 - usused
// 56 - unused
// 57 - unused
// 58 - unused
// 59 - unused
// 60 - unused
// 61 - usused
// 62 - unused
// 63 - unused
// 64 - unused
// format for g_fromDeviceToHostBuffer[]
//
// byte - purpose
// -------------------------------------
// 0 - do NOT use this for data, this is initialized to zero in USBstuff.c, leave as is (part of USB protocol)
// 1 - unused
// 2 - unused
// 3 - unused
// 4 - unused
// 5 - unused
// 6 - unused
// 7 - unused
// 8 - usused
// 9 - unused
// 10 - unused
// 11 - unused
// 12 - unused
// 13 - unused
// 14 - usused
// 15 - unused
// 16 - unused
// 17 - unused
// 18 - unused
// 19 - unused
// 20 - usused
// 21 - unused
// 22 - unused
// 23 - unused
// 24 - unused
// 25 - unused
// 26 - usused
// 27 - unused
// 28 - unused
// 29 - unused
// 30 - unused
// 31 - usused
// 32 - unused
// 33 - unused
// 34 - unused
// 35 - unused
// 36 - unused
// 37 - usused
// 38 - unused
// 39 - unused
// 40 - unused
// 41 - unused
// 42 - unused
// 43 - usused
// 44 - unused
// 45 - unused
// 46 - unused
// 47 - unused
// 48 - unused
// 49 - usused
// 50 - unused
// 51 - unused
// 52 - unused
// 53 - unused
// 54 - unused
// 55 - usused
// 56 - unused
// 57 - unused
// 58 - unused
// 59 - unused
// 60 - unused
// 61 - usused
// 62 - unused
// 63 - unused
// 64 - unused
// function prototypes ////////////////////////////////////////////////////////////////////////////
void highISR(void); // interrupt prototypes
void remappedHighISR(void); //
void yourHighPriorityISRCode(void); //
//
void lowISR(void); //
void remappedLowISR(void); //
void yourLowPriorityISRCode(void); //
//
extern void _startup(void); //
void yourInit(void);
void yourTasks(void);
void servoControl(void);
void commandServoToAngle2(BYTE angle);
void commandServoToAngle3(BYTE angle);
void commandServoToAngle4(BYTE angle);
void commandServoToAngle5(BYTE angle);
void commandServoToAngle6(BYTE angle);
void commandServoToAngle1(BYTE angle);
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma code HIGH_INTERRUPT_VECTOR = 0x08
void highISR(void) {
_asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
}
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void remappedHighISR(void) {
_asm goto yourHighPriorityISRCode _endasm
}
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma interrupt yourHighPriorityISRCode
void yourHighPriorityISRCode(void) {
if(PIR1bits.TMR1IF == 1) { // if timer 1 interrupt occurred . . .
PIR1bits.TMR1IF = 0;
servoControl();
}
} // return will be a "retfie fast"
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma code LOW_INTERRUPT_VECTOR = 0x18
void lowISR(void) {
_asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
}
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
void remappedLowISR(void) {
_asm goto yourLowPriorityISRCode _endasm
}
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma interruptlow yourLowPriorityISRCode
void yourLowPriorityISRCode(void) {
// check which int flag is set
// service int
// clear int flag
// etc.
} // return will be a "retfie"
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma code REMAPPED_RESET_VECTOR = 0x1000
void _reset(void) {
_asm goto _startup _endasm
}
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////
void main(void) {
USBInit(); // in USBFunctions.c
yourInit(); // in this file
while(1) {
USBTasks(); // in USBFunctions.c
yourTasks(); // in this file
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void yourInit(void) {
// until we have configured timers and related functionality, turn timers off
T1CONbits.TMR1ON = 0; // timer 1 off
// config output pins, pin #
TRISDbits.TRISD7 = 0;
TRISDbits.TRISD6 = 0; // 10
TRISDbits.TRISD5 = 0;
TRISDbits.TRISD4 = 0; // 10
TRISCbits.TRISC7 = 0;
TRISCbits.TRISC6 = 0; // 10
PWM1 = 0;
PWM2 = 0;
PWM3 = 0;
PWM4 = 0;
PWM5 = 0;
PWM6 = 0;
RCONbits.IPEN = 1; // enable priority level on interrupts
INTCONbits.GIE = 1; // enable high-priority interrupts
// timer 1 config
PIE1bits.TMR1IE = 1; // enable timer 1 overflow interrupt
IPR1bits.TMR1IP = 1; // timer 1 overflow interrupt priority set to high
T1CONbits.T1CKPS1 = 0; // timer 1 prescale 1:2
T1CONbits.T1CKPS0 = 1; //
T1CONbits.T1OSCEN = 0; // turn off separate oscillator that is internal to timer 1
T1CONbits.TMR1CS = 0; // use internal clock to increment timer 1
// end timer 1 config
T1CONbits.TMR1ON = 1; // timer 1 on
}
void yourTasks(void) {
if(g_USBDeviceState == CONFIGURED_STATE) {
receiveViaUSB(); // read into input buffer
// process inputs here (check g_fromHostToDeviceBuffer[x])
// set outputs here (set g_fromDeviceToHostBuffer[x])
// sendViaUSB();
// we call the DC motor function directly,
// note that the interrupts will call the servo and stepper functions
}
}
void servoControl(void) {
if(g_USBDeviceState == CONFIGURED_STATE) { // if USB connection . . .
commandServoToAngle2(g_fromHostToDeviceBuffer[1]); // command servo to angle specified by USB input buffer
commandServoToAngle3(g_fromHostToDeviceBuffer[2]);
commandServoToAngle4(g_fromHostToDeviceBuffer[3]);
commandServoToAngle5(g_fromHostToDeviceBuffer[4]);
commandServoToAngle6(g_fromHostToDeviceBuffer[5]);
commandServoToAngle1(g_fromHostToDeviceBuffer[6]);
} else { // else if no USB connection . . .
// command servo to angle specified by input pot
}
}
void commandServoToAngle2(BYTE angle) {
int i;
int servo_delay;
servo_delay = ((int)((float)angle*4.71));
// now we begin servo pulse high, pulse times are:
// 1.0 ms => servo at 0 deg
// 1.5 ms => servo at 90 deg
// 2.0 ms => servo at 180 deg
PWM2 = 1;
// turn RB4 on, begin pulse high
for(i=-120; i<servo_delay; i++) {
Delay10TCY(); // note TCY = 0.083333us, this call will delay 0.083333us * 10 = 0.83333us
}
PWM2 = 0;
// turn RB4 off, end pulse high
}
void commandServoToAngle3(BYTE angle) {
int i;
int servo_delay;
servo_delay = ((int)((float)angle*37.68));
// now we begin servo pulse high, pulse times are:
// 1.0 ms => servo at 0 deg
// 1.5 ms => servo at 90 deg
// 2.0 ms => servo at 180 deg
PWM3 = 1;
// turn RB4 on, begin pulse high
for(i=-120; i<servo_delay; i++) {
Delay10TCY(); // note TCY = 0.083333us, this call will delay 0.083333us * 10 = 0.83333us
}
PWM3 = 0;
// turn RB4 off, end pulse high
}
void commandServoToAngle4(BYTE angle) {
int i;
int servo_delay;
servo_delay = ((int)((float)angle*4.71));
// now we begin servo pulse high, pulse times are:
// 1.0 ms => servo at 0 deg
// 1.5 ms => servo at 90 deg
// 2.0 ms => servo at 180 deg
PWM4 = 1;
// turn RB4 on, begin pulse high
for(i=-120; i<servo_delay; i++) {
Delay10TCY(); // note TCY = 0.083333us, this call will delay 0.083333us * 10 = 0.83333us
}
PWM4 = 0;
// turn RB4 off, end pulse high
}
void commandServoToAngle5(BYTE angle) {
int i;
int servo_delay;
servo_delay = ((int)((float)angle*4.71));
// now we begin servo pulse high, pulse times are:
// 1.0 ms => servo at 0 deg
// 1.5 ms => servo at 90 deg
// 2.0 ms => servo at 180 deg
PWM5 = 1;
// turn RB4 on, begin pulse high
for(i=-120; i<servo_delay; i++) {
Delay10TCY(); // note TCY = 0.083333us, this call will delay 0.083333us * 10 = 0.83333us
}
PWM5 = 0;
// turn RB4 off, end pulse high
}
void commandServoToAngle6(BYTE angle) {
int i;
int servo_delay;
servo_delay = ((int)((float)angle*4.71));
// now we begin servo pulse high, pulse times are:
// 1.0 ms => servo at 0 deg
// 1.5 ms => servo at 90 deg
// 2.0 ms => servo at 180 deg
PWM6 = 1;
// turn RB4 on, begin pulse high
for(i=-120; i<servo_delay; i++) {
Delay10TCY(); // note TCY = 0.083333us, this call will delay 0.083333us * 10 = 0.83333us
}
PWM6 = 0;
// turn RB4 off, end pulse high
}
void commandServoToAngle1(BYTE angle) {
int i;
int servo_delay;
servo_delay = ((int)((float)angle*4.71));
// now we begin servo pulse high, pulse times are:
// 1.0 ms => servo at 0 deg
// 1.5 ms => servo at 90 deg
// 2.0 ms => servo at 180 deg
PWM1 = 1;
// turn RB4 on, begin pulse high
for(i=-120; i<servo_delay; i++) {
Delay10TCY(); // note TCY = 0.083333us, this call will delay 0.083333us * 10 = 0.83333us
}
PWM1 = 0;
// turn RB4 off, end pulse high
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
///////////////////////////////////////////////////////////////////////////////////////////////////
namespace USBMotorController {
/////////////////////////////////////////////////////////////////////////////////////////////////
public partial class Form1 : Form {
// constants //////////////////////////////////////////////////////////////////////////////////
// member variables ///////////////////////////////////////////////////////////////////////////
public USBClass USBObject;
int p = 0;
///////////////////////////////////////////////////////////////////////////////////////////////
public Form1() {
InitializeComponent();
USBObject = new USBClass();
}
///////////////////////////////////////////////////////////////////////////////////////////////
private void Form1_Load(object sender, EventArgs e) {
attemptUSBConnectionFrontEnd(); // attempt USB connection
}
///////////////////////////////////////////////////////////////////////////////////////////////
private void lblInfo_Click(object sender, EventArgs e) {
if (USBObject.connectionState == USBClass.CONNECTION_NOT_SUCCESSFUL)
{ // verify not already connected . . .
attemptUSBConnectionFrontEnd(); // then attempt to connect again
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void attemptUSBConnectionFrontEnd()
{
lblInfo.Text = "connecting . . . ";
USBObject.connectionState = USBObject.attemptUSBConnection(); // attempt to connect to USB board
if (USBObject.connectionState == USBClass.CONNECTION_SUCCESSFUL)
{ // if connection was successful
lblInfo.BackColor = System.Drawing.Color.LimeGreen;
lblInfo.Text = "connection successful";
tmrUSB.Enabled = true;
}
else if (USBObject.connectionState == USBClass.CONNECTION_NOT_SUCCESSFUL)
{ // else if connection was not successful
lblInfo.BackColor = System.Drawing.Color.Red;
lblInfo.Text = "connection not successful, click here to try again";
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
private void tmrUSB_Tick(object sender, EventArgs e) {
// USBObject.receiveViaUSB();
USBObject.fromHostToDeviceBuffer[1] = (byte)tbServo.Value;
USBObject.fromHostToDeviceBuffer[2] = (byte)trackBar1.Value;
USBObject.fromHostToDeviceBuffer[3] = (byte)trackBar2.Value;
USBObject.fromHostToDeviceBuffer[4] = (byte)trackBar3.Value;
USBObject.fromHostToDeviceBuffer[5] = (byte)trackBar4.Value;
USBObject.fromHostToDeviceBuffer[6] = (byte)trackBar5.Value;
USBObject.sendViaUSB();
}
private void label1_Click(object sender, EventArgs e)
{
label1.Text = USBObject.fromHostToDeviceBuffer[1].ToString();
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
} // end class
} // end namespace
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?