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

📄 neck.c

📁 C语言程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <pic18fxx2.h>
#define UCHAR unsigned char  
#define TZ  0          //按摩停止;
#define RN  1          //按摩揉捏;
#define PD  2          //按摩拍打;
#define RP  5          //揉捏拍打;
#define ZY  4          //按摩指压;
#define QJ  3          //敲击;
   
#define DISCHARGETIME 20                 //电机放电时间  20x5=100ms,5ms为单位时间单位;
#define TRANSDIRTIME  4                  //电机换向稳定时间 4x5ms=20ms;
#define POWEROFFTIME  2                  //断电稳定时间 2x5ms=10ms;
#define RETURNTIME    2                  //回复到待机状态时稳定时间 2x5ms=10ms;

#define FULL_LONG       120              //丝杆全长,上下行程间的距离,包括的圈数;
#define SHOULD_LOCATION0 20              //从上行程开关处到肩位置0处包括的圈数;
#define SHOULD_UNIT      5               //五个肩位置点之间的间距即包括的圈数;
#define PART_CYCLE      20               //局部工作时,上下移动范围;

UCHAR KneadSpeed[5]={0xef,0xdf,0xcf,0xbf,0xaf};
UCHAR FlapSpeed[5]={0xef,0xe3,0xd6,0xc9,0xbc};
UCHAR FingerSpeed[5]={0xf4,0xef,0xe9,0xe3,0xde};
UCHAR KnockSpeed[5]={0xef,0xe7,0xd9,0xd0,0xcb};
UCHAR KneadFlapSpeed[5][2]={{0xef,0xef},{0xdf,0xe3},{0xcf,0xd6},{0xbf,0xc9},{0xaf,0xbc}};
UCHAR AutoLocationSet[3][2]={{0,40},{80,120},{0,120}};
UCHAR UpLocationSet,DwLocationSet;
UCHAR nCurMoveDir,UpMoveDir,DwMoveDir,nPreMoveDir;                     //移动方向,0 停止 1 向下 2 向上;
UCHAR nCurMassState,nPreMassState,nCurMassSpeed,nPreMassSpeed;
bit bPreWidthB,bCurWidthB,bPreWidthA,bCurWidthA;
UCHAR widthcount,nCurWidthValue,nPreWidthValue;
UCHAR key,k,m=0,n=0,KeyOff=0,KeyOn=0;
UCHAR nTimeCount,nMoveTimeCount,nCurMoveCycle,nMoveCycleCount,CycleTimeCount;
bit bUpperOn,bFullAutoOn,bNeckAutoOn,WaistAutoOn,bDischarge,bDischargeComplete;
bit bCurCycleState,bPreCycleState,accycleflag;                        //圈数电平状态;
                                                                       
/*********************************************************************/

void CCPINIT();                                   //CCP模块PWM输出初始化程序;
void Delay_ms(UCHAR nTimeValue);                  //延时子程序;
void Initial_port();                              //端口初始化;
void widthajust();                                //宽度调整;
void tmint();                                     //定时器初始化;
void Initial_USART();                             //USART异步发送接收初始化;
void systemInit();                                //系统初始化;
void CycleDetect();                               //移动圈数检测;
void masscontrol();                               //按摩方法控制;
void Task();                                      //功能键判别及功能选择;

/**********************************************************************************/
/*                                中断函数                                        */
/**********************************************************************************/   
    
 void interrupt HI_ISR()                          //高优先级中断入口函数;
{
 if(TMR0IF==1)
 {
   TMR0IF=0;
   m++;
   if(m==10)
  {
    m=0;
    n++;
    if(n==1)
    {
    CCPR2L=0xff;
    }
    if(n==2)
    {
     CCPR2L=0xef;
     n=0;
    } 
  }
   TMR0H=0x3C;
   TMR0L=0xAF;                                    //对TMR0定时50ms写入一个初值; 
  }
}

 void interrupt low_priority LOW_ISR()            //低优先级中断入口函数;
{
  if(RCIF==1)                                     //取接收值,并清串口接收标志位;
  {
     k=RCREG;                                    
    if(k=0xFF)                                   //与从机建立握手信号,接收到
     key=1;
     else key=0;                                                                                              
  }
}

/*******************************************************************************/
 /*                  初始化函数                                   */
/*******************************************************************************/
                                                                                 
 void Initial_port()                             //端口初始化;
{
    ADCON1=0x0e;                                 //设置A,E端口为普通数字I/O,只有RA0为模拟输入端口;
    TRISE=TRISE|0x07;                            //设置各I/O口方向寄存器;
    TRISB=TRISB|0xFF;
    TRISD=TRISD&0x3F;
    PORTD=PORTD&0x3F;
}

 void CCPINIT()                                  //该程序用于使CCP模块产生分辨率为10位的PWM波形,占空比可选;
{                                                //CCP模块的PWM工作方式初始化子程序;
 TRISC=TRISC&0xF9;                               //设置CCP2、CCP1引脚为输出方式;
 PR2=0xFF;                                       //设置PWM的工作周期;
 CCPR1L=0xFF;    
 CCPR2L=0xFF;     
 CCP1CON=CCP1CON|0x3C;                           //CCP1的PWM输出;
 CCP2CON=CCP2CON|0x3C;                           //CCP2的PWM输出;
 T2CON=0x04;                                     //预分频比设置为1:1;
} 

 void Initial_USART()  //USART异步发送接收初始化;
{ 
 TXSTA=0x04;          // 选择异步高速方式传输8位数据;
 RCSTA=0x80;          // 允许串行口工作使能;
 TRISC=TRISC|0x80;    // PIC18F452:将RC7(RX)设置为输入方式; 
 TRISC=TRISC&0xbf;    // RC6(TX)设置为输出;
 SPBRG=25;            // 4M晶振,波特率9600;
 PIE1=PIE1|0x20;      //允许串行通讯接口(USART)接收中断使能;
 CREN=1;              // 允许串口接收数据;
 TXEN=0;              // 允许串口发送数据;
 RCIP=0; 
}
	
 void tmint()
{
 INTCON=INTCON|0x20;   //设置允许TMR0中断;
 INTCON=INTCON&0xFB;   //清除TMR0的中断标志;
 IPEN=1;               //中断优先级使能;
 T1CON=0x00;
 TMR1H=0xec;
 TMR1L=0x78;           //启动TMR1,定时时间为5ms,晶振为4.000M;
 T0CON=0x09;           //设定TMR0工作于16位定时器方式,使用内部时钟,不分频;
 TMR0H=0x3C;
 TMR0L=0xAF;           //对TMR0定时50ms写入一个初值; 
}
	
 void systemInit()
{
    Initial_port();                              //端口初始化;
    CCPINIT(); 
    INTCON=0x00;                                 //禁止总中断和外围中断;
    INTCON2=0x80;
    INTCON3=0x00;
    PIE1=0x00;
    PIE2=0x00;
    PIR1=0x00;	                                 //清中断标志;
	  PIR2=0x00;                                   //清中断标志;
    Initial_USART();                             //USART异步发送接收初始化;
    tmint();                                     //定时器初始化; 
}

/**********************************************************************************/
/*                     子函数                                                     */
/**********************************************************************************/                                        
//延时--以1ms为单位--晶体振荡(4.0MHz)
 void Delay_ms(UCHAR nTimeValue)
{
	UCHAR i;
	while(nTimeValue--)
	{
		for(i=0;i<50;i++)
		{
			asm("nop");asm("nop");asm("nop");asm("nop");
			asm("nop");asm("nop");asm("nop");asm("nop");
			asm("nop");asm("nop");asm("nop");asm("nop");
			asm("nop");asm("nop");asm("nop");asm("nop");
			asm("nop");asm("nop");	
		}	
	}
}

 void widthajust()                                   //机械手宽度调整函数;
{
  CCPR1L=KneadSpeed[0];                               //以最慢的揉捏速度调整宽度;                               
  bPreWidthB=bCurWidthB;
  bPreWidthA=bCurWidthA;
  bCurWidthA=RB4;
  bCurWidthB=RB3;
   if(RBIF)
  {
     if(bCurWidthA==0)                               //等待脉冲下降沿的到来;
	   bWidthProcess=1;                              //当达到最宽时,开始调整宽度;                               
     else if(bCurWidthB==0&&bWidthProcess)           //脉冲下降沿的到来;
	     widthcount++;                               //到来后,计数器增加1;
        RBIF=0;
  }
    if(widthcount==2)                                //判断是否到达宽度中等;
 	 {
 	  widthcount=0;                                  //波形计数器清0;
 	  bWidthProcess=0;
 	  bWidthComplete=1;
 	  CCPR1L=0xff; 
 	   break; 	
 	  }                                
}

 void CycleDetect()                                  //圈数检测函数;
{
   bCurCycleState=RE2;
   if(bCurCycleState!=bPreCycleState&&bCurCycleState)
       accycleflag=1;
    if(accycleflag&&bCurCycleState)
     CycleTimeCount++;
   else 
     {CycleTimeCount=0;
       accycleflag=0;}
    if(CycleTimeCount==3)                                
   {nMoveCycleCount++;     
    CycleTimeCount=0;
    accycleflag=0;}
   bPreCycleState=bCurCycleState; 
}

 void masscontrol()                                   //按摩手法控制函数;
{
     if(nCurMassState!=nPreMassState)
  {
      TMR0ON=0;                                       //关闭定时器0;
      switch(nCurMassState)                           //判断按摩方法及速度选择;
    {
      case 0: CCPR2L=0xff; 
              CCPR1L=0xff;                            //按摩停止;
              break;
      case 1:           
              CCPR2L=0xff; 
              CCPR1L=KneadSpeed[nCurMassSpeed];       //开启揉捏马达;  
              break;
 	    case 2: 
              CCPR1L=0xff;
              CCPR2L=FlapSpeed[nCurMassSpeed];        //开始拍打按摩;
 	            break;
      case 3:                                         //糅捏拍打功能;
              CCPR1L=0xff;                            //开始敲击按摩;

⌨️ 快捷键说明

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