基于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
上一篇:dsPIC30F6015控制AD7715程序源码 亲测可用
下一篇:PIC18读取SD卡示例PIC18 SD BMP Reader源码
推荐阅读
史海拾趣
Altera是一家以FPGA(可编程逻辑器件)和相关技术为主的半导体公司,于1983年成立于美国加利福尼亚州的圣塔克拉拉。以下是关于Altera公司发展的五个相关故事:
成立与早期发展:Altera公司由Robert Hartmann和Michael Magranet等人创立,最初以设计和制造EEPROM(可擦除可编程只读存储器)为主。1984年,Altera推出了全球第一个可编程逻辑器件EP300系列,开创了FPGA行业。随后,Altera不断扩大产品线,致力于FPGA技术的研发和推广。
FPGA技术创新:Altera在FPGA技术方面持续进行创新,推出了一系列新产品和技术。1992年,公司推出了第一个基于SRAM(静态随机存储器)的FPGA器件,从而实现了更高的速度和灵活性。随后,Altera不断改进器件结构、设计工具和软件支持,提高了产品性能和用户体验。
与竞争对手的竞争:在FPGA市场,Altera与Xilinx是两大竞争对手。两家公司在技术、产品性能、市场份额等方面展开激烈竞争。为了在市场上取得优势,Altera不断加大研发投入,推出了更具竞争力的产品,并积极开展营销和销售活动。
收购与合并:Altera在发展过程中进行了一系列收购与合并,以扩大市场份额和提升技术实力。2015年,英特尔公司以约160亿美元的价格收购了Altera,将其并入英特尔旗下,成为英特尔的子公司。这一收购使英特尔获得了Altera在FPGA领域的技术优势和市场份额,进一步巩固了英特尔在半导体行业的领先地位。
公司发展与创新:作为英特尔的子公司,Altera继续发展和创新。公司不仅致力于FPGA技术的进一步改进和推广,还在其他领域进行探索和拓展,如数据中心、人工智能、物联网等。Altera不断推出新产品和解决方案,满足不同行业和应用领域的需求,保持了在半导体行业的竞争优势。
以上是关于Altera公司发展的五个相关故事,这些故事展示了Altera从成立初期到被英特尔收购的发展历程,以及其在FPGA技术领域的技术创新、市场竞争和业务拓展等方面的重要进展。
近年来,随着电子信息技术的快速发展和智能化趋势的加剧,东晶电子也面临着新的机遇和挑战。为了适应市场变化和满足客户需求,公司开始实施战略转型和升级。公司加大了对新型电子元器件的研发力度,推动产品向微型化、功能化、高精度方向发展。同时,公司还积极开拓新领域和新市场,拓展业务范围和市场份额。这些举措为公司未来的发展奠定了坚实的基础。
请注意,这些故事是基于已知信息的概括性描述,并非具体的历史事件。在实际情况中,东晶电子的发展历程可能更加复杂和多样化。
在电子配件领域,Hama始终保持着对技术创新的追求。公司不断投入研发资源,推出了一系列具有自主知识产权的高精度、高可靠性的检测仪表产品,如激光测距仪、激光柜位计等,广泛应用于钢铁、矿山、化工等行业。这些创新产品不仅满足了客户的多样化需求,也提升了生产效率和产品质量,赢得了市场的广泛认可。同时,Hama还积极拓展国际市场,产品出口到欧洲、美洲、亚洲等多个国家和地区,进一步提升了其国际影响力。
DAICO公司成立于XXXX年,最初是一家位于加利福尼亚的小型私营公司。在公司成立的初期,DAICO专注于研发和生产中频/射频和微波控制产品,以及放大器。这些产品主要用于国防电子和航空航天领域,为DAICO在电子行业中打下了坚实的基础。
DAICO公司成立于XXXX年,最初是一家位于加利福尼亚的小型私营公司。在公司成立的初期,DAICO专注于研发和生产中频/射频和微波控制产品,以及放大器。这些产品主要用于国防电子和航空航天领域,为DAICO在电子行业中打下了坚实的基础。
随着产品质量的不断提升和市场口碑的积累,Accetek公司开始积极拓展国内外市场。公司参加了多个国际电子展览和交流活动,与全球多家知名企业建立了合作关系。同时,公司还加强了品牌建设和市场推广工作,通过广告宣传、媒体合作等方式提高品牌知名度和美誉度。这些举措有效地提升了公司的市场竞争力,为公司的快速发展提供了有力支持。
$(\'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的烧写器,或者是买什么样的烧写器,怎样和单片机连接上,谢谢的哦!急!!… 查看全部问答∨ |
下面代码是复制Microsoft网站上改的 [url=http://msdn.microsoft.com/zh-cn/library/system.data.sqlserverce.sqlceremotedataaccess(VS.80).aspx][/url] // Connection String to the SQL Server ...… 查看全部问答∨ |
S3C2440的开发板,原带32M BYTE * 2 的内存。想扩大到64M BYTE * 2,请问哪家公司提供64M的SDRAM, 什么型号?SAMSUNG的SDRAM不想再用了… 查看全部问答∨ |
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 & ...… 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- 答题抽奖:Mentor Tessent Automotive相关测试解决方案(奖品池还剩不少奖品哟)
- 动手学电源第一季:DIY 小风扇,Fan一夏!
- 智能云锁哪家强?TI市场和技术大咖邀你1月16日10:00直播间畅聊
- 直播已结束【TI MSPM0应用详解:个人电子、楼宇自动化和医疗】
- 观看福禄克计量校准视频 参与调查问卷好礼送!
- EEWorld邀你来拆解(第四期):热门充电宝大拆解
- 极简主义,足不出户,看东芝在线展会,安心答题送好礼!
- 有奖问答 | MPS汽车技术进阶之旅——ADAS站
- 为你点赞——我最爱有“干货”的博文
- 【直播已结束】一起深挖 TI 新发布的 Robotics SDK,看干货直播赢好礼!