搜索
bottom↓
回复: 14

求助:PIC16F877A 控制交流电机恒速程序(C语言)

[复制链接]

出0入0汤圆

发表于 2013-4-15 15:58:23 | 显示全部楼层 |阅读模式
本帖最后由 笑谈 于 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 uint  unsigned 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:130W  Vmotor:40V
                if(counter0()<=330)        //转速过低                // 330/4=83  18000
                {

                        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;
}








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-4-15 16:02:55 | 显示全部楼层
不知道是不是计数器部分的问题,PIC单片机和交流电机控制都刚上手,还望各位赐教,谢谢。

出0入0汤圆

发表于 2013-4-15 17:01:09 | 显示全部楼层
应该用PI调节吧,要不然滞缓也可以要有一定的差量。

出0入0汤圆

 楼主| 发表于 2013-4-15 17:09:40 | 显示全部楼层
wtliu 发表于 2013-4-15 17:01
应该用PI调节吧,要不然滞缓也可以要有一定的差量。

您好,能帮忙讲详细点吗?或者参考的资料。谢谢

出0入0汤圆

 楼主| 发表于 2013-4-16 10:34:45 | 显示全部楼层
今天调整硬件,测试了一下程序。
的确是计数器程序有问题,哪位帮忙看看哪里有问题,谢谢!

unsigned int counter0()                //TMR0 脉冲 计数器
{
        OPTION=0x21;                 //00100001     TOCKI引脚上升沿计数   1:4分频
        TMR0 = 0;
        delay_ms(1000);                //定时1000ms的时间,检测脉冲个数
        return (4*TMR0);        //实际速度为TMR0*4,因为进行过1:4分频
}

出0入0汤圆

 楼主| 发表于 2013-4-16 13:10:40 | 显示全部楼层
各位大侠过来帮忙看看啊,老大催的急,在线等,,,谢谢!

出0入0汤圆

 楼主| 发表于 2013-4-16 21:00:21 | 显示全部楼层
顶起,期待高手露面。。。

出0入0汤圆

发表于 2013-4-16 21:10:05 | 显示全部楼层
void delay_ms(unsigned char n)  //1ms
delay_ms(1000);
是这个原因么?

出0入0汤圆

 楼主| 发表于 2013-4-16 22:07:20 | 显示全部楼层
tanguojian 发表于 2013-4-16 21:10
void delay_ms(unsigned char n)  //1ms
delay_ms(1000);
是这个原因么?

应该不是的,我估计是计数器及返回值这边的问题

出0入0汤圆

发表于 2013-4-17 08:57:16 | 显示全部楼层

void delay_ms(unsigned char n)  //1ms
delay_ms(1000);
楼主看不出来么?

出0入0汤圆

 楼主| 发表于 2013-4-17 09:12:59 | 显示全部楼层
tanguojian 发表于 2013-4-17 08:57
void delay_ms(unsigned char n)  //1ms
delay_ms(1000);
楼主看不出来么?

谢谢提醒,是我疏忽了。我把n改成整形的。

出0入0汤圆

 楼主| 发表于 2013-4-17 15:28:47 | 显示全部楼层
程序更新,感觉计数器不能正常的捕捉到信号反馈给单片机。
大家出来讨论啊,有做过交流电机恒速的大侠出来谈谈

/************************************
测速度_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 uint  unsigned 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;
}

出0入0汤圆

 楼主| 发表于 2013-4-19 09:18:49 | 显示全部楼层
问题还没搞定。再次顶起,此帖如能完美结束的话相信对以后其他人也有很大的帮助。

出0入0汤圆

发表于 2013-4-19 11:16:09 | 显示全部楼层
这个也发帖啊!

出0入0汤圆

 楼主| 发表于 2013-4-19 12:24:02 | 显示全部楼层
HDhaidong 发表于 2013-4-19 11:16
这个也发帖啊!

说明你肯定懂,那指点一下?谢谢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 14:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表