📄 h.c
字号:
//宽中窄OK。8月29日12:30
//构造一个结构,包括GDJSH,GDJSL,MOTOR,
//高度计数值不由BOTTOM发到HAND,而是由HAND把区间设定的上高度值和下高度值发到BOTTOM,自动行走功能由BOTTOM实现。
//8月21日开始编辑功能程序
//总算通上了。17:32。happy happy happy
///8月20日17点,HAND接收后,T1中断可以工作,但HAND再发送就发不出去
//8月20日15点半,HAND发到BACK和BOTTOM功能正常,BACK可以发数据到HAND,但HAND收到数据后不能工作。
//总算弄清楚一个问题。由于器件作为从机一直处于接受态。主动操作时,必须清除所有可能产生的SSPIF
//hand不要READ(),只要WRITE()
//用定时读的方法不好实现。决定采用多主模式。8月18日13点
//倒背已调好。8月17日15点。现在开始调揉捏电机
//8月17日,#define XZDJB receiv[0] //行走电机。上述定义没有问题
//今天,调试与bottom的通信。
//现在改为以下定义,问题已解决。这样的定义k_value1 @ 0x20;k_value2 @ 0x21;与bit定义冲突,bit是从0x20开始的
//这样的定义k_value1 @ 0x7e;k_value2 @ 0x7f;与intsave | Registers saved on interrupt | $007F - $007F定
//义冲突,以前没有注意到这样的问题。2005年8月17日。
//static volatile unsigned char k_value1 @ 0x70;
//static volatile unsigned char k_value2 @ 0x71;
///*MCU=PIC16F73,编程曾敏辉 2005年8月9日*///
//按摩椅24V电控系统规划
//1、 背部(机芯)
//负载:揉捏电机、锤击电机、三维电机
//信号输入:宽中窄、光电行程、揉捏电机速度、锤击电机速度、三维电机速度
//2、 座部
//负载:行走电机(双向)、气泵、泄气阀4个、振动电机4个、倒背电机(双向)、抬小腿电机(双向)、小腿夹揉、加热
//信号输入:高度计数
//
//通信协议:
//下行报文(主——从):由16个字节组成
//序号 代号 负载(座部)0X20 代号 负载(背部)0X30 代号
//1 SEND[0] 行走电机(双向) XZDJ 揉捏电机(双向) RNDJ
//2 SEND[1] 行走电机速度 XZDJSD 揉捏电机速度 RNDJSD
//3 SEND[2] 倒背电机(双向) DBDJ 三维电机(双向) SWDJ
//4 SEND[3] 倒背电机速度 DBDJSD 三维电机速度 SWDJSD
//5 SEND[4] 小腿夹揉电机 XTJRDJ 锤击电机 CJDJ
//6 SEND[5] 小腿夹揉电机速度 XTJRDJSD 锤击电机速度 CJDJSD
//7 SEND[6] 抬小腿电机(双向) TXTDJ 备用 NC
//8 SEND[7] 加热、气泵 JRQB 备用 NC
//9 SEND[8] 泄气阀1~8 XQF 备用 NC
//10 SEND[9] 振动电机1~8 ZDDJ 备用 NC
//11 SEND[10] 备用 NC 备用 NC
//12 SEND[11] 备用 NC 备用 NC
//13 SEND[12] 备用 NC 备用 NC
//14 SEND[13] 备用 NC 备用 NC
//15 SEND[14] 备用 NC 备用 NC
//16 SEND[15] 备用 NC 备用 NC
//各字节含义:
//XZDJ
//D7 D6 D5 D4 D3 D2 D1 D0
//启/停 正/反 手动标志
//RNDJ
//D7 D6 D5 D4 D3 D2 D1 D0
//启/停 正/反 宽 中 窄 设定标志
//DBDJ、SWDJ、TXTDJ
//D7 D6 D5 D4 D3 D2 D1 D0
//启/停 正/反 分/秒 运行持续时间
//
//XTJRDJ、CJDJ
//D7 D6 D5 D4 D3 D2 D1 D0
//启/停 分/秒 运行持续时间
//
//JRQB
//D7 D6 D5 D4 D3 D2 D1 D0
//加热启/停 分/秒 气泵启/停 分/秒
//
//XQF、ZDDJ
//D7 D6 D5 D4 D3 D2 D1 D0
//启/停 启/停 启/停 启/停 启/停 启/停 启/停 启/停
//
//
//上行报文(从——主):由8个字节组成
//序号 代号 输入信号(座部)0X20 代号 输入信号(背部)0X30 代号
//1 RECEIV[0] 高度计数高字节 GDJSH 光电行程 GDXC
//2 RECEIV[1] 高度计数低字节 GDJSL 宽中窄 KZZ
//3 RECEIV[2] 备用 NC 锤击电机速度 CJDJSD
//4 RECEIV[3] 备用 NC 揉捏电机速度 RNDJSD
//5 RECEIV[4] 备用 NC 三维电机速度 SWDJSD
//6 RECEIV[5] 备用 NC 备用 NC
//7 RECEIV[6] 备用 NC 备用 NC
//8 RECEIV[7] 备用 NC 备用 NC
//
//字节含义:
//GDJSH(高字节):下限位,其值为0,上限位,其值最大
//D7 D6 D5 D4 D3 D2 D1 D0
//限位/无 计数值(上行时,光耦跳变1次增1;下行时,光耦跳变1次减1)
//
//GDJSL(低字节):
//D7 D6 D5 D4 D3 D2 D1 D0
//计数值(上行时,光耦跳变1次增1;下行时,光耦跳变1次减1)
//
//RNDJSD:
//D7 D6 D5 D4 D3 D2 D1 D0
//限位/无 光耦跳变2次的间隔时间
//
//SWDJSD:
//D7 D6 D5 D4 D3 D2 D1 D0
//限位/无 光耦跳变2次的间隔时间
//
//CDDJSD:
//D7 D6 D5 D4 D3 D2 D1 D0
//限位/无 光耦跳变2次的间隔时间
//
//KZZ:
//D7 D6 D5 D4 D3 D2 D1 D0
//限位/无 光耦跳变2次的间隔时间
//
//GDXC:
//D7 D6 D5 D4 D3 D2 D1 D0
//限位/无 光耦跳变2次的间隔时间
//
#include <pic.h>
//i2c定义
#define SCL RC3 /* clock on port C bit 2 */
#define SCL_DIR TRISC3
#define SDA RC4 /* data on port C bit 1 */
#define SDA_DIR TRISC4
#define I2CTRIS TRISC
#define MASTER_MODE 0B1011 /* I2C firmware controlled Master Mode (slave idle) */
#define SSPMode(val) SSPCON &=0xF0; SSPCON|=(val & 0xf)
#define I2C_INPUT 1 /* data direction input */
#define I2C_OUTPUT 0 /* data direction output */
#define I2C_READ 0x01 /* read bit used with address */
#define I2C_WRITE 0x00 /* write bit used with address */
#define SCL_HIGH() SCL_DIR = I2C_INPUT
#define SCL_LOW() SCL_DIR = I2C_OUTPUT
#define SDA_HIGH() SDA_DIR = I2C_INPUT
#define SDA_LOW() SDA_DIR = I2C_OUTPUT
#define HAND 0x10
#define BACK 0x20
#define BOTTOM 0x30
//按键定义(伊能)
#define onoff_k k8 //power开关
#define easy_k k6 //轻松程序
#define sleep_k k10 //睡眠程序
#define cure_k k14 //理疗程序
#define width_k k9 //宽度
#define area_k k12 //区间
#define go_up_k k7 //上行
#define go_down_k k11 //下行
#define massage_k k1 //推拿K1
#define knock_k k2 //敲击K2
#define anti_knead_k k0 //摆揉K0
#define knead_k k3 //揉捏K2
#define speed_inc_k k4 //速度增
#define speed_dec_k k5 //速度减
#define fall_k k15 //倒背
//指示灯定义
#define power_on_led() led_ram[1]=led_ram[1]|0b00000100 //power开
#define power_off_led() led_ram[1]=led_ram[1]&0b11111011 //power关
#define easy_on_led() led_ram[0]=led_ram[0]|0b00000100 //轻松程序开
#define easy_off_led() led_ram[0]=led_ram[0]&0b11111011 //轻松程序关
#define sleep_on_led() led_ram[2]=led_ram[2]|0b00000010 //睡眠程序开
#define sleep_off_led() led_ram[2]=led_ram[2]&0b11111101 //睡眠程序开
#define cure_on_led() led_ram[2]=led_ram[2]|0b00000100 //理疗程序开
#define cure_off_led() led_ram[2]=led_ram[2]&0b11111011 //理疗程序关
#define width_max_on_led() led_ram[4]=led_ram[4]|0b00000001 //宽度,宽开
#define width_max_off_led() led_ram[4]=led_ram[4]&0b11111110 //宽度,宽关
#define width_mid_on_led() led_ram[4]=led_ram[4]|0b00000100 //宽度,中开
#define width_mid_off_led() led_ram[4]=led_ram[4]&0b11111011 //宽度,中关
#define width_min_on_led() led_ram[4]=led_ram[4]|0b00000010 //宽度,窄开
#define width_min_off_led() led_ram[4]=led_ram[4]&0b11111101 //宽度,窄关
#define area_up_on_led() led_ram[5]=led_ram[5]|0b00000001 //区间,上开
#define area_up_off_led() led_ram[5]=led_ram[5]&0b11111110 //区间,上关
#define area_mid_on_led() led_ram[5]=led_ram[5]|0b00000010 //区间,中开
#define area_mid_off_led() led_ram[5]=led_ram[5]&0b11111101 //区间,中关
#define area_down_on_led() led_ram[5]=led_ram[5]|0b00000100 //区间,下开
#define area_down_off_led() led_ram[5]=led_ram[5]&0b11111011 //区间,下关
#define go_up_on_led() led_ram[3]=led_ram[3]|0b00000010 //上行开
#define go_up_off_led() led_ram[3]=led_ram[3]&0b11111101 //上行关
#define go_down_on_led() led_ram[3]=led_ram[3]|0b00000100 //下行开
#define go_down_off_led() led_ram[3]=led_ram[3]&0b11111011 //下行关
#define massage_on_led() led_ram[1]=led_ram[1]|0b00000001 //推拿开
#define massage_off_led() led_ram[1]=led_ram[1]&0b11111110 //推拿关
#define knock_on_led() led_ram[2]=led_ram[2]|0b00000001 //敲击开
#define knock_off_led() led_ram[2]=led_ram[2]&0b11111110 //敲击关
#define anti_knead_on_led() led_ram[0]=led_ram[0]|0b00000001 //摆揉开
#define anti_knead_off_led() led_ram[0]=led_ram[0]&0b11111110 //摆揉关
#define knead_on_led() led_ram[3]=led_ram[3]|0b00000001 //揉捏开
#define knead_off_led() led_ram[3]=led_ram[3]&0b11111110 //揉捏关
#define speed_inc_on_led() led_ram[0]=led_ram[0]|0b00000010 //速度增开
#define speed_inc_off_led() led_ram[0]=led_ram[0]&0b11111101 //速度增关
#define speed_dec_on_led() led_ram[1]=led_ram[1]|0b00000010 //速度减开
#define speed_dec_off_led() led_ram[1]=led_ram[1]&0b11111101 //速度减关
#define SPEED_STEP 50 //10*10=500ms,速度跳变1次
#define HIGH 0x00 //高速
#define MIDDLE 0x10 //中速
#define LOW 0x20 //低速
#define KUAN 0x09 //宽
#define ZHONG 0x05 //中
#define ZHAI 0x03 //窄
/*back BYTE DEFINE*/
/*master write to slave*/
#define RNDJB send1[0] //揉捏电机
#define RNDJSDB send1[1] //揉捏电机速度
#define SWDJB send1[2] //三维电机
#define SWDJSDB send1[3] //三维电机速度
#define CJDJB send1[4] //锤击电机
#define CJDJSDB send1[5] //锤击电机速度
/*master read from slave*/
#define GDXCB receiv1[0] //光电行程检测
#define CJSD receiv1[2] //锤击速度
#define RNSD receiv1[3] //揉捏速度
#define SWSD receiv1[4] //三维速度
#define KZZB receiv1[5] //宽中窄检测
/*bottom BYTE DEFINE*/
/*master write to slave*/
#define XZDJB send0[0] //行走电机
#define XZDJSDB send0[1] //行走电机速度
#define DBDJB send0[2] //倒背电机
#define DBDJSDB send0[3] //倒背电机速度
#define XTJRDJB send0[4] //小腿夹揉电机
#define XTJRDJSDB send0[5] //小腿夹揉电机速度
#define TXTDJB send0[6] //抬小腿电机
#define JRQBB send0[7] //加热气泵
#define XQFB send0[8] //泄气阀
#define ZDDJB send0[9] //振动电机
#define GDJSH send0[10] //高度计数高端值
#define GDJSL send0[11] //高度计数低端值
#define GDXCB send0[12] //光电行程检测
#define POWERB send0[13] //24V电源接通
unsigned char speed_count,key_count,i2c_count,led_count;
unsigned char massage_count;
unsigned char knock_count;
unsigned char knead_count;
unsigned char anti_knead_count;
unsigned char addr;
unsigned char receiv0[8],send0[16]; //bottom
unsigned char receiv1[8],send1[16]; //back
bit i2cerror,ACK0,SDABIT;
bit i2c_idle_flag;
bit cycle_flag;
bit key_flag;
bit track_flag;
bit power_flag;
bit knead_flag;
bit knock_flag;
bit fall_flag;
bit rise_flag;
unsigned char led_ram[6],led_i;
//*************key define*********************************************//
static volatile unsigned char k_value1 @ 0x30;
static volatile unsigned char k_value2 @ 0x31;
static volatile bit k7 @ (unsigned)&k_value1*8+7;
static volatile bit k6 @ (unsigned)&k_value1*8+6;
static volatile bit k5 @ (unsigned)&k_value1*8+5;
static volatile bit k4 @ (unsigned)&k_value1*8+4;
static volatile bit k3 @ (unsigned)&k_value1*8+3;
static volatile bit k2 @ (unsigned)&k_value1*8+2;
static volatile bit k1 @ (unsigned)&k_value1*8+1;
static volatile bit k0 @ (unsigned)&k_value1*8+0;
static volatile bit k15 @ (unsigned)&k_value2*8+7;
static volatile bit k14 @ (unsigned)&k_value2*8+6;
static volatile bit k13 @ (unsigned)&k_value2*8+5;
static volatile bit k12 @ (unsigned)&k_value2*8+4;
static volatile bit k11 @ (unsigned)&k_value2*8+3;
static volatile bit k10 @ (unsigned)&k_value2*8+2;
static volatile bit k9 @ (unsigned)&k_value2*8+1;
static volatile bit k8 @ (unsigned)&k_value2*8+0;
//*********************************系统程序**********************************************************//
delay_ctrl(void)
{
unsigned char i,j;
for(j=0;j<30;j++)
{
for(i=0;i<30;i++)
{asm("clrwdt");}
}
}
//系统程序处理,通信,按键扫描和LED灯显示
//*********************************按键扫描程序******************************************************//
scan_key(void)
{
unsigned char a;
if(!key_flag)
{
a=0xf0;
PORTB=a;
a=PORTB;
if(a!=0xf0)
{key_flag=1;} //first,判断是否有键按下,有,key_flag=1
else
{
k_value1=0;
k_value2=0; //无键按下,清除键值
}
}
else
{
key_flag=0; //next,逐行扫描,确定键值
a=0x10;
PORTB=a;
a=PORTB;
a=a&0x0f;
switch(a)
{
case 0x01:{k0=1;}break;
case 0x02:{k1=1;}break;
case 0x04:{k2=1;}break;
case 0x08:{k3=1;}break;
default: break;
}
a=0x20;
PORTB=a;
a=PORTB;
a=a&0x0f;
switch(a)
{
case 0x01:{k4=1;}break;
case 0x02:{k5=1;}break;
case 0x04:{k6=1;}break;
case 0x08:{k7=1;}break;
default: break;
}
a=0x40;
PORTB=a;
a=PORTB;
a=a&0x0f;
switch(a)
{
case 0x01:{k8=1;}break;
case 0x02:{k9=1;}break;
case 0x04:{k10=1;}break;
case 0x08:{k11=1;}break;
default: break;
}
a=0x80;
PORTB=a;
a=PORTB;
a=a&0x0f;
switch(a)
{
case 0x01:{k12=1;}break;
case 0x02:{k13=1;}break;
case 0x04:{k14=1;}break;
case 0x08:{k15=1;}break;
default: break;
}
}
}
//**********************************scan led code************************************************//
scan_led(void)
{
unsigned char a;
a=led_i;
PORTA=led_ram[a];
switch(a)
{
case 0x00:{PORTC=0b11111110;}break;
case 0x01:{PORTC=0b11111101;}break;
case 0x02:{PORTC=0b11111011;}break;
case 0x03:{PORTC=0b11011111;}break;
case 0x04:{PORTC=0b10111111;}break;
case 0x05:{PORTC=0b01111111;}break;
default: break;
}
a++;
if(a>5)
{a=0;}
led_i=a;
}
//**********************************延时程序****************************************************//
delay(void)
{
unsigned char i;
for(i=0;i<8;i++)
{asm("nop");}
}
//************************************************************************************************//
//**********************************i2c write code***********************************************//
i2c_write(unsigned char addr)
{
unsigned char a,b,c,i,j;
delay();
c=addr;
addr=addr&0xfe;
a=addr|0x00; //write,A0=0
SDA_HIGH();
SCL_HIGH();
SDA_LOW(); //start i2c
SSPIF=0;
for(i=0;i<8;i++)
{
SCL_LOW();
b=a&0x80;
if(b==0x80)
{SDA_HIGH();}
else
{SDA_LOW();}
SCL_HIGH();
a=a<<1;
}
SCL_LOW();
delay();
SDA_HIGH();
ACK0=SDA;
SCL_HIGH(); //9 rise edge
SSPIF=0;
if(!ACK0)
{
for(i=0;i<16;i++)
{
if(c==BOTTOM)
{a=send0[i];}
if(c==BACK)
{a=send1[i];}
for(j=0;j<8;j++)
{
SCL_LOW();
b=a&0x80;
if(b==0x80)
{SDA_HIGH();}
else
{SDA_LOW();}
SCL_HIGH();
a=a<<1;
}
SCL_LOW();
delay();
SDA_HIGH();
ACK0=SDA; //detect ACK signal
SCL_HIGH();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -