久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
直流有刷伺服控制系統(pic單片機,pid控制)
[打印本頁]
作者:
ynweseraph
時間:
2018-3-15 09:39
標題:
直流有刷伺服控制系統(pic單片機,pid控制)
基于PIC18系列單片機的直流有刷伺控制系統:(來處于國外貼)
1:原理圖(PDF)
2:原理圖及PCB圖(EAGLE)
3:帶pid + 編碼器的控制程序。main.c
0.png
(47.16 KB, 下載次數: 94)
下載附件
2018-3-15 15:32 上傳
電路原理圖如下:
0.png
(89.25 KB, 下載次數: 74)
下載附件
2018-3-15 15:33 上傳
單片機源程序如下:
// Vertical motor driver code
// Oringially made by Kevin Wolfe 2009-2011
// Modified by Matt Moses 2010-2011
//
#include <p18f1320.h>
//#include <stdlib.h>
//#include <delays.h>
//#include <math.h>
#define counterToSpeedScalar 150
#define numCountsPerStep 1
#define maxSpeed 255
#define Kp 35.0
#define Kd 0.0
#define Ki 0.0
#define dt 0.01
#define speedStep 1
#define errorTol 1
#define tempADSpeed 255
#define stepHomeThreshold 500
#define upTorqueLimit 150
#define downTorqueLimit -120
#pragma config IESO = ON
#pragma config FSCM = ON
#pragma config OSC = INTIO2
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config MCLRE = OFF
/****** DISABLE LVP (LOW-VOLTAGE Programming) ******/
/* This allows RB5 to operate as an interuppt on change I/O pin */
#pragma config LVP = OFF
/***************************************************/
void low_isr (void);
void high_isr (void);
void set_motor_output (unsigned char desiredPWM, unsigned char desiredDirection);
#pragma code high_vector_section=0x8
void high_vector (void)
{
_asm GOTO high_isr _endasm
}
#pragma code
#pragma code low_vector_section=0x18
void low_vector (void)
{
_asm GOTO low_isr _endasm
}
#pragma code
volatile int stepHighCounter = 0;
volatile char stepPulses = 0;
//volatile int stepCounts;
volatile int currentCounter = 0;
//volatile unsigned char currentADvalue;
volatile unsigned char trigger = 0;
//volatile structPrevStates prevStates;
//volatile enum { DIR_CW = 0, DIR_CCW = 1 } direction;
volatile enum { LOW = 0, HIGH = 1} prevA = LOW;
// changeToggle is a varb used for debugging
volatile enum {LOW = 0, HIGH = 1} changeToggle;
#pragma interrupt high_isr
void high_isr(void)
{
if ( INTCONbits.INT0IF ) //step pulse flag
{
// reset stepTimerFoo
stepHighCounter = 1;
// do important stuff
if ( PORTBbits.RB1 ) //Check direction pin
{
stepPulses++;
}
else
{
stepPulses--;
}
INTCONbits.INT0IF = 0; //reset step flag
}
if ( INTCONbits.RBIF ) //PORTB change interrupt
{
// // This is a little block for debugging - toggles A every time a change on PORTB
//
// if (changeToggle) {
// changeToggle = 0;
// PORTAbits.RA1 = 0;
// }
// else {
// changeToggle = 1;
// PORTAbits.RA1 = 1;
// }
if ( PORTBbits.RB5^prevA ) //CW Rotation
{
currentCounter++;
//PORTAbits.RA1 = 0;
}
else //CCW Rotation
{
currentCounter--;
//PORTAbits.RA1 = 1;
// if (changeToggle) {
// changeToggle = 0;
// PORTAbits.RA1 = 0;
// }
// else {
// changeToggle = 1;
// PORTAbits.RA1 = 1;
// }
}
prevA = PORTBbits.RB4;
PORTAbits.RA1 = PORTBbits.RB5;
INTCONbits.RBIF = 0; //resetQuadFlag
}
}
#pragma interruptlow low_isr
void low_isr(void) //timer interupt
{
trigger = 1;
INTCONbits.TMR0IF = 0; // reset TMR0 interrupt flag
}
void set_motor_output(unsigned char desiredPWM, unsigned char desiredDirection)
{
if ( desiredDirection )
{
PORTBbits.RB2 = 0;
CCPR1L = desiredPWM; // This is the register for the 8 MSB of the PWM pin RB3.
}
else
{
PORTBbits.RB2 = 1;
CCPR1L = (desiredPWM ); // This is the register for the 8 MSB of the PWM pin RB3.
}
}
long abs(long i)
{
if (i < 0)
return -i;
else
return i;
}
char sgn(long i)
{
if (i < 0)
return -1;
else if (i > 0)
return 1;
else
return 0;
}
void main (void)
{
long prevCounter = 0;
unsigned char tempTrigger = 0;
char tempStepPulses = 0;
long tempCurrentCounter = 0;
unsigned char currentADvalue = tempADSpeed;
long desiredCounter = 0;
long error = 0;
long prevError = 0;
long velocity = 0;
float integral = 0.0;
float derivative = 0.0;
long output = 0;
char testState = 0;
long testCounter = 0;
char homeFlag = 0;
enum { LOW = 0, HIGH = 1} homeDir = LOW;
/*************** SETUP INTERRUPTS ******************/
INTCONbits.GIEH = 0; // Temporarily disable global interrupts
INTCONbits.GIEL = 0; // Temporarily disable peripheral interrupts
INTCONbits.TMR0IE = 1; // Enable TMR0 Overflow interrupt
INTCONbits.INT0IE = 1; // Enable external interrupt on INT0/RB0
INTCONbits.RBIE = 1; // Enable Port B change interrupt
//INTCON2bits.RBPU = 0; // Enable Port B pull-ups
INTCON2bits.RBPU = 1; // Disable Port B pull-ups
INTCON2bits.INTEDG0 = 1; // Interrupt on rising edge for INT0
INTCON2bits.TMR0IP = 0; // Set TMR0 interrupt priority to Low
INTCON2bits.RBIP = 1; // Set Port B change interrupt to High
RCONbits.IPEN = 1; // Enable priority levels on interrupts
/****************************************************/
/***************** SETUP TMR0 ***********************/
//T0CONbits.TMR0ON = 0; // Temporarily disable TMR0 until the end of the setup;
T0CONbits.T08BIT = 1; // Use an 8-bit timer (1). Use a 16-bit timer (0).
T0CONbits.T0CS = 0; // Use internal clock cycles for the timer.
T0CONbits.PSA = 0; // Use prescalar to adjust overflow rate (0). Do not use prescalar (1).
/* Assign Prescalar */
T0CONbits.T0PS2 = 0;
T0CONbits.T0PS1 = 1;
T0CONbits.T0PS0 = 1;
/* This makes go slower */
//T0CONbits.T0PS2 = 1;
//T0CONbits.T0PS1 = 1;
//T0CONbits.T0PS0 = 1;
T0CONbits.TMR0ON = 1;
/***************************************************/
/************** SETUP I/O PINS *********************/
TRISBbits.TRISB4 = 1; // Encoder ChA input
TRISBbits.TRISB5 = 1; // Encoder ChB input
TRISBbits.TRISB6 = 0; // Set as output to avoid Port B interrupt on change
TRISBbits.TRISB7 = 0; // Set as output to avoid Port B interrupt on change
TRISBbits.TRISB0 = 1; // Step pulse input
TRISBbits.TRISB1 = 1; // Direction input
//TRISAbits.TRISA4 = 0; // Possible motor output pin RA4
TRISAbits.TRISA0 = 1; // Set RA0 as input for SPEED pin (analog input for A/D)
TRISAbits.TRISA1 = 0; // Set RA1 as output for diagnostic LED
//ADCON0bits.VCFG0 = 0; // Set A/D to External Vref(+/-) using 1 and 1
//ADCON0bits.VCFG1 = 0; // Set A/D to Vss and Vdd references using 0 and 0
/***************************************************/
/**************** SETUP A/D ************************/
/* Configure analog and digital pins */
ADCON1bits.PCFG0 = 1; // Set AN0 port as digital input (Home switch)
ADCON1bits.PCFG1 = 1; // RA1/AN1 diagnostic LED
ADCON1bits.PCFG2 = 1; // Reserved - test pad on AN2
ADCON1bits.PCFG3 = 1; // Reserved - test pad on AN3
ADCON1bits.PCFG4 = 1; // Set AN4/RB0 as a digital pin (Step pulse input)
ADCON1bits.PCFG5 = 1; // Set AN5/RB1 as a digital pin (Direction input)
ADCON1bits.PCFG6 = 1; // Set AN6/RB4 as a digital pin (ChA input)
//
// /* Select A/D input channel as AN0 */
// ADCON0bits.CHS0 = 0;
// ADCON0bits.CHS1 = 0;
// ADCON0bits.CHS2 = 0;
//
// /* Set A/D clock as Fosc/2 */
// ADCON2bits.ADCS0 = 0;
// ADCON2bits.ADCS1 = 0;
// ADCON2bits.ADCS2 = 0;
//
// ADCON2bits.ADFM = 0; // Left justify A/D conversion so only the 8 MSB are read later
//
// /* Turn on A/D module */
// ADCON0bits.ADON = 1;
/* Turn off A/D module */
ADCON0bits.ADON = 0;
/***************************************************/
/**************** SETUP PWM ************************/
/* Configure PWM pins P1A and P1B as inputs. */
TRISBbits.TRISB3 = 1;
TRISBbits.TRISB2 = 1;
/* Use PR2 to set the PWM period */
PR2 = 0xFF;
// Equation 15-1 PWM Period = [(PR2 + 1)] * 4 * TOSC * TMR2 Prescaler
// or about 1 / 490Hz
/* Set PWM Mode with P1A as a single modulated output */
CCP1CONbits.CCP1M0 = 0;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.P1M0 = 0;
CCP1CONbits.P1M1 = 0;
/* LSB of the PWM duty cycle */
CCP1CONbits.DC1B1 = 0;
CCP1CONbits.DC1B0 = 0;
/* MSB of the PWM duty cycle */
CCPR1L = 0x00;
/* Configure TMR2 */
PIR1bits.TMR2IF = 0; // Clear interupt flag for TMR2 equal to PR2
T2CONbits.T2CKPS1 = 1; // Set prescaler to 16 to decrease PWM frequency
T2CONbits.T2CKPS0 = 1;
T2CONbits.TMR2ON = 1; // Turn on Timer2
/* Wait for the TMR2IF flag go high before procedding */
while (!(PIR1bits.TMR2IF))
{
int temp = 0;
}
/* Set the PWM pins P1A and P1B as outputs. */
TRISBbits.TRISB3 = 0;
TRISBbits.TRISB2 = 0;
ECCPASbits.ECCPASE = 0;
/*****************************************************/
/***************** SET OSC SPEED *********************/
//OSCCONbits.IRCF0 = 1;
//OSCCONbits.IRCF1 = 1;
//OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF0 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF2 = 1;
/*****************************************************/
// This line is part of the initial check sequence and is not
// needed for normal operation:
desiredCounter = 0;
trigger = 0;
stepPulses = 0;
currentCounter = 0;
set_motor_output( 0, 0 );
/****************** ENABLE INTERRUPTS *****************/
INTCONbits.GIEH = 1; // Enable global interrupts
INTCONbits.GIEL = 1; // Enable peripheral innterupts
/******************************************************/
while (1)
{
INTCONbits.GIEH = 0;
tempTrigger = trigger;
INTCONbits.GIEH = 1;
if ( tempTrigger )
{
INTCONbits.GIEH = 0;
trigger = 0;
tempCurrentCounter = currentCounter;
tempStepPulses = stepPulses;
stepPulses = 0;
// Check if step pin has been held HIGH. If it has been held HIGH
// long enough to indicate a HOME command, set home flag, otherwise
// just increment stepHighCounter. stepHighCounter gets reset in
// in interrupt routine that reads step and direction lines.
if (stepHighCounter) {
if (stepHighCounter > stepHomeThreshold) {
homeFlag = 1;
stepHighCounter = 0;
homeDir = PORTBbits.RB1; //set home direction to direction input pin
}
else {
if (PORTBbits.RB0) {
stepHighCounter++;
}
}
}
//stepTimerFoo++;
//tempStepTimerFoo = stepTimerFoo;
INTCONbits.GIEH = 1;
// if tempStepTimerFoo > something
// then set homeFlag, set homeDir
// if homeflag
// if homeswitch
// turn off homing
// else
// set motor go to home in homeDir direction
// end
//else
// do normal motor control
//end
/*
INTCONbits.GIEH = 0;
trigger = 0;
INTCONbits.GIEH = 1;
//if (PORTAbits.RA1)
// PORTAbits.RA1 = 0;
//else
// PORTAbits.RA1 = 1;
INTCONbits.GIEH = 0;
tempCurrentCounter = currentCounter;
tempStepPulses = stepPulses;
stepPulses = 0;
INTCONbits.GIEH = 1; */
// velocity = (tempCurrentCounter - prevCounter)*counterToSpeedScalar;
// prevCounter = tempCurrentCounter;
// Uncomment this for normal operation
desiredCounter = desiredCounter + (tempStepPulses*numCountsPerStep);
if (homeFlag) // If we are in homing mode
{
if (PORTAbits.RA0) // if homeswitch is ON
{
// We're home!
set_motor_output(0,0);
homeFlag = 0;
desiredCounter = 0;
// turn off interrupts to clear sensitive variables
INTCONbits.GIEH = 0;
currentCounter = 0;
INTCONbits.GIEH = 1;
}
else // if homeswitch is OFF - we are still going home
{
if (homeDir) // going up
{
set_motor_output(abs(upTorqueLimit),1);
}
else // going down
{
set_motor_output(abs(downTorqueLimit), 0);
}
}
}
else
{
error = desiredCounter - tempCurrentCounter;
output = Kp * error;
////////////// Set motor output //////////////////////////////
//
// The variable "output" controls voltage to motor. Examples:
//
// this makes the motor go up:
// set_motor_output(30,1);
//
// this makes the motor go down:
// set_motor_output(30,0);
//
if (output <= 0)
{
if (output < downTorqueLimit)
{
output = downTorqueLimit;
}
set_motor_output(abs(output),0);
}
else
{
if (output > upTorqueLimit)
{
output = upTorqueLimit;
}
set_motor_output(abs(output),1);
}
}
}
}
}
復制代碼
Partlist
Exported from singleAxisMotor3.sch at 2/16/2014 12:03:57 PM
EAGLE Version 6.5.0 Copyright (c) 1988-2013 CadSoft
Assembly variant:
Part Value Device Package Library Sheet
C1 0.1uF C-USC1206 C1206 rcl 1
C2 0.1uF C-USC1206 C1206 rcl 1
C3 0.1uF C-USC1206 C1206 rcl 1
C4 0.1uF C-USC1206 C1206 rcl 1
C5 10.0uF C-US025-024X044 C025-024X044 rcl 1
C6 10.0uF C-USC1206 C1206 rcl 1
C7 10.0uF C-USC1206 C1206 rcl 1
C8 1000uF C-US025-024X044 C025-024X044 rcl 1
C9 1.0uF C-USC1206 C1206 rcl 1
C10 10nF C-USC1206 C1206 rcl 1
C11 10nF C-USC1206 C1206 rcl 1
IC2 7805L 7805L TO92 linear 1
IC3 40106D 40106D SO14 40xx 1
IC4 PIC18F1320_18PIN_DIP PIC18F1320_18PIN_DIP SO-18W modular_robot_parts 1
JP1 PIC_KIT_2_CONN PIC_KIT_2_CONN PIC_KIT_2_CONN modular_robot_parts 1
JP2 PINHD-2X4 2X04 pinhead 1
LED1 LEDCHIPLED_1206 CHIPLED_1206 led 1
P1 3PIN 3PIN 3PIN custom 1
R1 1k R-US_0207/2V 0207/2V rcl 1
R2 100k R-US_0207/2V 0207/2V rcl 1
R3 1k R-US_0207/2V 0207/2V rcl 1
R4 100k R-US_0207/2V 0207/2V rcl 1
R5 330 R-US_0207/2V 0207/2V rcl 1
R6 330 R-US_0207/2V 0207/2V rcl 1
R7 1k R-US_0207/2V 0207/2V rcl 1
R8 1k R-US_0207/2V 0207/2V rcl 1
R9 330 R-US_0207/2V 0207/2V rcl 1
R10 1k R-US_M1206 M1206 rcl 1
R11 2.7k R-US_M1206 M1206 rcl 1
R12 10k R-US_M1206 M1206 rcl 1
R13 10k R-US_M1206 M1206 rcl 1
TP1 1PAD 1PAD 1PAD custom 1
TP2 1PAD 1PAD 1PAD custom 1
TP3 1PAD 1PAD 1PAD custom 1
TP4 1PAD 1PAD 1PAD custom 1
TP5 1PAD 1PAD 1PAD custom 1
U1 LMD18200 LMD18200 TO-220-WIDE custom 1
X1 22-23-2021 22-23-2021 22-23-2021 con-molex 1
X2 22-23-2041 22-23-2041 22-23-2041 con-molex 1
所有資料51hei提供下載:
SingleAxisEmulator-master.zip
(282.84 KB, 下載次數: 42)
2018-3-15 09:39 上傳
點擊文件名下載附件
直流有刷伺服控制系 統
下載積分: 黑幣 -5
歡迎光臨 (http://m.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
丁香午夜
|
日韩免费一区二区
|
日韩一级av毛片
|
免费av大片
|
日韩中文字幕精品
|
欧美日批视频
|
狠狠五月
|
天天精品视频
|
久久免费视频网站
|
亚洲免费观看视频
|
国产又粗又猛又黄又爽的视频
|
国产精品成人在线
|
六月天婷婷
|
日韩精品视频在线免费观看
|
www一区
|
日本黄页视频
|
日本成片网
|
日韩精品综合
|
羞羞的视频在线观看
|
国产精品99久久久久久www
|
精品国产一区二区在线观看
|
亚洲国产天堂
|
国产免费一区二区三区免费视频
|
九九热这里
|
爱搞逼综合网
|
国产精品成人在线
|
99久久久国产精品免费蜜臀
|
激情高潮到大叫狂喷水
|
国产精品美女久久
|
日韩在线观看
|
中文字幕第7页
|
97国产精品人人爽人人做
|
国产视频一区二
|
日本精品视频在线观看
|
成人免费在线视频观看
|
国产精品久久久久久久久久久久久
|
欧美日韩精品一区
|
视频一二三区
|
亚洲三级黄色片
|
国产精品一二三四区
|
激情丁香
|