/*********************

STC8H3K32S2 LQFP32
STC8H1K24-36I-LQFP32

外部8M晶振

openpnp控制输出500hz（2ms）

1%占空比(20us) - 1号动作 feed
2%占空比(40us) - 2号动作
3%占空比(60us) - 3号动作
8%占空比(160us) - 8号动作 

连级 9-16  id123决定

70%-95% 动作结束  post pick

90度为最远端
**/
#include <STC8H.H>
#include "intrins.h"

#define		z0  (1000 + 155)     //0度高电平时间0.5ms(0.25%PWM) (20ms对应40000,)  20ms*0.025 
#define   z90  3000     //90度高电平时间1.5ms(0.75%PWM)  20ms*0.075

typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD; 

sbit INT0 = P3^2;
sbit L1 = P3^3;   //8mm=1  4mm=0
sbit L2 = P3^4;
sbit L3 = P3^5;
sbit L4 = P3^6;
sbit L5 = P3^7;
sbit L6 = P2^5;
sbit L7 = P2^7;
sbit L8 = P0^0;
sbit SW90 = P0^3;
sbit SW0 = P5^4;
sbit ID1 = P0^1;
sbit ID2 = P0^2;
sbit ID3 = P1^1;

/**********************************
ID1=1 ID2=1 ID3=1 -----------第1个板
ID1=1 ID2=1 ID3=0 -----------第2个
ID1=1 ID2=0 ID3=1 -----------第3个
ID1=1 ID2=0 ID3=0 -----------第4个
ID1=0 ID2=1 ID3=1 -----------第5个
ID1=0 ID2=1 ID3=0 -----------第6个
ID1=0 ID2=0 ID3=1 -----------第7个
ID1=0 ID2=0 ID3=0 -----------第8个

共64个feed
**********************************/

BYTE fy1;  //t2溢出计数
DWORD z1,z2; 
DWORD T1_sl,T1_sl1;
BYTE th0_1,tl0_1,zy2_1;
BYTE t1i=0;
BYTE dz=0; //动作 =1 1#; =2 2#; =0 不动
bit dz1=0;  //=1新动作
WORD pd1,pd2,pd3,pd4,pd5,pd6,pd7,pd8;  //频段

void Timer0Init(void)	 //TIME0 计算脉冲高电平时间
{
	  AUXR |= 0x80;		//定时器时钟1T模式
		TMOD = 0x00;
		TL0 = 0;                               
    TH0 = 0;
		TF0 = 0;		//清除TF0标志
		TR0 = 1;   
}
void Timer1Init(void)			//80毫秒@8MHz  //800ms输出一次频率
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xAB;		//设置定时初始值
	TH1 = 0x2F;		//设置定时初始值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
}
                                    
void Delay600ms()		//@8MHz  500ms
{
	unsigned char i, j, k; 

	_nop_();
	i = 21;
	j = 75;
	k = 189;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}    

void main()
{
	P0=0xff;
	P1=0xff;
	P2=0xff;
	P3=0xff;
	P4=0xff;
	P5=0xff;	
	//P0_Mode_HighZ(PIN_5);	
	P0_Mode_PullUp(PIN_0|PIN_1|PIN_2|PIN_3);
	//P1_Mode_HighZ(PIN_ALL);
	P1_Mode_PullUp(PIN_1);
	P1_Mode_OUT_PP(PIN_0|PIN_2);
	P2_Mode_PullUp(PIN_5|PIN_7);
	P2_Mode_OUT_PP(PIN_0|PIN_1|PIN_2|PIN_3|PIN_4|PIN_6);
	
	P3_Mode_PullUp(PIN_ALL);
	P4_Mode_PullUp(PIN_ALL);
	P5_Mode_PullUp(PIN_ALL);
	
	  P_SW2 = 0x80;

		XOSCCR = 0xc0; //启动外部晶振
		while (!(XOSCCR & 1)); //等待时钟稳定
		CLKDIV = 0x00; //时钟不分频
		CKSEL = 0x01; //选择外部晶振

		P_SW2 = 0x80;
	
		PWMA_PS=0x50;  //pwma _1 _2        //pwma pin脚选择  pwm3 pwm4 换到_2
    PWMA_CCER1 = 0x00;                          //写CCMRx前必须先清零CCERx关闭通道
	  PWMA_CCER2 = 0x00;                          //写CCMRx前必须先清零CCERx关闭通道		
    PWMA_CCMR1 = 0x60;                          //设置CC1为 PWMA输出模式1
		PWMA_CCMR2 = 0x60;
		PWMA_CCMR3 = 0x60;                          
		PWMA_CCMR4 = 0x60;                         //4
    PWMA_CCER1 = 0x11;  //2p 1P
		PWMA_CCER2 = 0x11;  //4P 3P 使能
		PWMA_PSCR = 3;   //4分频
		PWMB_PSCR = 3;   //4分频
		/***************************** //50HZ 舵机
		输出频率=时钟频率/(（PWMA_PSCR+1) * (PWMA_ARR+1))
		50=8000000/(4 * (PWMA_ARR+1))
		50=8000000/(4*PWMA_ARR+4)
		8000000=200*PWMA_ARR+200
		200*PWMA_ARR = 7999800
		PWMA_ARR=39999
		*******************************/		
    PWMA_ARR = 39999;                          //设置周期时间 20ms
		PWMB_ARR = 39999;
		
		PWMB_PS=0; 
    PWMB_CCER1 = 0x00;                         
		PWMB_CCER2 = 0x00;                         
    PWMB_CCMR1 = 0x60;   // 5                     
		PWMB_CCMR2 = 0x60;                         
    PWMB_CCMR3 = 0x60;                         
		PWMB_CCMR4 = 0x60;   //8
		PWMB_CCER1 = 0x11;   //6p 5P
		PWMB_CCER2 = 0x11;  //8P 7P 使能
		                            
		
		PWMA_CCR1 = z90;    // pwm1高电平时间
		PWMA_CCR2 = z90;
		PWMA_CCR3 = z90;
		PWMA_CCR4 = z90;
		PWMB_CCR5 = z90;
		PWMB_CCR6 = z90;
		PWMB_CCR7 = z90;
		PWMB_CCR8 = z90;
		
		PWMA_ENO = 0x55;                            //使能PWM1P 2p 3p 4p端口输出
		PWMA_BKR = 0x80;                            //使能主输出
		PWMA_CR1 = 0x01;                            //开始计时
		PWMB_ENO = 0x55;                            //使能PWM5P 6p 7p 8p端口输出
		PWMB_BKR = 0x80;                            //使能主输出
		PWMB_CR1 = 0x01;                            //开始计时
		
		INT0 = 1;
    IT0 = 0;                    //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿)
    EX0 = 1;                    //使能INT0中断

	  Timer0Init();
		ET0 = 1;                                    //使能定时器中断
		Timer1Init();
		ET1 = 1;
		EA=1;
		while(1)
		{
			if(SW90==0){PWMA_CCR1 = z90;PWMA_CCR2 = z90;PWMA_CCR3 = z90;PWMA_CCR4 = z90;PWMB_CCR5 = z90;PWMB_CCR6 = z90;PWMB_CCR7 = z90;PWMB_CCR8 = z90;while(!SW90);}
			if(SW0==0){PWMA_CCR1 = z0;PWMA_CCR2 = z0;PWMA_CCR3 = z0;PWMA_CCR4 = z0;PWMB_CCR5 = z0;PWMB_CCR6 = z0;PWMB_CCR7 = z0;PWMB_CCR8 = z0;while(!SW0);}
			if(dz1==1&&dz==1){dz1=0;PWMA_CCR1 = z0;Delay600ms();PWMA_CCR1 = z90;if(L1==0){Delay600ms();PWMA_CCR1 = z0;Delay600ms();PWMA_CCR1 = z90;}}
			if(dz1==1&&dz==2){dz1=0;PWMA_CCR2 = z0;Delay600ms();PWMA_CCR2 = z90;if(L2==0){Delay600ms();PWMA_CCR2 = z0;Delay600ms();PWMA_CCR2 = z90;}}
			if(dz1==1&&dz==3){dz1=0;PWMA_CCR3 = z0;Delay600ms();PWMA_CCR3 = z90;if(L3==0){Delay600ms();PWMA_CCR3 = z0;Delay600ms();PWMA_CCR3 = z90;}}
			if(dz1==1&&dz==4){dz1=0;PWMA_CCR4 = z0;Delay600ms();PWMA_CCR4 = z90;if(L4==0){Delay600ms();PWMA_CCR4 = z0;Delay600ms();PWMA_CCR4 = z90;}}
			if(dz1==1&&dz==5){dz1=0;PWMB_CCR5 = z0;Delay600ms();PWMB_CCR5 = z90;if(L5==0){Delay600ms();PWMB_CCR5 = z0;Delay600ms();PWMB_CCR5 = z90;}}	
			if(dz1==1&&dz==6){dz1=0;PWMB_CCR6 = z0;Delay600ms();PWMB_CCR6 = z90;if(L6==0){Delay600ms();PWMB_CCR6 = z0;Delay600ms();PWMB_CCR6 = z90;}}
			if(dz1==1&&dz==7){dz1=0;PWMB_CCR7 = z0;Delay600ms();PWMB_CCR7 = z90;if(L7==0){Delay600ms();PWMB_CCR7 = z0;Delay600ms();PWMB_CCR7 = z90;}}
			if(dz1==1&&dz==8){dz1=0;PWMB_CCR8 = z0;Delay600ms();PWMB_CCR8 = z90;if(L8==0){Delay600ms();PWMB_CCR8 = z0;Delay600ms();PWMB_CCR8 = z90;}}	
		}
}		

/*********************************************************************************************/
void TM0_Isr() interrupt 1           //中断入口
{
				fy1++;
}
/***********************************************************************************/
void TM1_Isr() interrupt 3  	//80毫秒@8MHz  //80ms计算一次频率
				{
					t1i++;
					if(t1i>=1)
					{
						t1i=0;
						//T1_sl=T1_sl1/8000000;  //s
						T1_sl=T1_sl1/8;  //us
							/*********************8M*******
							openpnp控制输出500hz（2ms）
							1%(20us)  2%(40us)  8%
							9%占空比(180us) - 第二块板1动作
							10%占空比(200us) - 第二块板2动作
							64%占空比(1280us) - 第八块板8动作
							******************************/
						/**********************************
						ID1=1 ID2=1 ID3=1 -----------第1块板
						ID1=1 ID2=1 ID3=0 -----------第2块板
						ID1=1 ID2=0 ID3=1 -----------第3块板
						ID1=1 ID2=0 ID3=0 -----------第4块板
						ID1=0 ID2=1 ID3=1 -----------第5块板
						ID1=0 ID2=1 ID3=0 -----------第6块板
						ID1=0 ID2=0 ID3=1 -----------第7块板
						ID1=0 ID2=0 ID3=0 -----------第8块板
						**********************************/
						if(ID1==1&&ID2==1&&ID3==1){pd1=20;pd2=40;pd3=60;pd4=80;pd5=100;pd6=120;pd7=140;pd8=160;} //---第1个
						if(ID1==1&&ID2==1&&ID3==0){pd1=180;pd2=200;pd3=220;pd4=240;pd5=260;pd6=280;pd7=300;pd8=320;} //---第2个
						if(ID1==1&&ID2==0&&ID3==1){pd1=340;pd2=360;pd3=380;pd4=400;pd5=420;pd6=440;pd7=460;pd8=480;} //---第3个
						if(ID1==1&&ID2==0&&ID3==0){pd1=500;pd2=520;pd3=540;pd4=560;pd5=580;pd6=600;pd7=620;pd8=640;} //---第4个
						if(ID1==0&&ID2==1&&ID3==1){pd1=660;pd2=680;pd3=700;pd4=720;pd5=740;pd6=760;pd7=780;pd8=800;} //---第5个
						if(ID1==0&&ID2==1&&ID3==0){pd1=820;pd2=840;pd3=860;pd4=880;pd5=900;pd6=920;pd7=940;pd8=960;} //---第6个
						if(ID1==0&&ID2==0&&ID3==1){pd1=980;pd2=1000;pd3=1020;pd4=1040;pd5=1060;pd6=1080;pd7=1100;pd8=1120;} //---第7个
						if(ID1==0&&ID2==0&&ID3==0){pd1=1140;pd2=1160;pd3=1180;pd4=1200;pd5=1220;pd6=1240;pd7=1260;pd8=1280;} //---第8个					
						
						///////////////////////////////////////////////////
						
						     if(T1_sl>=pd1-10 && T1_sl<pd1+10){dz=1;}  //1
						else if(T1_sl>=pd2-10 && T1_sl<pd2+10){dz=2;}  //2
						else if(T1_sl>=pd3-10 && T1_sl<pd3+10){dz=3;}  //3
						else if(T1_sl>=pd4-10 && T1_sl<pd4+10){dz=4;}  //4
						else if(T1_sl>=pd5-10 && T1_sl<pd5+10){dz=5;}   //5
						else if(T1_sl>=pd6-10 && T1_sl<pd6+10){dz=6;}   //6
						else if(T1_sl>=pd7-10 && T1_sl<pd7+10){dz=7;}    //7
						else if(T1_sl>=pd8-10 && T1_sl<pd8+10){dz=8;}    //8
						else{dz1=1;dz=0;}  //新动作
						
						//if(dz_f!=dz){dz1=1;dz=0;}		 //新动作
					}
				}
/***********************************************************************************/				
void INT0_Isr() interrupt 0
{
    if (INT0)                                   //判断上升沿和下降沿
    {
					TR0 = 0;
						if(TF0) {fy1++;TF0=0;}
						th0_1=TH0;
						tl0_1=TL0;
						zy2_1=fy1;
					TR0 = 1;
						((BYTE *)&z1)[3] = tl0_1;  //保存本次的捕获值
						((BYTE *)&z1)[2] = th0_1;
						((BYTE *)&z1)[1] = zy2_1;
						((BYTE *)&z1)[0] = 0;
    }
    else
    {
      
					TR0 = 0;
						if(TF0) {fy1++;TF0=0;}
						th0_1=TH0;
						tl0_1=TL0;
						zy2_1=fy1;
					TR0 = 1;
						((BYTE *)&z2)[3] = tl0_1;  //保存本次的捕获值
						((BYTE *)&z2)[2] = th0_1;
						((BYTE *)&z2)[1] = zy2_1;
						((BYTE *)&z2)[0] = 0;
						T1_sl1 = z2 - z1;   //计算两次捕获的差值,即得到时间长度
						((BYTE *)&T1_sl1)[0] = 0;  
		}
}
		