历史上的今天
今天是:2024年11月11日(星期一)
2019年11月11日 | 直流有刷伺服控制系统(pic单片机,pid控制)
2019-11-11 来源:51hei
基于PIC18系列单片机的直流有刷伺控制系统:(来处于国外贴)
1:原理图(PDF)
2:原理图及PCB图(EAGLE)
3:带pid + 编码器的控制程序。main.c
电路原理图如下:
单片机源程序如下:
// Vertical motor driver code
// Oringially made by Kevin Wolfe 2009-2011
// Modified by Matt Moses 2010-2011
//
#include //#include //#include //#include #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
史海拾趣
|
要求:按下开关灯亮,断开开关灯灭。 我用switch语句,按下开关灯亮了,可断开开关灯就是不灭,我改了n次了它还是不灭,我已经拿它没办法了,求哥哥们给个C语言的程序,谢谢! 比如:按k1,led1亮;按k2,led2与led3亮;按 ...… 查看全部问答> |
|
CE5下怎么基于现有BSP复制出一个新的BSP(名称不同),并且能够在新BSP上建立新的CE工程,要些改什么地方? CE5下怎么基于现有BSP复制出一个新的BSP(名称不同),并且能够在新BSP上建立新的CE工程,要些改什么地方?… 查看全部问答> |
|
从网上找了个sqlite3.exe,就这一个文件, 直接双击,就是sqlite> 在网上查了一下,建库有好多的方法,什么$,sqlite3 xxx.db等, 执行就报sql error。 直接create table .....OK。 insert .......OK。 .exit以后再打开sqlite3.exe时,刚才建 ...… 查看全部问答> |
|
内存控制器和mmu有什么区别? 现在接触davinci系列处理器,其中包含arm926、vpss(主要用于视频处理)、dsp 这些东西都在内存控制器之下工作,而mmu只在arm端有,想问是内存控制器是在arm内还是另外在片内独立的一个东西,而mmu和内存控制器有什么 ...… 查看全部问答> |
|
用modelsim 6.5仿真为什么会报下面的错误?请高手指教 vsim work.vtf_test# vsim work.vtf_test # Loading work.vtf_test(fast)# Loading work.modelsim_test(fast)# Loading work.maxii_io(fast)# Loading work.maxii_lcell(fast)# Loading work. ...… 查看全部问答> |




