gaochaoning 发表于 2009-3-3 10:20:15

数控钻床上控制变频器转速的小装置。有图、有程序,寻找可靠性方面的改进方案,请多提宝

数控钻床主轴转速是根据钻头的直径而变化的,主轴是由变频器控制的。巧的很,后配软件(运行在pc中的系统软件)没有改变转速的功能。于是我给它加了一个小装置,用m16控制3个继电器,再控制变频器上的转速输入端。小装置可以运行了。
    数控钻床主轴在上下运动,如果这时m16出现程序跑飞需重新启动,还要从原来的转速开始,否则会断钻头。这个地方是如何做到的。请指点。谢谢。

点击此处下载 ourdev_423212.rar(文件大小:15K) (原文件名:原理图.rar)

点击此处打开 ourdev_423215.JPG(文件大小:655K,只有400K以内的图片才能直接显示) (原文件名:100_3261.JPG)
/*********************************************
File name         : Demo_6_9.c
Chip type         : ATmega16
Program type      : Application
Clock frequency   : 4.000000 MHz
Memory model      : Small
External SRAM size: 0
Data Stack size   : 256
说明:程序中很多地方都是马老师书中的。
*********************************************/
#include"mega16.h"
#include"stdio.h"
#include"delay.h"
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x18
#endasm
#include <lcd.h>
bit   key_stime_ok;
unsigned char       key_stime_counter;                // 时间计数单元,
// Timer 0 比较匹配中断服务,2ms定时

interrupt void timer0_comp_isr(void)
{
        if (++key_stime_counter >=5)
        {
                key_stime_counter = 0;
                key_stime_ok = 1;        // 10ms到                        // 10ms到                  
        }                                                 // LED扫描显示
}

#define key_inputPIND
#define key_1      0b11111110
#define key_2      0b11111101
#define key_3      0b11111011
#define key_4      0b11110111
#define key_5      0b11101111
#define key_6      0b11011111
#define key_7      0b10111111
#define key_8      0b01111111
#define key_no   0b11111111
#define key_state_0      0
#define key_state_1      1
#define key_state_2      2

unsigned char music(void)
{
    unsigned chari=0;
    do
    {
       PORTA.3=1;
       delay_us(400);
       PORTA.3=0;
       delay_us(400);
       i++;
    }
    while(i<200);
         
}
unsigned char read_key(void)                        //读键状态机,每10-20ms执行一次
{   
    static unsigned char key_state = 0,key_old;   
    unsigned char key_press,key_return = key_no;   

    key_press = key_input;      // 读按键I/O电平   
    switch (key_state)   
    {   
      case key_state_0:                  // 按键初始态   
            if (key_press != key_no)key_state = key_state_1;    // 键被按下,状态转换到键确认态   
            break;   
      case key_state_1:                  // 按键确认态   
            if (key_press == key_old)      // 与原电平比较(消抖处理)
            {   
                key_return = key_press;   
                key_state = key_state_2;      // 状态转换到判键释放态   
            }   
            else   
                key_state = key_state_0;      // 按键已抬起,转换到按键初始态(消抖)   
            break;   
      case key_state_2:   
            if (key_press != key_old)
                key_state = key_state_0;      //按键已释放(或转按其它键),转换到按键初始态   
            break;
    }
    key_old = key_press;   
    return key_return;   
}

main()
{
   unsigned char key_value;
   PORTA = 0xff;                                       
   DDRA = 0xFF;
   PORTD = 0xff;       
   DDRD = 0x00;                                        // PD7为输入方式
   // T/C0 初始化
   TCCR0 = 0x0B;        // 内部时钟,64分频(4M/64=62.5KHz),CTC模式
   TCNT0 = 0x00;
   OCR0 = 0x7C;        // OCR0 = 0x7C(124),(124+1)/62.5=2ms
   TIMSK = 0x02;        // 允许T/C0比较匹配中断

   #asm("sei")        // 开放全局中断
   lcd_init(16);                       
   lcd_clear();
   lcd_putsf("Please input:");        // 第一行显示内容
   
      while (1)
      {
         if (key_stime_ok)            //10ms到,key_stime_ok=1                                // 10ms到,键处理
         {
               key_stime_ok = 0;
               key_value = read_key();   //注意控制10-20ms执行一次.
               if (key_value != key_no)//判别键值并做相应的处理
               {
                   switch (key_value)
                   {
                      case key_1:
                      lcd_gotoxy(0,1);
                      lcd_putsf("65K=65000RPM");        // 第二行显示内容
                      PORTA=0xef;
                      music( );
                      delay_ms(1000);
                      PORTA=0xff;
                      break;
                      case key_2:
                      lcd_gotoxy(0,1);
                      lcd_putsf("58K=58000RPM");        // 第二行显示内容
                      PORTA=0xee;
                      music( );
                      delay_ms(1000);
                      PORTA=0xfe;
                      break;
                      case key_3:
                      lcd_gotoxy(0,1);
                      lcd_putsf("52K=52000RPM");        // 第二行显示内容
                      PORTA=0xed;
                      music( );
                      delay_ms(1000);
                      PORTA=0xfd;
                      break;
                      case key_4:
                      lcd_gotoxy(0,1);
                      lcd_putsf("45K=45000RPM");        // 第二行显示内容
                      PORTA=0xec;
                      music( );
                      delay_ms(1000);
                      PORTA=0xfc;
                      break;
                      case key_5:
                      lcd_gotoxy(0,1);
                      lcd_putsf("20K=20000RPM");        // 第二行显示内容
                      PORTA=0xe8;
                      music( );
                      delay_ms(1000);
                      PORTA=0xf8;
                     
                      break;
                      case key_6:
                      lcd_gotoxy(0,1);
                      lcd_putsf("26K=26000RPM");        // 第二行显示内容   
                      PORTA=0xe9;
                      music( );
                      delay_ms(1000);
                      PORTA=0xf9;
                      break;
                      case key_7:
                      lcd_gotoxy(0,1);
                      lcd_putsf("32K=32000RPM");        // 第二行显示内容   
                      PORTA=0xea;
                      music( );
                      delay_ms(1000);
                      PORTA=0xfa;
                      break;
                      case key_8:
                      lcd_gotoxy(0,1);
                      lcd_putsf("38K=38000RPM");        // 第二行显示内容
                      PORTA=0xeb;
                      music( );
                      delay_ms(1000);
                      PORTA=0xfb;
                      break;
                   }
                }
                //............
         }
      }
}

shinehjx 发表于 2009-3-3 11:47:58

想办法在电源和IO上做隔离
使用屏蔽线
m16主频率尽量选低些,只控制几只继电器1M或以下应能满足
换成plc或选用抗干扰更好的mcu

shinehjx 发表于 2009-3-3 11:53:06

控制3个继电器是自动的吗?如果还要手动按键来选的话,不如用逻辑IC或机械开关来控制更为可靠

gaochaoning 发表于 2009-3-3 13:49:46

3个继电器的状态是由按键选择的,不是自动的。我想m16做的东西应该能经得起干扰的,就是要找到解决的办法,不要用逻辑IC或机械开关.

现在要从软件解决的问题是:主轴在上下移动,如果在这期间m16发生问题重启动后要能恢复原来的状态,比如原来PA0为1、PA1为0、PA2为1。重启后要能恢复这种状态。

自己有一点思路:比如按键后把数据保存在eeprom中,重启后立即读eeprom的数据并写到PORTA口。其他的工作如发声、lcd显示可以在后面做。

这种问题因该是属于重启后恢复原来数据的类型。

gaochaoning 发表于 2009-3-3 15:45:38

复位后PORTA可以保持原来状态了。

请指点如何使用看门狗,还没有找到实例。

taishandadi 发表于 2009-3-6 11:02:51

m16不是有寄存器,表示是何种复位的.按键设置好后状态保存在eep中,复位后查是何种复位,跑飞就去读设置。
avr不熟,刚看。

gaochaoning 发表于 2009-3-7 09:25:33

学习了,谢谢。已经装上去用了。看看可靠性如何。
页: [1]
查看完整版本: 数控钻床上控制变频器转速的小装置。有图、有程序,寻找可靠性方面的改进方案,请多提宝