历史上的今天

今天是:2024年11月11日(星期一)

正在发生

2019年11月11日 | 直流有刷伺服控制系统(pic单片机,pid控制)

发布者:CyberJolt 来源: 51hei关键字:直流有刷  伺服控制系统  pic单片机  pid控制 手机看文章 扫描二维码
随时随地手机看文章

基于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

[1] [2] [3] [4] [5]
关键字:直流有刷  伺服控制系统  pic单片机  pid控制 引用地址:直流有刷伺服控制系统(pic单片机,pid控制)

上一篇:dsPIC30F6015控制AD7715程序源码 亲测可用
下一篇:PIC18读取SD卡示例PIC18 SD BMP Reader源码

推荐阅读

  多个可乐瓶环绕,扫地机器人灵巧地穿梭其中清除杂物,没有触碰到任何一个障碍物。这是在上海国家会展中心5号馆Neato的展台前可以看到的场景。   “目前,市场上的扫地机器人大多是靠碰撞的方式探测前方物体,可能会对家具、家电等造成损坏。我们的扫地机器人应用汽车技术,克服了这个缺点。重要的是,它们能够清理屋内的微小尘埃,非常适合北方居...
联发科与台积电今日共同宣布,采用台积电12纳米制程技术生产的业界首颗8K数字电视系统单芯片MediaTek S900已经进入量产。S900芯片采用台积电低功耗12纳米鳍式场效晶体管(FinFET)精简型(12FFC)技术生产。联发科副总经理暨制造本部总经理高学武对此表示,全球8K电视需求日趋强劲,本次与台积电针对支持8K电视芯片的先进技术合作,有利于推动高端智能电...
Keilc课程设计成绩评定表学生姓名贾超班级学号140302*专 业测控课程设计题目八位竞赛抢答器的设计评语组长签字:成绩日期 2017年 月 日课程设计任务书学 院自动化与电气工程专 业测控技术与仪器学生姓名贾超班级学号1403020313课程设计题目八位竞赛抢答器的设计实践教学要求与任务:通过本课程设计使学生进一步巩固《KeilC程序设计》...
整合STM32 MCU的低功耗、高性能和安全性与Sierra Wireless 的弹性的全球蜂窝物联网接入和边缘设备上云方案,简化物联网设备部署中国,2021 年11月11日-- 服务多重电子应用领域的全球半导体领导者意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)和全球领先的物联网服务提供商Sierra Wireless宣布了一项合作协议,让STM32微控制器(M...

史海拾趣

问答坊 | AI 解惑

PROTUES仿真实例

非常好的PROTEUS的实例,供分享…

查看全部问答∨

超声波测距的程序

#include <reg51.h> #define uchar unsigned char #define uint unsigned int #define ulong unsigned long extern void cs_t(void); extern void delay(uint); extern void display(); data uchar testok; data ulong time,num; ucha ...…

查看全部问答∨

单片机教程【2】蜂鸣器

$(\'swf_R48\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/sid/30387538/v.swf\'), ...…

查看全部问答∨

at80c51应该怎样烧写程序?用什么烧写器?

想做个at80c51的板子,但是不知道用什么烧写器,不知道怎样烧写程序,谁能告诉我一些,或者告诉我怎样制作at80c51的烧写器,或者是买什么样的烧写器,怎样和单片机连接上,谢谢的哦!急!!…

查看全部问答∨

SqlCeRemoteDataAccess问题

下面代码是复制Microsoft网站上改的 [url=http://msdn.microsoft.com/zh-cn/library/system.data.sqlserverce.sqlceremotedataaccess(VS.80).aspx][/url] // Connection String to the SQL Server            ...…

查看全部问答∨

哪种SDRAM 是64M BYTE?

S3C2440的开发板,原带32M BYTE * 2 的内存。想扩大到64M BYTE * 2,请问哪家公司提供64M的SDRAM, 什么型号?SAMSUNG的SDRAM不想再用了…

查看全部问答∨

关于桌面目录下的desktop.ini文件

desktop.ini ===================== [.ShellClassInfo] LocalizedResourceName=@\\Windows\\ceshell.dll,-20480 [LocalizedFileNames] My Documents.lnk=@\\Windows\\ceshell.dll,-20486 ============== ...…

查看全部问答∨

我刚有了一个面试,给我留了个作业。哪位能帮帮我?

我刚有了一个面试,给我留了个作业。哪位能帮帮我?我的工作就有希望了 写已小段程序 TI MSP430Fxxx 1) 用中断控制 2) 在P1.0产生一个连续的 1KHz 变占空比的输出 3) 占空比由P1.1 P1.2 P1.3 控制如下   P1.1     & ...…

查看全部问答∨

单片机控制箱体升温??

单片机控制一个箱子里的温度,用什么器件去升温呢??5V ,12v的优先考虑了,求建议!!…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved