电机速度控制PIC课设报告程序.docx

上传人:b****6 文档编号:8456663 上传时间:2023-01-31 格式:DOCX 页数:15 大小:18.90KB
下载 相关 举报
电机速度控制PIC课设报告程序.docx_第1页
第1页 / 共15页
电机速度控制PIC课设报告程序.docx_第2页
第2页 / 共15页
电机速度控制PIC课设报告程序.docx_第3页
第3页 / 共15页
电机速度控制PIC课设报告程序.docx_第4页
第4页 / 共15页
电机速度控制PIC课设报告程序.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

电机速度控制PIC课设报告程序.docx

《电机速度控制PIC课设报告程序.docx》由会员分享,可在线阅读,更多相关《电机速度控制PIC课设报告程序.docx(15页珍藏版)》请在冰豆网上搜索。

电机速度控制PIC课设报告程序.docx

电机速度控制PIC课设报告程序

 

附录:

#include

__CONFIG(0x00F1);

//__CONFIG(0x3F71);

#defineLCD_ERD6

#defineLCD_RWRD5

#defineLCD_RSRD4

#defineCOM0

#defineDAT1

#defineLINE10b10000000

#defineLINE20b11000000

#defineLEDRB5

#defineDN_POSITIONLINE2+15//第2行显示速度回差的个位位置

#defineDN_POSITIONLINE2+15//第2行显示速度回差的个位位置

bank1charDD[16];

constcharMENU0[2][17]={

{"PIC16F887"},

{"PICC9.5"},

};

constcharLINE[2]={LINE1,LINE2};

constunsignedintND[11]={200,500,800,1100,1400,1700,2000,2300,2600,2900,3200};

//定义结构体类型STRU的变量KEY

structSTRU

{unsignedSET:

3;

unsignedINC:

1;

unsignedDEC:

1;

unsignedFLAG:

1;

unsignedCHANGE:

1;

unsignedSETINT:

1;

}KEY;

union//联合体AD_RESULT存放AD转换结果

{

unsignedintAD_TEMP;

charAD[2];

}AD_RESULT;

//EEPROM第一单元占空比D初值,第二单元转速误差运行值DN初值

__EEPROM_DATA(200,10,255,255,255,255,255,255);

unsignedcharD;//占空比10倍

unsignedHT;//高电平时间(us)

unsignedintN0_MIN=150;

unsignedintN0_MAX=2048;

unsignedintN0;//期望转速值

unsignedintN;//实际测速值

unsignedcharDN;//转速误差

unsignedlongn;

charWW,QW,BW,SW,GW;

unsignedcharT0N;

unsignedintDN_OLD;

unsignedintT=0;

unsignedintN1;

unsignedintN2;

intAD_SUB(void);

voidCSH(void);

voidDISP_N0_DN(unsignedint,unsignedchar);

voidDISP_N_D(unsignedint,unsignedchar);

voidCAP_CSH(void);

voidPWM_CSH(unsignedint);

voidDUTY_SET(unsignedint);

voidAD_CSH(void);

voidLCD_CSH(void);

voidLCD_WRITE_4(char,char);

voidLCD_WRITE(char,char);

voidLCD_BUSY(void);

charLCD_READ(void);

voidDISP_C(char);

voidDISP_MENU(constchar*A);

voidBCD(unsignedint);

voidDELAY(unsignedint);

voidDELAY_I(unsignedint);

voidDELAY_US(char);

voidinterruptINT_ISR(void);

voidchange(void);

//unsignedintDN_GET(void);

//宏定义:

清屏

#defineCLR_LCD()\

LCD_WRITE(0b00000001,COM);\

DELAY

(2)

//AD转换,期望转速N0取值N0_MIN~N0_MAX,并放大100倍

voidmain(void)

{

unsignedinti;

CSH();

DISP_MENU(*MENU0);

DELAY(100);

//DELAY(400);

CLR_LCD();

while

(1)

{

N0=AD_SUB();

DISP_N0_DN(N0,DN);//显示期望转速和转速误差允许值

DISP_N_D(N,D);

change();//显示实际转速和占空比

while(KEY.FLAG==0)

{DELAY

(1);

i++;

if(i>200)LED=0;

if(i>400)break;

}

DN_OLD=DN;

while(KEY.FLAG==1)

{

if(KEY.SET==1)//进入修改,字符闪

LCD_WRITE(DN_POSITION,COM);//确定字符闪的位置

LCD_WRITE(0b00001111,COM);//字符闪

if(KEY.SETINT==1)

{if(KEY.SET==1)

N1=ND[T];

DELAY_US(3);

KEY.SETINT=0;T++;

if(T>10)T=0;

KEY.CHANGE=1;

}

if(KEY.INC==1)

{if(KEY.SET==1)DN++;

KEY.INC=0;

KEY.CHANGE=1;

}

if(KEY.DEC==1)

{if(KEY.SET==1)DN--;

KEY.DEC=0;

KEY.CHANGE=1;

}

if(KEY.CHANGE==1)//如果有修改,刷新显示

{DISP_N0_DN(N0,DN);

KEY.CHANGE=0;

if(KEY.SET==1)//刷新后重新开字符标闪

LCD_WRITE(DN_POSITION,COM);//确定字符闪的位置

LCD_WRITE(0b00001101,COM);//字符闪

}

}

if(DN_OLD!

=DN)

EEPROM_WRITE(1,DN);//写入速度控制的回差值,在EEPROM的地址1

}

}

voidchange(void)

{unsignedintj;

if(N>N0+DN)

{

HT--;

if(HT>1000)HT=1000;

DUTY_SET(HT);

DELAY(300);

}

elseif(N

{

HT++;

if(HT>1000)HT=0;

DUTY_SET(HT);

DELAY(300);

}

LED=1;

j=0;

}

voidCSH(void)

{

ANSELH=0;//关闭B口模拟引脚,设为I/O引脚

TRISB=0b00001111;

OPTION=0b00010111;//B口上拉,且下降沿中断

INTCON=0b11010000;//GIE=1;PEIE=1;INTE=1;RBIE=1;

IOCB=0b00001110;//B口电平变化中断控制寄存器,RB1、RB2电平变化产生中断,在RBIE=1的前提下

KEY.FLAG=0;

KEY.SET=0;

TMR1H=TMR1L=0;

T1CON=0b00110001;//1:

8分频

TRISD=0b00000000;

TRISC=0b00100000;

HT=EEPROM_READ(0);

DN=EEPROM_READ

(1);

LCD_CSH();

CAP_CSH();

PWM_CSH(HT);

AD_CSH();

}

intAD_SUB(void)

{GODONE=1;

while(GODONE==1);

ADIF=0;

AD_RESULT.AD[0]=ADRESL;

AD_RESULT.AD[1]=ADRESH;

n=AD_RESULT.AD_TEMP;

n*=350;

N2=n/1023+N1;

returnN2;

}

voidDISP_N0_DN(unsignedintSTART_N0,unsignedcharDELTA_N)

{LCD_WRITE(0b00001100,COM);//不闪

LCD_WRITE(LINE2,COM);//即第2行的第0个字符

BCD(START_N0);//将要显示的起动占空比值做BCD转换

LCD_WRITE('N',DAT);//在当前位置显示字符'N'

LCD_WRITE('0',DAT);//在当前位置显示字符'0'

LCD_WRITE('=',DAT);//在当前位置显示字符':

'

LCD_WRITE(QW+0x30,DAT);//显示千位

LCD_WRITE(BW+0x30,DAT);//显示百位

LCD_WRITE(SW+0x30,DAT);//显示十位

LCD_WRITE(GW+0x30,DAT);//显示个位

LCD_WRITE('r',DAT);//在当前位置显示字符'r'

LCD_WRITE('p',DAT);//在当前位置显示字符'/'

LCD_WRITE('m',DAT);//在当前位置显示字符'm

LCD_WRITE('',DAT);//在当前位置显示空格'

BCD(DELTA_N);//将要显示的转速n控制回差量做BCD转换

LCD_WRITE('D',DAT);//在当前位置显示字符'D'

LCD_WRITE('n',DAT);//在当前位置显示字符'n'

LCD_WRITE('=',DAT);//在当前位置显示字符':

'

LCD_WRITE(SW+0x30,DAT);//显示十位

LCD_WRITE(GW+0x30,DAT);//显示个位

}

voidDISP_N_D(unsignedintR1,unsignedcharDUTY)//速度在R1,占空比DUTY

{

LCD_WRITE(0b00001100,COM);//不闪

BCD(R1);

LCD_WRITE(LINE1,COM);//DDRAM地址,第1行的第5个字符

LCD_WRITE('',DAT);//在当前位置显示空格''

LCD_WRITE('N',DAT);

LCD_WRITE('=',DAT);

LCD_WRITE(QW+0x30,DAT);//显示千位

LCD_WRITE(BW+0x30,DAT);//显示百位

LCD_WRITE(SW+0x30,DAT);//显示十位

LCD_WRITE(GW+0x30,DAT);//显示个位

LCD_WRITE('r',DAT);//在当前位置显示字符'r'

LCD_WRITE('p',DAT);//在当前位置显示字符'/'

LCD_WRITE('m',DAT);//在当前位置显示字符'm'

LCD_WRITE('',DAT);//在当前位置显示空格''

BCD(DUTY);//将要显示的转速n控制回差量做BCD转换

LCD_WRITE('D',DAT);//在当前位置显示字符'D'

LCD_WRITE('=',DAT);//在当前位置显示字符':

'

LCD_WRITE(SW+0x30,DAT);//显示十位

LCD_WRITE(GW+0x30,DAT);//显示个位

LCD_WRITE('%',DAT);//显示字符'%'

}

voidCAP_CSH(void)

{

TRISC2=1;

CCP1CON=0b00000110;

TMR1H=TMR1L=0;

T1CON=0b00110001;

CCP1IF=0;

CCP1IE=1;

GIE=1;

PEIE=1;

}

voidinterruptINT_ISR(void)

{

longX;

unsignedintTZ;

if(CCP1IF==1)

{

TMR1H=TMR1L=0;

TZ=(CCPR1H<<8)|CCPR1L;

X=7500000;

N=X/TZ;

CCP1IF=0;

}

if(INTF==1)

{DELAY_I(30);

INTF=0;

KEY.SET+=1;

KEY.FLAG=1;

if(KEY.SET>1)

{KEY.SET=0;

KEY.FLAG=0;

RBIE=0;

}

//TMR1ON=1;

RBIE=1;

//PEIE=1;

//GIE=1;

T0IE=1;

TMR0=0;

T0IF=0;

T0N=0;

}

if(RBIF==1)

{DELAY_I(30);

if(RB3==0&&KEY.FLAG==1)

{KEY.SETINT=1;

T0N=0;

}

if(RB2==0&&KEY.FLAG==1)

{KEY.DEC=1;

T0N=0;

}

if(RB1==0&&KEY.FLAG==1)

{KEY.INC=1;

T0N=0;

}

RBIF=0;

}

if(T0IF==1)

{T0IF=0;

TMR0=0;

T0N++;

if(T0N>100)//约6S

{KEY.FLAG=0;

KEY.SET=0;

T0IE=0;

}

}

}

//设置周期为1000US的PWM输出

voidPWM_CSH(unsignedintht)

{

PR2=249;

DUTY_SET(ht);//X=0b0011001000;

T2CON=0b00000101;//预分频比为1:

4

}

//设置PWM波的高电平时间

voidDUTY_SET(unsignedintht)

{

CCPR2L=(ht>>2)&0x0FF;

CCP2CON=((ht<<4)&0x30)|0x0C;

D=ht/10;//由高电平时间计算占空比

}

voidAD_CSH(void)

{

TRISA0=1;

ANSEL=0x01;

ANSELH=0;

ADCON1=0b10000000;//A/D结果右对齐,参考电压GND,VDD

ADCON0=0b10000001;//AD转换时钟8us(32Tosc),AD通道AN0,GODONE=0;AD模块使能;

DELAY_US

(2);//延时20us

AD_SUB();//AD转换

}

voidLCD_CSH(void)

{

DELAY(20);

LCD_WRITE_4(0b0011,COM);

DELAY

(1);

LCD_WRITE_4(0b0011,COM);

DELAY_US(10);

LCD_WRITE_4(0b0011,COM);

DELAY_US(10);

LCD_WRITE_4(0b0010,COM);

LCD_BUSY();

LCD_WRITE(0b00101000,COM);//4位数据格式,2行,5*7点阵

LCD_WRITE(0b00001100,COM);//打开显示,光标不显示,不闪烁

CLR_LCD();

LCD_WRITE(0b00000110,COM);//光标右移,不整体移动

}

//将R1低4位写入LCD,FLAG选择写命令(0)或者写数据

(1)

voidLCD_WRITE_4(charR1,charFLAG)

{

LCD_RW=0;NOP();//写模式

LCD_RS=FLAG;NOP();//选择写命令还是写数据

PORTD&=0xF0;NOP();//RD低4位清零

LCD_E=1;NOP();//LCD使能

PORTD|=(R1&0x0F);NOP();//将R1低4位送到D端口低4位

LCD_E=0;NOP();//使能端形成下降沿,开始送数据

LCD_RS=0;NOP();//默认为写命令状态

PORTD&=0xF0;//LCD4位数据输入端清零

}

//将一字节的R1写入LCD,FLAG选择写命令(0)或者写数据

(1)

//写之前先检查是否忙,写完后延时100us,分两次写4位数据/命令

voidLCD_WRITE(charR1,charFLAG)

{

charR2;

LCD_BUSY();

R2=(R1>>4)&0x0F;//先写入高4位

LCD_WRITE_4(R2,FLAG);

R2=R1&0x0F;//后写入低4位

LCD_WRITE_4(R2,FLAG);

DELAY_US(10);//延时100us

}

voidLCD_BUSY(void)

{

unsignedcharR1;

while

(1)

{

R1=LCD_READ();//读寄存器

if((R1&0x80)==0x00)//最高位为忙标志位

break;

}

}

charLCD_READ(void)

{

unsignedcharR1;

TRISD|=0xF0;//D口低4位为输入

LCD_RS=0;NOP();//选择命令

LCD_RW=1;//写命令模式

NOP();NOP();

LCD_E=1;//LCD使能

NOP();NOP();

R1=0;

R1=PORTD&0x0F;

R1=(R1<<4)&0xF0;//读数据的高4位给R1高4位

LCD_E=0;NOP();//使能端形成下降沿

LCD_E=1;NOP();

R1|=PORTD&0x0F;//读数据的低4位给R1低4位

LCD_E=0;NOP();

LCD_RW=0;

TRISD&=0x0F;//D口低4位恢复为向LCD输出

returnR1;

}

voidDISP_C(charline)

{

chari;

LCD_BUSY();

LCD_WRITE(line,COM);

for(i=0;i<16;i++)

LCD_WRITE(DD[i],DAT);

}

voidDISP_MENU(constchar*A)

{

chari,j;

for(i=0;i<2;i++)

{

for(j=0;j<16;j++)

DD[j]=*A++;

A++;

DISP_C(LINE[i]);

}

}

//从R1双字节数转换为十进制数万位-个位:

WW,QW,BW,SW,GW

voidBCD(unsignedintR1)

//延时nms

voidDELAY(unsignedintn)

voidDELAY_I(unsignedintn)

//延时(n*10)us

voidDELAY_US(charn)

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1