📄 0507新从机.c
字号:
#include<REG2051.H>
//#include <absacc.h>
#include <intrins.h>
//#define debug
#define uchar unsigned char
sbit ANS= P3^3; //抢答按键
sbit REQ= P3^4; //发送中断请求。0请求中断
sbit LIGHT= P3^7;//从机抢答灯1灭;0亮
sbit R_T=P3^5; //控制485接收或发送状态1发送0接收
#define SETMODE 0X10
#define STARTMODE 0X20
#define TESTMODE 0X30
#define SWAITMODE 0X80
#define OVERMODE 0X00
#define RESETCOMMAND 0X01
#define STARTCOMMAND 0X02
#define STOPCOMMAND 0X03
#define TESTCOMMAND 0X04
#define ASKCOMMAND 0X06
#define LAMPCOMMAND 0X09
#define ANSWERCOMMAND 0XA0
#define NOP {_nop_();_nop_();_nop_();}
//变量定义
uchar data SendData[5]={0x7e,0x00,0x00,0x00,0x7f};//向外发送的数据。0x7E+命令+机器编号+数据+0x7F
uchar data ReceiveData[5]={0x00,0x00,0x00,0x00,0x00};//接收的数据。0x7E+命令+机器编号+数据+0x7F
uchar data mcuWorkState[2]={0x00,0x00}; //从机的工作状态 命令+数据 change可能用不到 删除
uchar data bianhao; //机器编号
uchar data time_5ms;
bit ReceiveEndF=0;//接收命令标志0未接收;1已经接收等待处理。
bit key_enable_bit=0; //键盘锁。1响应键盘;0不响应
bit key=0;
bit ERR;
void iniMCU(void)
{
/*与初始化有关的寄存器
计时控制寄存器 TCON TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
与中断相关 TF1 TF0 IE1 IT1 IE0 IT0
定时器相关寄存器 //TH0 //TL0 //TH1 //TL1
计时工作方式 TMOD GATE C/T M1 M0 GATE C/T M1 M0
中断允许寄存器 IE EA ES ET1 EX1 ET0 EX0
串口中断寄存器 SCON SM0 SM1 SM2 REN TB8 RB8 TI RI
中断优先级 IP PS PT1 PX1 PT0 PX0
特殊功能寄存器 PCON SMOD
*/
EA=0;
TMOD=0x21; //置定时器1为方式2,定时器0为方式1
SCON=0x50; //MODE 1 ,ALLOW RECEIVE
TL0=0x00;TH0=0xee;
TR0=1; //TCON^4 定时器0开始运行
ET0=1;
TH1=TL1=0x0Fd;//9600 TH1=TL1=0X0FA;//4800
TR1=1; //定时器1开始运行
ES=1; //串口中断允许
PS=1; //串行通信中断优先级
TI=0;
REN=1; //允许串口接收数据
//TB8=1;//在模式2 和模式3 中将被发送数据的第9 位
IT0=1; //外部中断0为边沿触发方式。
IE0=0; //中断请求位清零
EX0=0;// 禁止int0
LIGHT=1;
R_T=0;//接收状态
ANS=1; //抢答按键
INT0=1;////中断脚INT0
REQ=1; //发送中断请求。0请求中断
EA=1; //IE= 0x80;中断使能
bianhao=P1&0x0f;
P1=(~(P1<<4))|0x0f;
}
void delay(uchar Wait_time)
{
uchar i,j;
for (j=0;j<Wait_time;j++)
for (i=0; i<250; i++) // 1ms
_nop_();
}
//发送5字节数据。数据格式见抢答器协议
void Send_Data(void)
{
uchar i;
R_T=1;
delay(1);
NOP;
TI=0;
for(i=0;i<5;i++)
{
SBUF=SendData[i];
while(TI==0) ;
TI=0;
NOP //change
}
R_T=0;
NOP;
}
//接收数据处理
void RdataCode(void)
{
uchar i;
if(ReceiveEndF)
{
switch(ReceiveData[1])
{
case RESETCOMMAND:
LIGHT=1;
NOP
REQ=1; //关中断请求
IE0=0;
EX0=0;//关中断0
key_enable_bit=0; //**不响应键盘
NOP
key=0; //按键值清零,
break;
case ASKCOMMAND://轮询命令(主机响应通讯请求后发给从机要求返回数据的命令)
if (ReceiveData[2]==bianhao)
{
key_enable_bit=0;//不再扫描键盘
REQ=1;//停止通讯请求
IE0=0;
EX0=0;
SendData[1]=ANSWERCOMMAND;SendData[2]=bianhao;
if(key) SendData[3]=0x01;
else SendData[3]=0x00;
Send_Data();
}
break;
case STARTCOMMAND://开始抢答
if (bianhao>7) i= (ReceiveData[2]>>(bianhao-8))&0x01;
else i=(ReceiveData[3]>>bianhao)&0x01; //判断有无此从机号
if (i==1)
{
REQ=1; //关中断请求
LIGHT=1; //灯灭
IE0=0;
EX0=1;//开中断0
key_enable_bit=1;//响应键盘
key=0;
}
break;
case TESTCOMMAND: //测试模式
if (ReceiveData[2]==bianhao)
{
LIGHT=0;
NOP
IE0=0;
EX0=0;//关中断0
key_enable_bit=1;//响应键盘
key=0;
}
break;
case LAMPCOMMAND://控制从机灯状态
REQ=1;
IE0=0;
EX0=0;//关中断0
key_enable_bit=0; //禁止响应键盘
key=0;
if (ReceiveData[2]==bianhao)
{
if (ReceiveData[3]==0x00)
{ LIGHT=1;NOP }
else if (ReceiveData[3]==0x01)
{ LIGHT=0; NOP }
}
break;
default:
break;
}
ReceiveEndF=0;
}
}
//按键处理
keycode(void)
{
//根据拨码开关点亮lcd
bianhao= P1&0x0f;
if (bianhao<1||bianhao>10)
{
ERR=1;
REQ=1;
IE0=0;
EX0=0;//关中断0
key_enable_bit=0; //禁止响应键盘
key=0;
P1=0xf0|0x0f; //黑灯,
LIGHT=1;
NOP
}
else
{
P1=(~(bianhao<<4))|0x0f;
ERR=0;
}
//扫描抢答按键
if(key_enable_bit&&ERR==0)
{
if(!ANS)
{
if (time_5ms>10)//延时50ms
{
IE0=0;
EX0=0; //**禁止本机中断
REQ=0;//通讯请求
key_enable_bit=0; //按键完成,申请中断,不再扫按键。
key=1;
}
}
else {time_5ms=0;}
}
else {time_5ms=0;}
//return(0);
}
void main()
{
iniMCU();
for(;;){
keycode();
if (ERR==0) RdataCode();
}
}
//接收中断
void int0() interrupt 0 using 1
{
key_enable_bit=0;
key=0; //**禁止本机键盘
IE0=0;
EX0=0;
}
//接收数据
void serial() interrupt 4 using 2
{
if(RI){
RI=0;
if(ReceiveEndF==0)
{
ReceiveData[0]=ReceiveData[1];
ReceiveData[1]=ReceiveData[2];
ReceiveData[2]=ReceiveData[3];
ReceiveData[3]=ReceiveData[4];
ReceiveData[4]=SBUF;
if(ReceiveData[0]==0x7e&&ReceiveData[4]==0x7f)
{
if (ReceiveData[1]<ANSWERCOMMAND) //if(((bianhao)==ReceiveData[2]) || ReceiveData[2]==0xff)
{
ReceiveEndF=1;
}
}
}
}
}
void timer0() interrupt 1 using 3
{
TL0=0x00;TH0=0xee; //5MS定时中断
time_5ms++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -