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

📄 dpramcomm.c

📁 51单片机C语言应用程序设计实例精讲.rar
💻 C
字号:
/*****************************************/
/* Copyright (c) 2005, 通信工程学院      */
/* All rights reserved.                  */
/* 作    者:戴 佳		        		 */
/*****************************************/

#include "DPRamComm.h"

/* 40ms定时中断服务子程序:
   定期更新左端单片机的状态信息,查询右端单片机的状态信息*/
void timer0_int() interrupt 1 using 1
{
	TR0 = 0;						// 关闭T0
  	TH0 = 0x70;						// 重置40ms定时器的计数初值
  	TL0 = 0x00; 
  	FillState();					// 定期更新左端单片机状态让右端单片机可查询
  	GetState();						// 定期查询右端单片机的状态信息   
}

/* 外部中断0服务子程序:
   设置中断标志位int0flag,读清中断*/
void out_int0() interrupt 0 using 1
{
  	uchar ch;
  	int0flag = 1;					// 表示外部中断0,实际是双口RAM产生的中断
  
  	get_sem(&INTL_SEM);				// 申请并获得左中断旗语
  	ch = DPRAM_INTR;    			// 读清中断
  	INTL_SEM = 0x01;				// 释放左中断旗语
}	

/* 主程序 */
void main()
{ 
	int0flag = 0;
	rdyflag = 0;
	ProvTimes = 0;

	LpStateRamAddr = 0x2000;
	LpProvRamAddr = 0x2400;
	RpStateRamAddr = 0x3000;
	RpProvRamAddr = 0x3400;


	/* 等待右端单片机准备就绪 */
	while(rdyflag!=1)
	{
		get_sem(&RP_STT_SEM);		// 申请并获得右端状态旗语
		if (*RpStateRamAddr == READY)	
			rdyflag = 1;			// 右端单片机准备就绪标志置1
		RP_STT_SEM = 0x01;			// 释放右端状态旗语
	}

	/* 对右端单片机进行初始配置 */
	InitProvRP();	
	
	/* 通过向左端状态空间的第一地址单元写READY向右端表示左端准备就绪 */
	get_sem(&LP_STT_SEM);			// 申请并获得左端状态旗语
	*LpStateRamAddr = READY;		// 左端单片机准备就绪
	LP_STT_SEM = 0x01;				// 释放左端状态旗语

	ProvTimes++;					// 对右端口的配置次数加1		

	EA = 1;							// 开CPU中断
  	EX0 = 1;						// 开外部中断0 
	ET0 =1;							// 开T/C0中断
  	PX0	= 0;						// 外部中断低优先级
  	PT0 = 1;						// 计数器高优先级
  	TMOD = 0x01;					// T/C0工作在方式1
  	TH0 = 0x70;						// 预置40ms定时器的计数初值
  	TL0 = 0x00;
  	TR0 = 0;						// 不启动T0

	/* 右端单片机接收左端对其的初始化配置,运行正常后触发双口RAM的
	左端中断,左端单片机受中断触发后对右端单片机作第二次配置,并启
	动40ms定时器,开始定期更新本机的状态信息并监测右端单片机的状态 */
    while(int0flag==1)
	{
		if (ProvTimes==1)
		{
			ProvTimes++;			// 对右端口的配置次数加1
			Prov();					// 对右端口单片机二次配置
			
			/* 通过出发右端中断,通知右端单片机接受二次配置*/
			get_sem(&INTR_SEM);		// 申请并获得右中断旗语
  			DPRAM_INTL = 0xFF;    	// ITNR脚为低,出发右端单片机中断
  			INTR_SEM = 0x01;		// 释放右中断旗语
		}

		TR0 = 1;					// 启动40ms定时器T0		
	}  	
}

/* 申请并获得旗语函数 */
bit get_sem(uchar *sem_type)         	
{
  	*sem_type = 0x00;				// 申请旗语
  	while((*sem_type!=0x00));		// 无限循环直至获得旗语    
  	return(1);
}


/* 对右端单片机的初始化配置函数:为简化起见,通过向左端的配置
   空间2500H~25FFH全写0x22,表示对右端单片机的初始配置命令  */
void InitProvRP(void)
{
	uchar i;
	get_sem(&LP_PRO_SEM);			// 申请左端配置旗语	
	for (i=0;i++;i<=255)
		*(LpProvRamAddr+i) = 0x22; 
	LP_PRO_SEM = 0x01;				// 释放左端配置旗语		
}

/* 对右端单片机的二次配置函数:为简化起见,通过向左端的配置
   空间2500H~25FFH全写0x33,表示对右端单片机的初始配置命令  */
void Prov(void)
{
	uchar i;
	get_sem(&LP_PRO_SEM);			// 申请左端配置旗语	
	for (i=0;i++;i<=255)
		*(LpProvRamAddr+i) = 0x33; 
	LP_PRO_SEM = 0x01;				// 释放左端配置旗语
}


/* 更新本机状态函数:为了简化起见,此函数表示为向左端状态空
   间第一地址单元(存放设备就绪信息)以后的254字节全写0x44  */
void FillState(void)
{
	uchar i;
	get_sem(&LP_STT_SEM);			// 申请并获得左端状态旗语
	for (i=0;i++;i<=254)
		*(LpStateRamAddr+i+1) = 0x44;
	LP_STT_SEM = 0x01;				// 释放左端状态旗语
}

/* 查询另一端单片机状态函数:为简化起见,此函数表示为用数组
   ArrayState存取右端状态空间第一地址单元(存放设备就绪信息)
   以后的254字节(3001H~30FFH)包含的状态信息		*/ 
void GetState(void)
{
	uchar i;
	get_sem(&RP_STT_SEM);			// 申请并获得右端状态旗语
	for (i=0;i++;i<=254)
		ArrayState[i] = *(RpStateRamAddr+i+1);
	RP_STT_SEM = 0x01;				// 释放右端状态旗语
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -