📄 keil00.c
字号:
/*********************************************************
2007.4.03
**********************************************************
A3986步进驱动控制板硬件定义
P00~~~P07--------方位I1~~~I8 P11---出牌计数
P10---有无牌检测 P12---LED灯 P14---出牌电机
P13---传动电机 P32---RS485cs P33---传感器电源控制
P34---按键 P36---A3986_Vref P35---A3986时钟输入
P37---转动方向 P23---A3986_EN P23---A3986_EN
P21---A3986_SR(衰减有效) P24.P25---A3986_PFD1.PFD2(衰减选择)
P22---A3986_RST P24.P25---A3986_MS1.MS2(细分选择)
***************************************************************
计数传感器有牌为H.无牌为L----有牌检测传感器有牌为L.无牌为H
***************************************************************
通信协议:前导码RB+接收编号+发送编号+命令+参数1+参数2+结束码0D
编号:A---A仓板 B---B1板 C---B2板 M---主板
命令号:0x01---发牌 0x20---接收出错
0x02---过渡轮转 0x21---收到命令
0x03---过渡轮停 0x22---执行完毕
0x04---清牌 0x23---状态返回
0x07---状态查询 0x24---少牌报警
0x25---卡牌报警
*********************************************************/
#include <stdio.h>
#include <AT89x52.h>
#include <absacc.h>
#include <intrins.h>
#define Back_OPTO P1_0 /*左有无牌 */
#define Count_OPTO P1_1 /*出牌计数*/
#define LED P1_2
#define Back_motor P1_3 /*传动电机2*/
#define Front_motor P1_4 /*出牌电机2*/
#define TEST P1_5
#define R485cs P3_2
#define OPTOV P3_3 /*传感器电源控制端*/
#define KEY P3_4
#define Step P3_5 /*脉冲*/
#define ConVref P3_6 /*功率控制*/
#define DIR P3_7 /*方向控制*/
#define A3986_SR P2_1 //A3986
#define A3986_RST P2_2 //A3986
#define A3986_EN P2_3 //A3986
#define A3986_PFD1 P2_4 //A3986
#define A3986_PFD2 P2_5 //A3986
#define A3986_MS1 P2_6 //A3986
#define A3986_MS2 P2_7 //A3986
#define azimuth P0 /*方位*/
void Init(void); /*初始化*/
void Rs232int(void); /*串口中断*/
void Receive(void); /*串口接收*/
void Transmit(void); /*串口发射*/
void Delay50ms(void); /*延时50ms*/
void OutCard(void); /*发牌子程序*/
void StateB(void); /*B状态查询*/
void BboxState(void); /*Bbox状态查询*/
void Test1(void); /*测试程序*/
void Test2(void); /*测试程序*/
void Turn(void); /*转动程序*/
void Riffle1(void); /*A洗牌程序*/
void Out1(void); /*A出牌程序*/
void ShaoCar(void); /*少牌处理*/
void TXok(void); /*任务发出及反馈处理*/
void ClrCard(void); /*清牌程序*/
void OUTremnantCard(void); /*发底牌子程序*/
/************************************************************************
TX[8]---发送数组 ReceivePack[8]---接收数组
BoxNO----当前接牌盒编号变量 Azidata----出牌口方位变量
Box1data----牌盒1内牌数变量 Box2data---牌盒2内牌数变量
Box3data----牌盒3内牌数变量 Box4data---牌盒4内牌数变量
Card_data----每次发牌数变量 Count0-----临时变量
AllCard,Mandata,SingleCard,RemnantCard---总牌数,人数,每人牌数,底牌数
State----工作状态变量(0-闲、1-忙、2-任务完成、3-错误1、4-错误2、5-错误3)
*************************************************************************/
unsigned char TX[8]={'R','B',0x0,'A',0x0,0x0,0x0,0x0D};
unsigned char ReceivePack[10];
unsigned char Card_data,BoxNO,Box1data,Box2data,Box3data,Box4data,CarBak;
unsigned char AllCard,Mandata,SingleCard,RemnantCard,RemnantBox,firstOUT;
unsigned char Place,Command,ErrorNO,State,Count0,Count1,Count2; //Busy,
bit ShaoCardBit,RxdOKBit,OutBit,BboxErr,PanErr,OUTmodeBit,ClrBit;
/*ShaoCardBit:少牌标志 RxdOKbit:接收OK*/
/*SingleCard,Place--位置变量*/
unsigned char bdata Wupaidata;
sbit Wupai1=Wupaidata^0;
sbit Wupai2=Wupaidata^1;
sbit Wupai3=Wupaidata^2;
sbit Wupai4=Wupaidata^3;
void main(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
LED=0; //*正常进入程序,亮LED灯0.2'*/
Delay50ms();
Delay50ms();
LED=1;
ConVref=0; /*步进电机小功率*/
Init(); /*初始化*/
while(!A3986_SR)
{
Test1();
} /*TEST测试有效,进入测试程序*/
DIR=0; /*顺时针转动定位*/
A3986_EN=0;
Delay50ms();
ConVref=1; /*步进电机大功率*/
while(azimuth==0xff)
{
for(Count0=0;Count0<255;Count0++)
{
_nop_();
_nop_();
}
Step=!Step;
}
ConVref=0; /*小功率*/
switch(azimuth)
{
case 0x7f: Place=1; break; /*当前接牌盒位置判断*/
case 0xef: Place=2; break; /*Place--位置变量*/
case 0xbf: Place=3; break; //
case 0xdf: Place=4; break; //
default: break;
}
if(!KEY)
{
while(1) /*测试有效进入测试程序*/
{
Test2();
}
}
ClrBit=0;
State=0;
ErrorNO=0;
TR2=1;
while(1)
{
if(ErrorNO)
{
TX[2]='M';
TX[4]=0x55;
TX[5]=ErrorNO;
Transmit();
ErrorNO=0;
Command=0;
}
//if(Command==0x11||Command==0x12||Command==0x13||Command==0x14||Command==0x04||Command==0x07)
if(ClrBit)
Command=0x04;
if(Command)
{ //TX[2]='M';
//TX[4]=0x21;
//TX[5]=Command;
//Transmit();
switch(Command)
{
case 0x11: Command=0;
AllCard=ReceivePack[5]; /*0x11--设置游戏参数*/
Mandata=ReceivePack[6];
SingleCard=ReceivePack[7];
RemnantCard=ReceivePack[8];
break;
case 0x12: State=Command; /*0x12--洗牌*/
Riffle1(); /*A类游戏洗牌*/
break;
case 0x13: State=Command; /*0x13--发牌*/
firstOUT=ReceivePack[6]; /*第一个出牌口(出牌盒)选择*/
Out1(); /*A类出牌*/
break;
case 0x14: State=Command; /*0x13--发底牌*/
Count0=ReceivePack[5]; /*0x13--底牌出口*/
OUTremnantCard();
break;
case 0x04: State=Command; /*0x13--清牌*/
ClrBit=0;
ClrCard();
break;
case 0x07: State=Command; /*0x13--有无牌检测*/
StateB();
break;
default: Command=0;
break;
}
if(!ClrBit&&State)
{
if(ErrorNO)
{
TX[2]='M'; /*返回错误类型*/
TX[4]=0x22; //TX[4]=0x55;
TX[5]=State; //TX[5]=0x13;
Transmit();
}
else /*执行完成后返回*/
{
TX[2]='M';
TX[4]=0x22;
TX[5]=State;
Transmit();
}
State=0;
Command=0;
}
}
}
}
/***********************************
*-------发底牌程序--------------*
***********************************/
void OUTremnantCard(void)
{
unsigned char x;
BoxNO=Count0+2; /*底牌出口确定*/
if(BoxNO>4)
BoxNO=BoxNO-4;
if(0<BoxNO&&BoxNO<5)
{
Turn();
}
if(PanErr)
goto OUTremnantexit; /*转盘错误退出*/
TX[4]=1; /*无错B仓发牌*/
switch(RemnantBox)
{
case 1: TX[2]='B'; TX[5]=RemnantCard;TX[6]=0; break;
case 2: TX[2]='B'; TX[5]=0;TX[6]=RemnantCard; break;
case 3: TX[2]='C'; TX[5]=RemnantCard;TX[6]=0; break;
case 4: TX[2]='C'; TX[5]=0;TX[6]=RemnantCard; break;
default: break;
}
Transmit();
TXok();
if(ErrorNO)
goto OUTremnantexit;
Command=0;
x=0;
while(Command==0) /*等待B仓返回信息*/
{
Delay50ms();
if(x>50)
{
break;
}
x++;
}
if(Command)
{
TX[2]='M';
switch(Command)
{
case 0x22: State=4;TX[4]=0x22;TX[5]=0x14;Transmit();ErrorNO=0;break; /*B仓返回完成*/
case 0x25: State=7;ErrorNO=0x25;break; /*B仓返回卡牌*/
default: State=6;ErrorNO=0x2a;break; /*B仓通讯错误*/
}
}
OUTremnantexit:
Command=0;
}
/***********************************
*-------清牌程序--------------*
***********************************/
void ClrCard(void)
{
unsigned char x1,Bbox;
bit CaPaibit,Box1ok,Box2ok,Bclrbit;
switch(azimuth)
{
case 0x7f: Bbox=0x42; break; /*当前接牌盒位置判断*/
case 0xef: Bbox=0x42; break; /*Place--位置变量*/
case 0xbf: Bbox=0x43; break; //
case 0xdf: Bbox=0x43; break; //
default: break;
}
A3986_EN=0;
OPTOV=0; /*开有无牌传感器*/
Delay50ms();
CaPaibit=0;
Box1ok=0;
Box2ok=0;
BboxErr=0;
Bclrbit=1;
TX[2]='B';
TX[4]=0x04;
Transmit();
TXok();
if(BboxErr) /*B通讯错误退出*/
goto Clrexit;
TX[2]='C';
TX[4]=0x04;
Transmit();
TXok();
if(BboxErr) /*B通讯错误退出*/
goto Clrexit;
while(!Back_OPTO||Count_OPTO) /*有牌则清牌*/
{
Back_motor=0;
Front_motor=0;
if(Bclrbit)
{
for(x1=0;x1<40;x1++)
{
Delay50ms();
}
Bclrbit=0;
TX[2]=Bbox; /*B清牌*/
TX[4]=0x04;
Transmit();
TXok();
}
}
Back_motor=1;
Front_motor=1;
OPTOV=1;
//TX[2]=Bbox; /*B清牌*/
//TX[4]=0x04;
//Transmit();
//TXok();
Clrexit:
A3986_EN=1;
LED=1;
}
/***********************************
*-------A类出牌程序--------------*
***********************************/
void Out1(void)
{
unsigned int x,y;
BoxNO=1; /*固定发牌位置*/
Turn();
TX[2]='B';
TX[4]=0x02; /*0x02一次把牌发完命令*/
TX[5]=0x11;
TX[6]=0x11;
Transmit();
TXok();
Delay50ms();
if(ErrorNO)
goto RemOUT;
TX[2]='C';
TX[4]=0x02; /*0x02一次把牌发完命令*/
TX[5]=0; /*三家游戏底牌不出*/
TX[6]=0x11;
Transmit();
TXok();
x=0;y=0;
while(1)
{
Delay50ms();
if(Command==0x22) /*等待B仓发牌完成*/
{
y++;
Command=0;
}
if(y==2) break;
x++;
if(x>200) break;
}
RemOUT:
Delay50ms();
}
/***********************************
*-------A类洗牌程序--------------*
***********************************/
void Riffle1(void)
{
unsigned char Ya,Cou0; //man,x
unsigned char AllCardbak,RemnantCardbak;
bit xbit;
AllCardbak=AllCard;
RemnantCardbak=RemnantCard;
xbit=0;
ShaoCardBit=0; /*少牌标志*/
Cou0=0;
Box1data=0;
Box2data=0;
Box3data=0;
Box4data=0;
if(Mandata==3)
{
RemnantBox=3;
} /*3人时底牌盒为3*/
else
RemnantBox=TL2%4+1; /*用计数器数据来计算随机底牌盒*/
OPTOV=0; //+
Delay50ms();
while(1)
{
Card_data=TL2%3+1;
BoxNO=TH2%4+1;
while(BoxNO==Cou0)
{
BoxNO=TH2%4+1;
} /*取首个接牌盒位置*/
if(AllCard>0x54)
AllCard=0;
if(AllCard-RemnantCard<Card_data*Mandata) /*检查总牌数是否够发一轮牌*/
{
Card_data=(AllCard-RemnantCard)/Mandata;
}
for(Ya=0;Ya<Mandata;Ya++) /*发牌一轮*/
{
if(Command==0x04) /*清牌*/
{
Ya=Mandata;
}
else
{
if(Mandata==3) /*判断是否为3人游戏*/
{
if(BoxNO==3)
{
BoxNO=4;
}
}
if(Cou0==BoxNO) //*****
{
BoxNO++; //*****
if(BoxNO>=5) //*****
{
BoxNO=1;
} //*****
} //*****
Turn(); /*转动*/
Cou0=BoxNO; /*保存当前位置*/
OPTOV=0; //+
Delay50ms();
CarBak=Card_data; /*发牌数bak*/
OutCard(); /*发牌*/
if(ShaoCardBit)
{
ShaoCar();
} /*少牌处理*/
AllCard=AllCard-CarBak; /*Card_data总牌数更新*/
switch(BoxNO)
{
case 1: Box1data=Box1data+Card_data; break; /*牌盒牌数更新*/
case 2: Box2data=Box2data+Card_data; break; //
case 3: Box3data=Box3data+Card_data; break; //
case 4: Box4data=Box4data+Card_data; break; //
default: break;
}
BoxNO++; /*转动方位变化*/
if(BoxNO>4) //
{
BoxNO=1;
} //
}
}
if(Command==0x04) /*清牌*/
{
ClrBit=1;
break;
}
if((RemnantCard!=0)||(AllCard==RemnantCard)) /*发底牌程序*/
{
if(RemnantBox!=Cou0||AllCard==RemnantCard) /*底牌等于总牌数?*/
{
BoxNO=RemnantBox;
Turn();
if(RemnantCard<Card_data||AllCard==RemnantCard)
{
Card_data=RemnantCard;
}
CarBak=Card_data; /*发牌数bak*/
OutCard(); /*发牌*/
if(ShaoCardBit)
{
ShaoCar();
} /*少牌处理*/
if(Command==0x04) /*清牌*/
{
ClrBit=1;
break;
}
RemnantCard=RemnantCard-CarBak; /*底牌数更新*/
AllCard=AllCard-CarBak; /*总牌数更新*/
switch(RemnantBox)
{
case 1: Box1data=Box1data+CarBak; break; /*牌盒牌数更新*/
case 2: Box2data=Box2data+CarBak; break; //
case 3: Box3data=Box3data+CarBak; break; //
case 4: Box4data=Box4data+CarBak; break; //
default: break;
}
}
}
if(AllCard==0||AllCard>54)
{
OPTOV=0; //+
Delay50ms();
while(!Back_OPTO||Count_OPTO) /*总牌数为0时如有牌报牌多,无牌退出*/
{
if(!xbit)
{
TX[2]='M';
TX[4]=0x26; /*多牌报警*/
Transmit();
xbit=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -