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

📄 zoubeifuwei.c

📁 这个事自己做的第一个单片机程序
💻 C
📖 第 1 页 / 共 3 页
字号:
  #include <iom168v.h>
  #include <macros.h>

  typedef unsigned char uchar;
  typedef unsigned int  uint;

  #define MAXstep1    1600
  //勾杯电机最大步数
 
  #define MAXstep2    1800
  //推杯1电机最大步数 
  
  #define MAXstep3    1800
  //推杯2电机最大步数
 
  #define MAXstepTG    480
  #define MAXstepDG    1480                   
  //预温电机最大步数
  
  #define  START_GO      (PIND&0x10)             
  //零位光耦
  #define  END_GO        (PIND&0x08)             
  //末端光耦
             
  //电机使能   
  #define  M_ENABLE      (PORTB|=0x04)
  #define  M_UNENABLE    (PORTB&=~0x04)          
  
  #define  M_HIGHMOVE    (PORTD&=~0x80)          
  //高压运行
  #define  M_LOWMOVE     (PORTD|=0x80)           
  //低压锁定
  
  #define  M_CLOCKWISE   (PORTB|=0x01)           
  //顺时针方向
  #define  M_UNCLOCKWISE (PORTB&=~0x01)         
  //逆时针方向

  #define  LED_ON        PORTD &= ~0x01;
  #define  LED_OFF       PORTD |=0x01;
  
  #define  BUSY_ON		 PORTC |= 0x08
  #define  BUSY_OFF		 PORTC &= ~0x08
  
  #define  NORMAL        PORTB &= ~0x80
  #define  UNNORMAL      PORTB |=0x80
  
  uint Ystep;                            //大于2000在通光区,小于2000在挡光区
  uchar Eflag=0;                         //错误码
  uchar I2cRbuf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};	//IIC总线接收命令 
  uchar I2cSbuf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};   //IIC发送上层命令 
  
   void delay1(uint rate)                //脉冲延时
  {
   uint i;
   for(i=0;i<=rate;i++);
  }

   void delay(uint temp1,uint temp2)     //延时程序
  {   
    uint i;
    uint j;
    for(i=0;i<=temp1;i++)
      for(j=0;j<=temp2;j++);
  }
  
  void port_init()
 {
    DDRB  = 0xD7;               //端口初使化程序
  	PORTB = 0x00;
  	DDRC  = 0x08;
  	PORTC = 0x37;
  	DDRD  = 0xE1;
  	PORTD = 0x81;
 }

  void twi_init()
  {
   //IIc总线初始化
   TWCR  = 0x00; //disable twi.
   TWBR  = 0xC0; //set bit rate 32
   TWSR  = 0x00; //set prescal	TWPS1:0=00
   TWAR = (((PINC & 0x07)+1)<<1) | 0x01;  //local address is 1 ;识别广播地址
   //TWAR = 0X03;//1
   TWAMR = 0x00;
  }
  
   void timer0_init()
  {
	TCCR0B = 0x00; //stop
 	TCCR0A = 0x83; //快速PWM模式,TOP=0xFF,匹配时OC0A为0,TOP时OC0A为1
	OCR0A  = 0x00;
 	TCNT0  = 0x00;
    //  TCCR0B = 0x89; //start timer
  }
  
   void init_devices()
  {
 	CLI(); 
 	port_init();
 	twi_init();
	timer0_init();
  }

  void SetCurrent(uchar curr)
  {
    OCR0A  = curr;
 	TCCR0B = 0x81; //start timer0,不分频
  }

  void ClrCurrent()
  {
    TCCR0B = 0x00; //stop timer0
  }

  void Warn(uchar i)                               //报警程序
  {
   PORTD &= ~0x01;
   Eflag=i;
  }
  
/***************************************
     twi_Sreceive() SR函数
  d_begin=0x00,I2cRbuf[10],d_stop=0xff
****************************************/
  uchar twi_Sreceive()
  {
    uint i;
	uchar n_sr,flag=1;
    i=0;
    /*while(!(TWCR & (1<<TWINT)) && i<=10000)i++;
    if(i>10000)
    {
	   //TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);////////////////
	   //twi_init();
	   TWCR = (1<<TWEA)|(1<<TWEN);
	   return 0;
    }
	
	if((TWSR & 0xF8) == 0x60)
	   TWCR |= (1<<TWINT);
	else
	{
	   //TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);/////////////////////
	   //twi_init();
	   TWCR = (1<<TWEA)|(1<<TWEN);
	   return 0;
	}*/
	
    //wait data receive
    n_sr = 0;
    while(1)
    {
        while(!(TWCR & (1<<TWINT))&& i<=10000)i++;//
        if(i>10000)
        {
			//TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);////////////////
			//twi_init();
	   	    TWCR = (1<<TWEA)|(1<<TWEN);
		    return 0;
        }
		if((TWSR & 0xF8) == 0x80)	   //data
		{
		 	I2cRbuf[n_sr] = TWDR;
        	n_sr++;
			TWCR |= (1<<TWINT);
		}
		else if((TWSR & 0xF8) == 0xA0) //stop
		{
			TWCR |= (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
			return n_sr;
		}
		else if((TWSR & 0xF8) == 0x60) //sla+w
		{
		 	TWCR |= (1<<TWINT);
			n_sr = 0;
			for(i=0; i<10; i++)
			   I2cRbuf[i] = 0;
		}
		else if((TWSR & 0xF8) == 0x00) //bus error
		{
		 	twi_init();
	   		TWCR = (1<<TWEA)|(1<<TWEN);
			return 0;
		}
		else
		{
			//TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);////////////
			//twi_init();
	   		TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
	   		return 0;
		}
    }
   // n_sr=i;//记录接收数据个数
    return n_sr;
  }
    
	
	uchar Reset1(uint FX)             // 勾推杯电机复位,FX为方向标志,1为顺时针
    {
     uint rate;
     uint high;
     uchar j;
	 uint MAXstep;
	 uint step;
	 
	 j=(PINC & 0x07);
	 if(j==0x01)
	   MAXstep=MAXstep1;
	  
	 if(j==0x02)
	    MAXstep=MAXstep2;
	  
	 if(j==0x03)
	   MAXstep=MAXstep3;
     
      high = 45;
     
     SetCurrent(10);
     M_ENABLE;                 //电机使能
     M_HIGHMOVE;               //高压运行
	 rate =180;
	 step=0;

     if(START_GO)
      { 
        if(FX)
		 M_UNCLOCKWISE;
		else M_CLOCKWISE;
        while(START_GO)
        {
          PORTB &=~0x02;
          delay1(rate);
		  PORTB |=0x02;
          delay1(rate);
          if(rate>=high)
           rate-=5;
          step++;
          if(step>MAXstep)
          {
            M_LOWMOVE;
            M_UNENABLE;
			ClrCurrent();
            Warn(1);                         //报警程序
            return 0;
          } 
        } 
        delay(100,1000);
      }
	  
	  step=0;
      rate=180;
	  if(FX)  
       M_CLOCKWISE;
	  else M_UNCLOCKWISE;
      while(!START_GO)
      {
        PORTB &=~0x02;
        delay1(rate);
		PORTB |=0x02;
        delay1(rate);
        if(rate>=high)
           rate-=5;
        step++;
        if(step>MAXstep)
         {
          M_LOWMOVE;
          M_UNENABLE;
		  ClrCurrent();
          Warn(1);                         //报警程序
          return 0;
         } 
      }
	  delay(300, 200);
      M_LOWMOVE;
	  ClrCurrent();
	  //Eflag=0;
	  return 1;
   }
    
  
  uchar Reset2()                         //预温区移动电机复位
  {
    uint rate;
    uint high;
    uchar j;
	uint i;
	uint step;
    high = 100;
     
    M_ENABLE;
    M_HIGHMOVE;
	SetCurrent(10);
   
    if(!START_GO)		              //在挡光区
	{
	   step=0;
	   rate=180;
	   M_UNCLOCKWISE;
	   while(!START_GO)               //走向零点光耦
       {
          PORTB &=~0x02;
          delay1(rate);
		  PORTB |=0x02;
          delay1(rate);
          if(rate>=high)
           rate-=5;
          step++;
          if(step>MAXstepDG)
          {
            M_LOWMOVE;
            M_UNENABLE;
			ClrCurrent();
            Warn(1);                         //报警程序
            return 0;
          } 
       }       
	   for(i=0;i<=50;i++)			//此时已通光
	   {
	      PORTB &=~0x02;
	      delay1(rate);
	      PORTB |=0x02;
	      delay1(rate);
	   }
	   delay(100,1000);
	}
	
    if(START_GO)		 			//在通光区
    {
      rate=180;
	  step=0;
      M_CLOCKWISE;
	  while(START_GO)                //走向零点光耦
      {
        PORTB &=~0x02;
        delay1(rate);
		PORTB |=0x02;
        delay1(rate);
        if(rate>=high)
           rate-=5;
        step++;
        if(step>MAXstepTG)
        {
          M_LOWMOVE;
          M_UNENABLE;
		  ClrCurrent();
          Warn(1);                         //报警程序
          return 0;
        } 
      }
	  for(i=0;i<=50;i++)			//此时已挡光
	  {
	     PORTB &= ~0x02;
	     delay1(rate);
	     PORTB |= 0x02;
	     delay1(rate);
	  }
	  delay(100,1000);
	
	  M_UNCLOCKWISE;
	  rate=180;
	  step=0;
	  while(!START_GO)           //在挡光区走向零点光耦
      {
        PORTB &=~0x02;
        delay1(rate);
		PORTB |=0x02;
        delay1(rate);
        if(rate>=high)
           rate-=5;
        step++;
        if(step>MAXstepDG)
         {
          M_LOWMOVE;
          M_UNENABLE;
		  ClrCurrent();
          Warn(1);                         //报警程序
          return 0;
         } 
      }      
	  M_LOWMOVE;
    }
	Ystep=2000;
	ClrCurrent();
	//Eflag=0;
	return 1;
  }
  
  
  void JBmove(uint step)             //进杯电机动作,step为电机指定步数
  {
   uint rate;
   uint i;
   uint j;
   rate=180;
   
   M_ENABLE;
   M_HIGHMOVE;
   M_CLOCKWISE;
   SetCurrent(10);
   
   for(j=0;j<3;j++)
   {
      for(i=0;i<=step-30;i++)
      {
       PORTB &=~0x02;
	   delay1(rate);
	   PORTB |= 0x02;
	   delay1(rate);
	   if(rate>=100)
	    rate-=3;
      }
      for(i=0;i<=30;i++)
      {
       PORTB &=~0x02;
	   delay1(rate);
	   PORTB |=0x02;
	   delay1(rate);
	   if(rate<=200)
	   rate+=3;
      }
	  if(!START_GO)
	     break;
   }	
   M_LOWMOVE;
   if(START_GO)              //无杯
    Warn(0x11);
   if(!START_GO&&END_GO)     //杯子数不到10
    Warn(0x12);
   delay(100,100);
   ClrCurrent();
  }
  
//勾杯和推杯电机动作,完成一次动作后会复位,FX是方向标志为1时顺时针  
  uchar GTmove(uint FX)                   
  {
   uint i;
   uint rate;
   uchar j;
   uint MAXstep;
   uint high;
   uint step;
   high=45;
   rate=180;
	 
   j=(PINC & 0x07);
   if(j==0x01)
   {
	    MAXstep=MAXstep1;
	    i=1390;
   }
   if(j==0x02)
   {
	    MAXstep=MAXstep2;
		i=1680;
   }
   if(j==0x03)
   {
	    MAXstep=MAXstep3;
		i=1680;
   }
   
   SetCurrent(10);
   M_ENABLE;
   M_HIGHMOVE;
   if(FX)
     M_UNCLOCKWISE;
   else M_CLOCKWISE;
   step=0;
   while(!END_GO)              //加速阶段
      {

⌨️ 快捷键说明

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