求助:PIC16F877A 控制交流电机恒速程序(C语言)
本帖最后由 笑谈 于 2013-4-15 16:04 编辑各位大侠
小弟用PIC16F877A 控制交流电机恒速,但是程序部分始终调不好,请高手帮忙看看,指点一下问题出在哪里。谢谢!
下面是原理图及程序:
/************************************
测速度_1 控制在RPM=20000 RPMmax=30000
PIC 16F877A
Fosc = 4MHz
TMR0 做计数器
TMR1 做定时器
AC_ZERO = RA2
SPEED_MEASURE = RA4
PHOTO_OPEN = RB7
AC_PWM1 = RC2
************************************/
#include<pic.h>
#define uchar unsigned char
#define uintunsigned int
__CONFIG(0x3B31);
uint i;
uint SPEED_NUM;
void delay_ms(unsigned char n);//1ms
void init()
{
TRISC=0; //RC2=AC_PWM1 OUTPUT
PORTC=0xff;
TRISA=0xff; //RA2=AC_ZERO(INPUT);RA4=SPEED_MEASURE(INPUT,作为计数器使用,TMR0)
SPEED_NUM = 4;
}
unsigned int counter0() //TMR0 脉冲 计数器
{
OPTION=0x21; //00100001 TOCKI引脚上升沿计数 1:4分频
TMR0 = 0;
delay_ms(1000); //定时1000ms的时间,检测脉冲个数
return (4*TMR0); //实际速度为TMR0*4,因为进行过1:4分频
}
void main() //低功率运行
{
init(); //delay_ms=8 ::::RPM:13000 Pmax:130WVmotor:40V
if(counter0()<=330) //转速过低 // 330/4=8318000
{
if(RA2==0)
{
SPEED_NUM--;
delay_ms(SPEED_NUM); //delay_ms
PORTC = 0x00;
delay_ms(1);
PORTC = 0xff;
}
else
{
delay_ms(SPEED_NUM); //delay_ms
PORTC = 0x00;
delay_ms(1);
PORTC = 0xff;
}
}
if(330<counter0()<340) //转速刚好 RPM=19800~20400
{
if(RA2==0)
{
delay_ms(SPEED_NUM);
PORTC = 0x00;
delay_ms(1);
PORTC = 0xff;
}
else
{
delay_ms(SPEED_NUM); //delay_ms
PORTC = 0x00;
delay_ms(1);
PORTC = 0xff;
}
}
if(counter0()>=340) //转速过高 // 340/4=85
{
if(RA2==0)
{
SPEED_NUM++;
delay_ms(SPEED_NUM); //delay_ms
PORTC = 0x00;
delay_ms(1);
PORTC = 0xff;
}
else
{
delay_ms(SPEED_NUM); //delay_ms
PORTC = 0x00;
delay_ms(1);
PORTC = 0xff;
}
}
}
void delay_ms(unsigned char n)//1ms
{
unsigned char i;
unsigned int TMR1 = TMR1H<<8 + TMR1L;
T1CON = 0b00000000;
TMR1IF = 0;
TMR1H = 0;
TMR1L = 0;
TMR1ON = 1;
for(i=0;i<n;i++)
{
TMR1L = TMR1L + 0x18;
TMR1H = TMR1H + 0xFC;
while(!TMR1IF);
TMR1IF = 0;
}
TMR1ON = 0;
}
不知道是不是计数器部分的问题,PIC单片机和交流电机控制都刚上手,还望各位赐教,谢谢。 应该用PI调节吧,要不然滞缓也可以要有一定的差量。 wtliu 发表于 2013-4-15 17:01 static/image/common/back.gif
应该用PI调节吧,要不然滞缓也可以要有一定的差量。
您好,能帮忙讲详细点吗?或者参考的资料。谢谢 今天调整硬件,测试了一下程序。
的确是计数器程序有问题,哪位帮忙看看哪里有问题,谢谢!
unsigned int counter0() //TMR0 脉冲 计数器
{
OPTION=0x21; //00100001 TOCKI引脚上升沿计数 1:4分频
TMR0 = 0;
delay_ms(1000); //定时1000ms的时间,检测脉冲个数
return (4*TMR0); //实际速度为TMR0*4,因为进行过1:4分频
} 各位大侠过来帮忙看看啊,老大催的急,在线等,,,谢谢! 顶起,期待高手露面。。。 void delay_ms(unsigned char n)//1ms
delay_ms(1000);
是这个原因么? tanguojian 发表于 2013-4-16 21:10 static/image/common/back.gif
void delay_ms(unsigned char n)//1ms
delay_ms(1000);
是这个原因么?
应该不是的,我估计是计数器及返回值这边的问题
void delay_ms(unsigned char n)//1ms
delay_ms(1000);
楼主看不出来么? tanguojian 发表于 2013-4-17 08:57 static/image/common/back.gif
void delay_ms(unsigned char n)//1ms
delay_ms(1000);
楼主看不出来么?
谢谢提醒,是我疏忽了。我把n改成整形的。 程序更新,感觉计数器不能正常的捕捉到信号反馈给单片机。
大家出来讨论啊,有做过交流电机恒速的大侠出来谈谈
/************************************
测速度_1 控制在RPM=25000 RPMmax=30000
PIC 16F877A
Fosc = 4MHz
TMR0 做计数器
TMR1 做定时器
AC_ZERO = RA2
SPEED_MEASURE = RA4
PHOTO_OPEN = RB7
AC_PWM1 = RC2
************************************/
#include<pic.h>
#define uchar unsigned char
#define uintunsigned int
__CONFIG(0x3B31);
uint SPEED_NUM;
void delay_ms(unsigned int n); //1ms
void init()
{
TRISC=0; //RC2=AC_PWM1 OUTPUT
PORTC=0xff; //先输出高电平,此时交流电机不转
TRISA=0xff; //RA2=AC_ZERO(INPUT);RA4=SPEED_MEASURE(INPUT,作为计数器使用,TMR0)
SPEED_NUM = 3;
}
unsigned int counter0() //TMR0 脉冲 计数器 1s计数
{
OPTION=0x21; //00100001 TOCKI引脚上升沿计数 1:4分频
TMR0 = 0;
delay_ms(1000); //定时1000ms的时间,检测脉冲个数
return (4*TMR0); //实际速度为TMR0*4,因为进行过1:4分频
}
void main() //低功率运行
{
init();
while(1)
{
counter0();
if(counter0()<=414) //转速过低 // 414*60=24840
{
if(RA2==0)
{
PORTC=0xff;
SPEED_NUM--;
delay_ms(SPEED_NUM); //delay_ms
PORTC = 0x00;
delay_ms(1);
}
}
if((counter0()>414)&&(counter0()<417)) //转速刚好 RPM=24840~25020
{
if(RA2==0)
{
PORTC=0xff;
delay_ms(SPEED_NUM);
PORTC = 0x00;
delay_ms(1);
}
}
if(counter0()>=417) //转速过高 417*60=25020
{
if(RA2==0)
{
PORTC=0xff;
SPEED_NUM++;
delay_ms(SPEED_NUM); //delay_ms
PORTC = 0x00;
delay_ms(1);
}
}
}
}
void delay_ms(unsigned int n)//1ms
{
unsigned int i;
unsigned int TMR1 = TMR1H<<8 + TMR1L;
T1CON = 0b00000000;
TMR1IF = 0;
TMR1H = 0;
TMR1L = 0;
TMR1ON = 1;
for(i=0;i<n;i++)
{
TMR1L = TMR1L + 0x18;
TMR1H = TMR1H + 0xFC;
while(!TMR1IF);
TMR1IF = 0;
}
TMR1ON = 0;
}
问题还没搞定。再次顶起,此帖如能完美结束的话相信对以后其他人也有很大的帮助。 这个也发帖啊!{:sweat:} HDhaidong 发表于 2013-4-19 11:16 static/image/common/back.gif
这个也发帖啊!
说明你肯定懂,那指点一下?谢谢
页:
[1]