版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、/*注意:由于本程序要用到看门狗对单片机进行复位,故运行本程序时一定要打开看门狗。 同时选择振荡器为HS*/#include <pic.h>#include <stdio.h>#include <stdlib.h>#define VOLOFFL 0X92/*设定31.5V为低压保护动作电压*/#define VOLONL 0X99/*设定33V为低压保护恢复电压*/#define CURB 0X0004B/*电流环比例系数KP*/#define CURA 0X00050/*电流环比例系数KI+KP*/#define TH 0X32000/*电流环的限幅输出*
2、/#define FULLDUTY 0XFF/*PWM占空比为1*/ #define TSON 0X27/*刹车时的调速手柄复位条件 TS<=1.5V*/#define SPELOW 0/*电机转速为0*/#define TSHOFF 0X38/*调速手柄电压为1.1V时的采样值*/#define GSPEHI1 0X65/*最大转速给定*/#define GSPEHI2 0XCA#define SPEB1 0X004E/*转速环比例系数KP*/#define SPEA1 0X0050/*转速环比例系数KP+KI*/#define SPEB2 0X003E/*转速环比例系数KP*/#de
3、fine SPEA2 0X0040/*转速环比例系数KP+KI*/#define GCUR 0X3F0/*转速环限幅输出*/#define MAXCUR 0X3F/*电流环的最大给定*/#define KLSPE 0X0A/*转速闭环积分分离点*/#define KLCUR 0X030/*电流闭环积分分离点*/#define TIME_CUR 0X06/*电流采样次数*/volatile char CURGIVE;/*存储电流给定值*/volatile unsigned char COUNT;volatile unsigned char STATE1;/*存储当前电机转子位置*/volatil
4、e unsigned char OLDSTATE;/*存储上一次电机转子位置*/volatile unsigned char DELAY;volatile unsigned char SPEED;/*存储电机转速SPEED=SPECOUNT*2+TMR1H*/volatile unsigned char SPECOUNT;/*电机转速计数器*/volatile unsigned char COUNT_VOL;/*存储电池电压采样周期*/volatile int TSH;/*存储转速给定值*/volatile unsigned char TEMP1;volatile unsigned char
5、VOLTAGEH;/*存储电池电压*/volatile unsigned char COUNT_TS;/*存储调速手柄采样周期*/volatile unsigned char CURRENT8=0;/*存储电流反馈值*/volatile unsigned char COUNT_CUR;/*存储电流采样次数*/union spe volatile int X; volatile unsigned char A2;union cur volatile long Y; volatile unsigned char B4;bit REHIGH;/*低压保护动作后,电池电压重新恢复到36VREHIGH=
6、1*/bit OFF;/*刹车条件结束,OFF=1*/bit SAME;/*当前采样所得电机转子位置与前次采样所得相等时,SAME=1*/ bit SP1; /*电机转速低于50r/min,SP1=1*/bit TS;/*当前AD采样值为调速手柄,TS=1*/bit VOLTAGE;/*当前AD采样值为电池电压,VOLTAGE=1*/bit SPEPID;/*需要进行一次转速PI运算,WHENT SPEPID=1*/bit LOWPOWER;/*需要进行一次电池电压测试,LOWPOWER=1*/bit SHUTDOWN;/*刹车中断发生,SHUTDOWN=1*/bit CURPID;/*需要进
7、行一次电流PI运算,CURPID=1*/bit LOWSPEED;/*WHEN SPEED IS LOW,LOWSPEED=1*/*-电机转子位置输出表-*/const unsigned char out_table=0XAF,0XBE,0XFF,0X07E,0X0CF,0X0FF,0X0D7,0X077,0X0FF;/*-函数声明-*/void power(void);void curpi(void);void breakon(void); void interrupt interrupted(void);void sample(void);void output(void);void sp
8、epi(int, int);/*-主程序-*/main()PORTC=0XFF;/*关断逆变桥所有MOSFET*/TRISC=0X02;/*设置RC口输入输出状态*/PIR1=0;/*清所有中断标志位*/INTCON=0;/*屏蔽所有中断*/T2CON=0X01;/*关闭TMR2,置TMR2预分频为4*/CCPR1L=FULLDUTY;/*PWM输出占空比为1*/CCP1CON=0XFF;/*CCP1工作于PWM方式*/CCP2CON=0X0B;/*CCP2工作于特殊事件触发方式,用作AD采样周期寄存器*/ADCON0=0X81;/*选择AD转换时钟为32分频、AN0通道、AD转换允许*/as
9、m("CLRWDT");/*清看门狗*/TMR2=0X0;/*TMR2计数器清零*/TMR1H=0;/*TMR1计数器清零*/TMR1L=0;T1CON=0;/*TMR1预分频为1、关闭振荡器,工作于定时工作方式*/CCPR2H=0X09;/*初始化AD采样周期寄存器,T=600uS*/CCPR2L=0X60;TRISA=0XFF;/*RA口设置为模拟输入口*/TRISB=0XEF;/*RB口设置为输入*/CCP2IE=0;/*CCP2中断禁止*/ADIE=1;/*AD采样中断允许*/PR2=0XC7;/*初始化PWM频率为5KHz*/ADCON1=0X02;/*AD采样结
10、果左移,RA口引脚均为模拟输入*/TMR0=0;OPTION=0XD1;/*取消RB口弱上拉,选择INT在上升沿产生中断,TMR0 1:4*/TMR2ON=1;/*开CCP1,送出占空比为1的PWM脉冲*/REHIGH=0;/*初始化相应的标志位*/OFF=0;SP1=0;SAME=0;VOLTAGE=0;SPEPID=0;LOWPOWER=0;SHUTDOWN=0;CURPID=0;LOWSPEED=1;sample();/*确定当前转子位置*/SAME=0;output();/*根据采得状态值触发相应的MOSFET*/INTCON=0XF8;/*开总中断、外围中断、INT中断、TMR0和R
11、B口电平变化中断允许*/SPECOUNT=0;/*初始化转速计数器*/CURGIVE=0;/*转速给定为0*/SPEED=0X7F;/*初始化转速寄存器,认为当前转速为0*/COUNT_TS=0X08;/*设定调速手柄采样周期为4mS*/COUNT_VOL=0;/*设定电池端电压采样周期为1024mS*/COUNT_CUR=TIME_CUR;/*连续采样电流6次*/CURRENT7=0;/*设定采得电流得最小值为0*/CURRENT0=0XFF;/*设定采得电流得最大值为FF*/TS=1;/*设TS标志位,当前采样值为调速手柄电压值*/ADGO=1;/*开AD采样*/TMR1ON=1;/*开T
12、MR1定时器*/for(;) asm("CLRWDT");/*清看门狗*/ if(CURPID=1)/*需要进行电流PI运算?*/ curpi();/*是,进行电流PI运算*/ CURPID=0;/*清电流PI运算标志位*/ if(SPEPID=1)/*需要进行转速PI运算?*/ spepi(SPEED,TSH);/*是,进行转速PI运算*/ SPEPID=0;/*清转速PI运算标志位*/ if(LOWPOWER=1)/*需要测试电池端电压?*/ power();/*是,调用POWER子程序*/ while(REHIGH=1)/*如果REHIGH=1,进入死循环,利用看门狗
13、复位单片机*/ continue; if(SHUTDOWN=1)/*刹车中断到来?*/ breakon();/*调用刹车子程序*/ while(OFF=1)/*如果OFF1,进入死循环,利用看门狗复位单片机*/ continue; /*-转速PI运算子程序-*/void spepi(int SPEED1, int TSH1)union spe SPEEP;/*声明SPEEP为联合,用于临时存储SPEB*SPEEK*/static volatile int SPEUK=0;/*用于存储转速PI运算最终结果*/static volatile int SPEEK=0;/*用于存储转速误差*/if(L
14、OWSPEED=1) if(SP1=1)/*转速很慢?*/ SPEED1=0X7F;/*是,置SPEED1寄存器为7F*/ SPEED1=(0X7F-SPEED1);/*获取当前电机转速*/ TSH1=TSH1-TSHOFF;/*调速手柄采样值减去偏移量1.1V,获取转速给定*/ if(TSH1<0)/*转速给定小于0?*/ SPEUK=0;/*是,清转速PI输出寄存器*/ CURGIVE=0;/*PI调节器输出为0*/ return;/*返回*/ if(TSH1>=GSPEHI1)/*转速给定大于最大给定?*/ TSH1=GSPEHI1;/*是,转速给定设置为最大给定*/ SPE
15、EP.X=SPEEK*SPEB1;/*求取KP*E(K-1),其中E(K-1)为前次转速误差*/ SPEEK=TSH1-SPEED1;/*求取当前转速误差*/ SPEUK=SPEUK+SPEEK*SPEA1-SPEEP.X;/*否则进行转速PI运算*/else SPEED1=0XFE-SPEED1; TSH1=(TSH1-TSHOFF)*2; if(TSH1<0)/*转速给定小于0?*/ SPEUK=0;/*是,清转速PI输出寄存器*/ CURGIVE=0;/*PI调节器输出为0*/ return;/*返回*/ if(TSH1>=GSPEHI2)/*转速给定大于最大给定?*/ TS
16、H1=GSPEHI2;/*是,转速给定设置为最大给定*/ SPEEP.X=SPEEK*SPEB2;/*求取KP*E(K-1),其中E(K-1)为前次转速误差*/ SPEEK=TSH1-SPEED1;/*求取当前转速误差*/ SPEUK=SPEUK+SPEEK*SPEA2-SPEEP.X;/*否则进行转速PI运算*/ if(SPEUK<0)/*PI运算结果为负?*/ SPEUK=0;/*是,清SPEUK*/ CURGIVE=0;/*PI调节器输出为0*/ return;/*返回*/SPEEP.X=SPEUK;/*若SPEUK大于0,则SPEUK内容送联合SPEEP*/CURGIVE=(SP
17、EEP.A0&0xf0)|SPEEP.A1;/*对SPEUK的高、低字节处理获得PI调节器输出*/asm("SWAPF _CURGIVE,f");if(SPEUK>GCUR)/*SPEUK大于限幅值?*/ CURGIVE=MAXCUR;/*PI调节器输出限幅值*/ SPEUK=GCUR;/*输出限幅*/return;/*返回*/ /*-电流PI运算子程序-*/void curpi(void)union cur UK;/*声明UK,用于暂时存储E(K-1)*KP*/volatile static int CUREK=0;/*声明CUREK和CURUK*/vola
18、tile static long CURUK=0;volatile int CURRENTH=0;if(CURRENT1!=0) CURRENTH=CURRENTH+(int)CURRENT1;/*求取电流平均值*/if(CURRENT2!=0) CURRENTH=CURRENTH+(int)CURRENT2;if(CURRENT3!=0) CURRENTH=CURRENTH+(int)CURRENT3;if(CURRENT4!=0) CURRENTH=CURRENTH+(int)CURRENT4;if(CURRENT5!=0) CURRENTH=CURRENTH+(int)CURRENT5;
19、UK.Y=(long)CUREK*CURB;/*求取E(K-1)*KP*/CURRENTH=CURRENTH>>3;/*获取反馈电流平均值*/if(CURRENTH=0)/*如果电流反馈值为0,则置反馈值为1*/ CURRENTH=0X04;CUREK=(int)CURGIVE-CURRENTH;/*求取当前电流误差EK*/CURUK=CURUK+(long)CUREK*CURA-UK.Y;/*进行电流PI运算*/if(CURUK<=0)/*PI运算结果小于0?*/ CURUK=0;/*是,清PI运算结果寄存器*/ CCPR1L=FULLDUTY;/*PWM输出占空比为1*/
20、 CCP1X=0; CCP1Y=0; return;/*返回*/UK.Y=TH-CURUK;/*电流环限幅值减去当前PI运算结果*/if(UK.Y<=0)/*电流PI运算输出大于限幅值?*/ CURUK=TH;/*是,电流PI运算限幅输出*/ CCPR1L=0;/*PWM输出占空比为0*/ CCP1X=0;/*清CCP1CON.5*/ CCP1Y=0;/*清CCP1CON.4*/ return;/*返回*/UK.Y=UK.Y>>2;/*处理UK,获取PWM输出高电平时间*/CCPR1L=UK.B1;/*根据高电平时间设置相应寄存器*/CCP1X=1;if(UK.B0&
21、0X80)=0)CCP1X=0;CCP1Y=1;if(UK.B0&0X40)=0)CCP1Y=0;return;/*-中断服务子程序-*/#pragma regsused w fsr pclath status#pragma interrupt_level 1void interrupt interrupted(void)/*中断服务子程序*/if(T0IF=1)/*TMR0中断?*/ T0IF=0;/*是,清中断标志*/ SPECOUNT=SPECOUNT+1;/*转速计数器加1*/ if(SPECOUNT>=0X80)/*转速值大于80*/ SP1=1;/*置SP1标志位,代
22、表转速很慢*/else if(RBIF=1)/*当前中断为RB口电平变化中断?*/ RBIF=0;/*是,清中断标志*/ sample();/*采样RB口状态*/ if(SAME=0)/*RB口状态与上一次状态相同?*/ output();/*不同,调输出子程序*/ if(SP1=1)/*转速计数器溢出?*/ SPEED=0X7F;/*是,认为当前转速为0X7F*/ TMR0=0;/*清TMR0定时器,重新定时*/ OPTION=OPTION|0X01;/*置TMR0预分频为1*/ else if(LOWSPEED=1) SPEED=SPECOUNT;/*否,算出当前电机转速*/ TMR0=0
23、;/*清TMR0定时器,重新定时*/ OPTION=OPTION|0X01;/*置TMR0预分频为4*/ if(SPECOUNT<=0X20) SPEED=SPECOUNT<<1; TMR0=0; OPTION=OPTION&0XF8; LOWSPEED=0; else SPEED=SPECOUNT; TMR0=0; OPTION=OPTION&0XF8; if(SPECOUNT>=0X4C) SPEED=SPECOUNT>>1; TMR0=0;/*清TMR0定时器,重新定时*/ OPTION=OPTION|0X01;/*置TMR0预分频为4
24、*/ LOWSPEED=1; SPECOUNT=0;/*转速计数器清零*/ SP1=0;/*清溢出标志*/ SAME=0;/*清SAME标志位*/ RBIF=0;/*清RB口中断标志*/ else if(ADIF=1)/*当前中断为AD采样中断?*/ if(TS=1)/*是。当前AD采样调速手柄?*/ CHS0=1;/*是。选择AN1采样通道,准备采样电流*/ COUNT_VOL=COUNT_VOL+1; /*采样电压周期寄存器加1*/ if(COUNT_VOL=0)/*电压采样周期到?*/ CHS0=0;/*是,选择AN3采样通道,准备采样电压*/ CHS1=1; VOLTAGE=1;/*置
25、电压采样标志位*/ ADIF=0;/*清AD中断标志*/ SPEPID=1;/*置转速PI运算标志位*/ TS=0;/*清调速手柄采样标志*/ TSH=(int)ADRESH;/*AD采样结果送TSH寄存器*/ if(VOLTAGE=1)/*需要采样电压?*/ asm("MOVLW 0X06");/*是,延时*/ asm("MOVWF _TEMP1"); asm("AD5 DECFSZ _TEMP1"); asm("GOTO AD5"); ADGO=1;/*开启AD转换器,采样电机电压*/ else if(VOLT
26、AGE=1)/*当前AD转换为电压值?*/ CHS1=0;/*是,选择AN1通道,准备采样电流*/ CHS0=1; ADIF=0;/*清AD中断标志*/ VOLTAGE=0;/*清电压采样标志位*/ VOLTAGEH=ADRESH;/*AD采样结果送VOLTAGEH寄存器*/ LOWPOWER=1;/*置LOWPOWER标志位*/ else/*当前AD采样为电流采样*/ if(ADRESH<=CURRENT0) CURRENTCOUNT_CUR=CURRENT0;/*是,保存较大的采样值*/ CURRENT0=ADRESH;/*较小值送CURRNT0*/ else if(ADRESH&g
27、t;=CURRENT7)/*当前采样值大于本次采样循环中的最大电流值?*/ CURRENTCOUNT_CUR=CURRENT7;/*是,小的采样值送CURRENT保存*/ CURRENT7=ADRESH;/*大的采样值送CURRENT7*/ else CURRENTCOUNT_CUR=ADRESH;/*当前采样值不是最大也不是最小,保存*/ ADIF=0;/*清AD转换中断标志*/ COUNT_CUR=COUNT_CUR-1;/*电流采样循环寄存器减1*/ if(COUNT_CUR=0)/*本次电流采样循环完毕?*/ COUNT_CUR=TIME_CUR;/*是,重新初始化电流采样循环寄存器*
28、/ CURRENT0=0XFF;/*重新初始化采样最大和最小值寄存器*/ CURRENT7=0; COUNT_TS=COUNT_TS-1;/*调速手柄采样寄存器减1*/ if(COUNT_TS=0)/*调速手柄寄存器为0?*/ CHS0=0;/*是,选择AN0采样通道*/ COUNT_TS=0X08;/*重新初始化调速手柄采样周期寄存器*/ asm("MOVLW 0X0A");/*延时*/ asm("MOVWF _TEMP1"); asm("AD3 DECFSZ _TEMP1"); asm("GOTO AD3");
29、/*置手柄采样标志位*/ ADGO=1;/*开AD采样*/ TS=1;/*置TS标志位*/ CURPID=1;/*置CURPID标志位,电流PI运算允许*/ else asm("MOVLW 0X06");/*电流采样循环没结束,延时*/ asm("MOVWF _TEMP1"); asm("AD6 DECFSZ _TEMP1"); asm("GOTO AD6"); ADGO=1;/*开AD,继续采样电流*/ /*中断返回*/ else if(INTF=1)/*外中断到来?*/ SHUTDOWN=1;/*置SHUTDO
30、WN标志位*/ INTF=0;/*清外中断标志*/ /*中断返回*/*-电机转子位置采样子程序-*/#pragma interrupt_level 1void sample(void)/*RB口状态采样子程序*/unsigned char STATE2,STATE3;/*变量声明*/resamp: STATE1=PORTB&0XE0;/*取RB口高3位信息送STATE1*/#asm MOVLW0X0A/*延时*/MOVWF_DELAYDEL1DECFSZ_DELAYGOTODEL1 #endasmSTATE2=PORTB&0XE0;/*再取RB口高3位信息送STATE2*/if
31、(STATE1=STATE2)/*两次读得得状态相同?*/ if(STATE1=OLDSTATE) /*是。认为STATE1为当前状态,再判当前状态与上次调用本子程序得到状态相同?*/ SAME=1;/*相同,置SAME标志位*/ else OLDSTATE=STATE1;/*否则保存当前状态值*/ return;/*子程序返回*/#asm/*若两次读得状态不同,则延时*/MOVLW0X0AMOVWFDELAYDEL2DECFSZDELAYGOTO DEL2#endasmSTATE3=PORTB&0XE0;/*第三次读取RB口高三位状态值*/if(STATE1=STATE3)/*第三次
32、状态值与第一次相同否?*/ if(STATE1=OLDSTATE) /*相同,认为STATE1为当前状态,再判当前状态与上次调用本子程序得到状态相同?*/ SAME=1;/*相同,置SAME为1*/ else OLDSTATE=STATE1;/*否则保存当前状态*/ return;/*返回*/if(STATE2=STATE3)/*第三次状态值与第二次状态值相同否?*/ STATE1=STATE2;/*相同,则认为STATE2为当前状态,当前状态值送STATE1*/ if(STATE1=OLDSTATE) /*再判当前状态与上次调用本子程序得到状态相同?*/ SAME=1;/*相同则置SAME标
33、志位*/ else OLDSTATE=STATE1;/*否则STATE1送OLDSTATE保存*/ return;/*返回*/goto resamp;/*若在本次子程序调用中所取得三次状态值各不相同,则重新采样RB口*/*-转子位置输出子程序-*/#pragma interrupt_level 1void output(void)/*电机换相子程序*/asm("SWAPF _STATE1");/*STATE1高低半字节互换*/RP0=0;/*选择0存储体*/PORTC=out_tableSTATE1>>1;/*查表输出相应的换相值*/return;/*返回*/*-刹车处理子程序-*/void breakon(void)OFF=0;/*清刹车标志位*/SHUTDOWN=0;if(RB0=0)/*
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025机械设备的买卖合同
- 洛阳理工学院《工科大学化学-物理化学(二)》2023-2024学年第一学期期末试卷
- 污水处理厂导向钻进施工合同
- 墙绘施工合同范本
- 教育培训机构劳务管理
- 食品企业财务健康检查
- 2024年动力煤进口清关共享成功之道!3篇
- 广西壮族自治区河池市2023-2024学年高一上学期1月期末考试数学试题(解析版)
- 医疗器械招投标管理规范
- 医药招投标项目招标文件编制
- 国家开放大学电大《建筑制图基础》机考三套标准题库及答案3
- 降低故障工单回复不合格率
- 可涂色简笔画打印(共20页)
- 灯光架介绍及使用说明
- 十一学校行动纲要
- GB 1886.6-2016 食品安全国家标准 食品添加剂 硫酸钙(高清版)
- 关于房屋征收及土地收储过程中的税收政策(仅供参考)
- 唯一住房补贴申请书(共2页)
- 单面多轴钻孔组合机床动力滑台液压系统课程设计
- 中医养生脾胃为先PPT文档
- 门窗工程成品保护方案(附图)
评论
0/150
提交评论