📄 neck.c
字号:
#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 + -