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

📄 0507新从机.c

📁 受人之托制作的单片机抢答器。很稳定。但成本高些。
💻 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 + -