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

📄 h.c

📁 用PIC单片机对直流电机的控制,用在按摩椅上的.有倒背,敲打等功能.
💻 C
📖 第 1 页 / 共 3 页
字号:
//宽中窄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 + -