⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main_cv__.c

📁 一款挂面机的自动化控制源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//ICC-AVR application builder : 2004-8-22 19:49:01
// Target : M16
// Crystal: 16.000Mhz
//本程序所用的长度单位为毫米,时间单位为8个时钟周期(千万分之五秒)
#include <Mega16.h>
//#include <macros.h>
#include <h_iic.c>
#include <Mega16.h>  
#include <string.h>
#include <delay.h>
//TWI状态定义
//MT 主方式传输  MR 主方式接收
#define START 0x08 
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_SLA_NOACK 0x20
#define MT_DATA_ACK  0x28
#define MT_DATA_NOACK 0x30
#define MR_SLA_ACK  0x40
#define MR_SLA_NOACK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NOACK 0x58
//hardware IIC
#define TWINT   7
#define TWEA    6
#define TWSTA   5
#define TWSTO   4
#define TWEN    2 

//常用TWI操作(主模式写和主模式读)
#define Start()    	  (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define Stop()     	  (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define Wait()	   	  {while(!(TWCR&(1<<TWINT)));}
#define TestAck() 	  (TWSR&0xf8)
#define SetAck()	  (TWCR|=(1<<TWEA))
#define SetNoAck()        (TWCR&=~(1<<TWEA))
#define TWI()	  	  (TWCR=(1<<TWINT)|(1<<TWEN)) 
#define TWE()             (TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN))
#define Write8Bit(x)      {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} 

#define zlg7290  0x70

/******************************************
               I2C总线写字符串
	       返回0:写成功
	       返回非0:写失败
*******************************************/
      
unsigned char ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
{     unsigned char i;
          #asm("cli")
          Start();//I2C启动
	  Wait();
	  if(TestAck()!=START){Stop(); return 1;}        //ACK
	  Write8Bit(sla);//写I2C从器件地址和写方式
	  Wait();
	  if(TestAck()!=MT_SLA_ACK){Stop(); return 1;}   //ACK
	  Write8Bit(suba);//写地址
	  for(i=0;i<no;i++)
	  { Wait();
	    if(TestAck()!=MT_DATA_ACK){Stop(); return 1;}//ACK
	    Write8Bit(*s);//写数据
	    s++;
	  }	
	  Wait(); 
	  if(TestAck()!=MT_DATA_ACK){Stop(); return 1;}  //ACK	
	  Stop();//I2C停止
	  #asm("sei")
 	  return 0;
}

/******************************************
               I2C总线读字符串
	       如果读失败也返回0,正确返回1;
*******************************************/
unsigned char IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) 
      {    
	   unsigned char i;
	    #asm("cli")
	   Start();//I2C启动
	   Wait();
	   if (TestAck()!=START) {Stop(); return 0;}//ACK	   
	   Write8Bit(sla);//写I2C从器件地址和写方式
	   Wait(); 
	   if (TestAck()!=MT_SLA_ACK) {Stop(); return 0;}//ACK
	   Write8Bit(suba);//写地址
	   Wait();
	   if (TestAck()!=MT_DATA_ACK) {Stop(); return 0;}
	   Start();//I2C重新启动
	   Wait();
	   if (TestAck()!=RE_START)  {Stop(); return 0;}
	   Write8Bit(sla+1);//写I2C从器件地址和读方式
	   Wait();
	   if(TestAck()!=MR_SLA_ACK)   {Stop(); return 0;}//ACK 
	   for(i=0;i<no-1;i++)
	   {  TWE();//启动主I2C读方式
	      Wait();
	      if(TestAck()!=MR_DATA_ACK)  {Stop(); return 0;};//ACK
	      *s=TWDR;//读取I2C接收数据
	      s++;
	   }
	   TWI();//启动主I2C读方式
	   Wait();
	   if(TestAck()!=MR_DATA_NOACK)  {Stop(); return 0;}//ACK	
	   *s=TWDR;//读取I2C接收数据	
	   Stop();//I2C停止 
	   #asm("sei")
	   return 1;
      }
unsigned char ZLG7290_SendData(unsigned char SubAdd,unsigned char Data)
{
	if(SubAdd>0x17)
	return 0;
	ISendStr(zlg7290,SubAdd,&Data,1);
       	delay_ms(10);
	return 1;
}
//向zlg7290命令缓冲区发送命令(2个字节)
unsigned char ZLG7290_SendCmd(unsigned char Data1,unsigned char Data2)
{  
    unsigned char Data[2];
	Data[0]=Data1;
	Data[1]=Data2;
	ISendStr(zlg7290,0x07,Data,2);
       	delay_ms(10);
	return 1;
}
//向zlg7290的显示缓冲区发送数据
void ZLG7290_SendBuf(unsigned char *display_buf,unsigned char num)
{
 	unsigned char i;
	for(i=0;i<num;i++)
	{	
		ZLG7290_SendCmd(0x60+i,*display_buf);
		display_buf++;
	}
} 
//zlg7290的键值
unsigned char ZLG7290_GetKey()
{   unsigned char rece=0;
    if( IRcvStr(zlg7290,1,&rece,1)==0 )  return (0);
       	delay_ms(10);
	return rece;
} 
//向ZLG7290发送字符串
void disstring(char *tmp)
{
unsigned char num;
unsigned char i;  
unsigned char chr,chr1,chr2;
char *at;
num=strlen(tmp);
//at=strchr(tmp,46);
//if (at[0]==0) num=num-1;
//if (num>=8) num=8;
at=tmp;
if (num>8)
   {
   if (*at==46) num=9;
   at++;
   }
for (i=0;i<num;i++)
   {
   chr=0x68-i;
   chr=*tmp;
   switch (chr)
      {
      case '0' : chr1=0; break;
      case '1' : chr1=1; break;
      case '2' : chr1=2; break;
      case '3' : chr1=3; break;
      case '4' : chr1=4; break;
      case '5' : chr1=5; break;
      case '6' : chr1=6; break;
      case '7' : chr1=7; break;
      case '8' : chr1=8; break;
      case '9' : chr1=9; break; 
      case ' ' : chr1=31; break;
      case 'A' : chr1=10; break;
      case 'b' : chr1=11; break;
      case 'C' : chr1=12; break;
      case 'd' : chr1=13; break;
      case 'E' : chr1=14; break;
      case 'F' : chr1=15; break;
      case 'G' : chr1=16; break;
      case 'H' : chr1=17; break;
      case 'i' : chr1=18; break;
      case 'J' : chr1=19; break;
      case 'L' : chr1=20; break;
      case 'O' : chr1=21; break;
      case 'P' : chr1=22; break;
      case 'q' : chr1=23; break;
      case 'r' : chr1=24; break;
      case 't' : chr1=25; break;
      case 'U' : chr1=26; break;
      case 'y' : chr1=27; break;
      case 'c' : chr1=28; break;
      case 'h' : chr1=29; break;
      case 'T' : chr1=30; break;
      case '.' : chr1=128; break;
      default  : chr1=31; 
      }
    
   tmp++; 
   chr2=*tmp;
   if (chr2=='.')  
      {
      chr1=chr1+128;
      tmp++;
      }
   ZLG7290_SendCmd(chr,chr1);
   }
} 
//#include <eeprom.h>
#include <stdlib.h>
///////////////  键盘定义
#define START_K 1    
//启动
#define ENTER 1
//确定
#define STOP 5    
//停止  
#define RETURN 5
//返回
#define K1 2      
//1
#define INC_SPEED 2
//增速
#define K2 3      
//2
#define DEC_SPEED 3
//减速
#define K3 4
//4
#define SET 4
//设定
#define K4 6
//4
#define SPEED 6
//速度
#define K5 7
//5
#define COUNT 7
//计数
#define K6 8
//8
#define SUM 8
//累计
#define K0 9
//9
#define CLEAR 9
//清零
#define K7 10
//7
#define MIAN_LENGTH 10
//面长
#define K8 11
//8
#define CUT_NUM 11
//刀数
#define K9 12
//9
#define JIGAN 12
//积杆
#define M_ZHUANBI 4000  
//转刀一周步进电机的步数
 
///////////////  全局变量定义
unsigned char M_state=0;  //步进电机的运行状态
/*
0:停转
1:启动
2:减速至停转
3:加速至随动
4:减速至随动
5:随动
6:加速至碎刀
7:碎刀
8:转动至平行
*/
unsigned int step_num=0;  //步进电机相对平行点的占步数
//unsigned char M_maichong; //步进电机的脉冲
unsigned int tmp_t1=64536; //计时器1的当前数值
unsigned char qidong_num=0;      //启动过程中步进电机所走的占步数
unsigned char dec_speed_bz=0;    //启动减速标志
unsigned int dec_speed_num=0;    //减速所走的步数
float DW_juli;    //单位距离
float P_speed;    //皮带速度
float juli;       //切刀到杆切点的距离
unsigned char time0_chi;  //计时器0的次数(256的倍数)
unsigned char time0_yu;   //计时器0的余数(整除256后所得的余数)
unsigned char time0_fen;  //如果余数太小,则从次数中分出一次来,和余数加在一起分担剩余的时间
unsigned char pidai_yunxing=0;   //皮带运行:1表示正常运行,0表示停止运行
eeprom float set_speed;   //设定的转速******
unsigned char dj_jibie=0;    //电磁调速电动机速度增减的级别
unsigned char dj_fangxi=0;   //电磁调速电动机调速的方向
unsigned char on_scr=0;      //可控硅导通标志
unsigned int pre_jsq=2000;      //上一次可控硅触发计时
unsigned char key=0;    //按键的键值
unsigned char on_key=0; //有键按下的标志
unsigned char key_num=0;  //计数,每计50查一次按键
unsigned char next_gan=0; //过下一杆标志
unsigned char guogan=0;   //开始正式过杆的标志
eeprom float dw_speed=0.00000025;      //一个时间单位所走的毫米数*******
float ganwei;   //杆位:挂面杆相对于切点的位置
float next_ganwei;   //下一杆的杆位
eeprom float juli_jcd;      //检测点到切点的距离*******
eeprom float ganju;        //两根挂面杆的距离*******
eeprom float longth_guamian;   //切好的挂面的长度*******
eeprom float longth_zongmian;  //一杆上挂面的总长度*******
unsigned char jidao;    //一杆面共切几刀
unsigned char first_gan=1; //第一杆标志
unsigned char qidong=0;   //步进电机是否起动
unsigned char jileigan=0;  //累积的杆数
eeprom unsigned char max_ganshu=10;  //积累杆数的上限
unsigned char caoshu=0;  //高速标志
float current_speed;     //当前速度
eeprom float caogan_speed;      //高速时的速度
unsigned char menu_jb=0;   //菜单级别
unsigned char menu_gn=0;      //菜单功能码  
char *string1;
char string2[]="    PASS"; 
char tmp_string[9];          //输入参数时,显示的数字
unsigned char cs_num=0;        //当前参数的位数
 char *str_dis;

///////////////
void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = 0xF0;
 DDRB  = 0xF0;
 PORTC = 0x00; //m103 output only
 DDRC  = 0xC0;
 PORTD = 0x00;
 DDRD  = 0x00;
}
#define ADC_VREF_TYPE 0xC0
unsigned int read_adc(void)  //读取模数转换的值,即测速发电机的电压值
{
unsigned char adc_H,adc_L;
unsigned int adc_jg;
adc_L=ADCL;
adc_H=ADCH;
adc_jg=adc_H*256+adc_L;
return adc_jg;
}
//TIMER0 initialize - prescale:8
// WGM: Normal
// desired value: 1Hz
// actual value: Out of range
void timer0_init(void)
{
 TCCR0 = 0x00; //stop
 TCNT0 = 0x00 /*INVALID SETTING*/; //set count
 OCR0  = 0x00 /*INVALID SETTING*/;  //set compare
 TCCR0 = 0x02; //start timer
}

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
unsigned char i; 
if (on_scr==1)   //如果可控硅触发标志为1,则触发可控硅
   {
   TCCR0=0;
   PORTC=PORTC | 0b01000000;
   for (i=0;i<20;i++)  ;
   PORTC=PORTC & 0b10111111;
   on_scr=0;
   }
if (time0_chi>0) //如果计数器0次数大于0,则重新开始(0-255)的计时
   {
   TCNT0=0;
   TCCR0=2;
   time0_chi--;
   }
else
   {
   if (time0_fen>0)
      {
	  TCNT0=time0_fen;
	  TCCR0=2;
	  time0_fen=0;
	  }
   else
      {
	  TCNT0=time0_yu;
	  TCCR0=2;
	  on_scr=1;
	  }
   }

}

//TIMER1 initialize - prescale:8
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Hz
// actual value: Out of range
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0x00 /*INVALID SETTING*/; //setup
 TCNT1L = 0x00 /*INVALID SETTING*/;
 OCR1AH = 0x00 /*INVALID SETTING*/;
 OCR1AL = 0x00 /*INVALID SETTING*/;
 OCR1BH = 0x00 /*INVALID SETTING*/;
 OCR1BL = 0x00 /*INVALID SETTING*/;
 //OCR1CH = $OCR1CH$;
 //OCR1CL = $OCR1CL$;
 ICR1H  = 0x00 /*INVALID SETTING*/;
 ICR1L  = 0x00 /*INVALID SETTING*/;
 TCCR1A = 0x00;
 TCCR1B = 0x02; //start Timer
}

interrupt [TIM1_OVF] void timer1_ovf_isr(void)  //步进电机控制
{
 unsigned char i;  //循环变量
 unsigned int time1_jsq;   //time1的时间值
 unsigned int avg_speed;   //平均速度
 if (M_state==0)   //停止状态
    {
	return;
	}
 //TIMER1 has overflowed
TCNT1 = tmp_t1;   //计数器赋初值
PORTC |=0b10000000;      //给出步进电机驱动脉冲
for (i=0;i<5;i++);
PORTC &=0b01111111; 
step_num++;     //计步加一
time1_jsq=65535-tmp_t1+1;;
 switch (M_state)
    {
    case 1:      //启动状态
	   {
	   qidong_num++;
       tmp_t1=64536;
	   if (qidong_num>160)
	      {
		  M_state=3;    //结束启动状态,转入加速状态
		  }
	   } break;
	case 2:       //减速至停转
	   {
	   if (time1_jsq<1000) time1_jsq++;
	   tmp_t1=65535-time1_jsq+1;
	   if (dec_speed_bz==1)
	      {
		  dec_speed_bz=0;
		  if (step_num>(M_ZHUANBI*3/4)) dec_speed_num=2*M_ZHUANBI-step_num; else dec_speed_num=M_ZHUANBI-step_num;
		  }
	   dec_speed_num--;
	   if (dec_speed_num==0) M_state=0;
	   } break;
	case 3:     //加速至随动
	case 4:     //减速至随动
	   {
	   avg_speed=(unsigned int)((juli/(1000-step_num))/P_speed+0.5);
	   
	   if (avg_speed>time1_jsq) time1_jsq++;
	   if (avg_speed<time1_jsq) time1_jsq--;
	   tmp_t1=65535-time1_jsq+1;
	   if (step_num==999) M_state=5;
	   } break;    
	case 5:    //随动
	   {
	   time1_jsq=(unsigned int)(DW_juli/P_speed);
	   tmp_t1=65535-time1_jsq+1;
	   } break;
	case 6:    //加速至碎刀
	   {
	   if (time1_jsq>111) time1_jsq--;
	   tmp_t1=65535-time1_jsq+1;
	   if (time1_jsq==111) M_state=7;
	   } break;
	case 7:    //碎刀
	   {
	   time1_jsq=111;
	   tmp_t1=65425;
	   } break;
	case 8:    //转动至平行
	   {
	   if (step_num==0) M_state=0;
	   tmp_t1=64536;
	   time1_jsq=1000;
	   } break;
	}
juli=juli-P_speed*time1_jsq;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -