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

📄 addr_prc.c

📁 楼宇对讲系统里用的文字信息接收。用可视对讲话机的TFT屏可看到从管理中心发过来的广播信息和本户的特发信息
💻 C
字号:
/***********************************************************/
/*							                               */
/*                CPU:AT89c55   20MHZ                      */
/*                Copyright  2004.09  Comelit              */
/*                AUTHOR:  LV_XIAO_LU                      */
/*                                                         */
/***********************************************************/


#include "reg52.h"
#include "define.h"
#include "variable.h"
#include "typedef.h"
#include "function.h"

//#define MESSAGE_START_ADDR 0x1100 
/* 
#define MESSAGE_START_ADDR 0x1900 

#define MESSAGE_LENTH  512      //相当于255个汉字的信息
                                //一条信息占用FLASH MEMORY 合计128*4段
#define MAX_MESSAGE_CNT 200

#define PAGE_0 0
*/
sbit FLASH_A16 = P1^0;
/*
typedef union
{    struct
     {
	   
        unsigned int page_addr;
        unsigned int  address;
     }address;
	  unsigned long addr;
}ADDRESS;
 

struct MES_CON_BLOCK              //共占8 个字节
  {
    ADDRESS mes_addr;                 //贮存的是信息块所分配的起始地址
	struct MES_CON_BLOCK xdata *prev; //指回上一个信息控制块
    struct MES_CON_BLOCK xdata *next;  //指向下一个信息控制块
  };
*/

// extern  struct  MES_CON_BLOCK  xdata mes_control_b[MAX_MESSAGE_CNT];   //
// extern  struct  MES_CON_BLOCK  xdata *free_tcb_list_b  ;           //该指针指向的控制块指向的区域是可以贮存信息的
// extern  struct  MES_CON_BLOCK  xdata *disp_tcb_list_b  ;           // 该指针指向的控制块指向的区域表示可以读出信息的  

// extern  struct  MES_CON_BLOCK  xdata mes_control[MAX_MESSAGE_CNT];   //
// extern  struct  MES_CON_BLOCK  xdata *free_tcb_list  ;           //该指针指向的控制块指向的区域是可以贮存信息的
// extern  struct  MES_CON_BLOCK  xdata *disp_tcb_list  ;           // 该指针指向的控制块指向的区域表示可以读出信息的  


 void Mes_tcb_init(void) ;
 void Bank_switch(struct  MES_CON_BLOCK xdata *block_addr);

 void Insert_disp_tcb_block(struct  MES_CON_BLOCK xdata *block);
 void Del_disp_tcb_block(struct  MES_CON_BLOCK xdata *block);
 void Free_tcb_block(struct  MES_CON_BLOCK xdata *block);
// void Del_store_block(struct  MES_CON_BLOCK xdata *block);
 struct  MES_CON_BLOCK xdata *Create_tcb_block(void);
 struct  MES_CON_BLOCK xdata *Get_disp_last_block(void);

/**********************************************************************/
/* 由于FLASH无法单字节写,故先在SRAM里初始化好,然后才可以存入FLASH中 */
/* mes_control定位于SRAM区的0X100                                     */
/**********************************************************************/
 
void Mes_tcb_init(void)               //初始化信息控制块数据
{
  unsigned int i;
  unsigned long addr=(unsigned int)MESSAGE_START_ADDR;       //第一条信息从flash的0x1900开始
  unsigned long bank_addr=0x0000;
  struct MES_CON_BLOCK xdata *block = mes_control; //struct MES_CON_BLOCK xdata *block = (struct MES_CON_BLOCK xdata*)0x100;
 
  for(i=0;i<MAX_MESSAGE_CNT;i++)
  {
 //   addr +=MESSAGE;
    if(addr<=0xffff)
    {
    	if( ((unsigned int)((unsigned int)0xffff-(unsigned int)addr)) >= (unsigned int)MESSAGE_LENTH )              //判定在64K范围是否有贮存一条信息的空间,若
        {                                             //不够,则转到下一个64K FLASH
       		block->mes_addr.addr = addr+bank_addr ;
        }
        else
        {
            addr=(unsigned int)MESSAGE_START_ADDR;
            bank_addr+=0x10000;
            block->mes_addr.addr=addr+bank_addr;
        }
    }

    block->next=block+1;
    block++;
    addr+=MESSAGE_LENTH;
 }
   block--;
//   block->next = (struct  MES_CON_BLOCK *)END;
   block->next = &MES_NULL;
  /*链表初始化*/
   free_tcb_list = &mes_control[0] ;                       
//   disp_tcb_list = (struct  MES_CON_BLOCK *)END;
   disp_tcb_list = &MES_NULL;
}



/***************************************************************/
/***************************************************************/
 


/*该函数根据传递过来的块的高位地址来切换FLASH的64K BANK */
/*
void Bank_switch(struct  MES_CON_BLOCK xdata *block_addr)
{
	switch(block_addr->mes_addr.address.page_addr)
	{
	   case 0x0000:

	              PORT_ONE=0;
				  PORT_TWO=0;	             
	            
				 break;
	   case 0x0001:
	             PORT_ONE=1;
				 PORT_TWO=0;
			
				 break;
	   case 0x0002:
	             PORT_ONE=0;
				 PORT_TWO=1;
			
				 break;
	   case 0x0003:
				 PORT_ONE=1;
				 PORT_TWO=1;
				
				 break;
	   default:
	             break;
	}
}*/

void Page_switch(unsigned char page)
{
	if(1 == page)
	   FLASH_A16 = 1;
    else 
	   FLASH_A16 = 0;
}


/***************************************************************/
/* 该函数是把已经贮存有最新信息的内存块链接到显示信息链表中最前*/
/* 面,表示为最新消息                                          */
/***************************************************************/
 
void Insert_disp_tcb_block(struct  MES_CON_BLOCK xdata *block)

{
   if(block == &MES_NULL)
      return;

   if(disp_tcb_list != &MES_NULL)              //在已有待显示链中插入
   {
      block->next = disp_tcb_list; 
	  block->prev = &MES_NULL;
	  ET2 = 0;
      disp_tcb_list -> prev = block; 	  	  
      disp_tcb_list = block;
      ET2 = 1;                         
   }
   else
   {
	   block->next = &MES_NULL ; //最后信息指空表示已无可显示信息
	   block->prev = &MES_NULL ; //表明这是第一条
	   EA = 0;
       disp_tcb_list = block;
       EA = 1;                      
   }
   
}


/***************************************************************/
/***************************************************************/

void Del_disp_tcb_block(struct  MES_CON_BLOCK xdata *block)
{
   
    if(block == &MES_NULL)
          return;
    else
	{
//		if( block->prev == (struct  MES_CON_BLOCK xdata *)END )                     //要删除的是头一条信息
       	EA = 0;
        if( block->prev == &MES_NULL )
		{
	   		if(block->next != &MES_NULL)                                            //不是第一条
//			block->next->prev = (struct  MES_CON_BLOCK xdata *)END ;
            {
//			   EA = 0;
			   block->next->prev = &MES_NULL ;			   
               disp_tcb_list = block->next ;
//			   EA = 1;
			}
			else
			{
//			    EA = 0;
                disp_tcb_list = &MES_NULL;
//				EA = 1;
			}
		}
        else 
        {          
            block->prev->next = block->next;
            block->next->prev = block->prev;       	
        }
		EA = 1;
         Free_tcb_block(block);
     }
}



/***************************************************************/
/* 把通过参数传递过来的控制块放回到free_tcb_list 链中的最后面  */
/***************************************************************/

void Free_tcb_block(struct  MES_CON_BLOCK xdata *block)
{
   struct  MES_CON_BLOCK xdata *temp_p;
   temp_p = free_tcb_list ;
   if(temp_p == &MES_NULL)      //free_tcb_list已空,直接加入
   {
		free_tcb_list = block ;
        block->next = &MES_NULL ;
        return;
   }
   else
   {
		 while((temp_p -> next != &MES_NULL)&&(temp_p -> next != block)) //要保证同一内存控
        {                                               //制块不会重复放入free_tcb_list表中
          	temp_p = temp_p -> next;
    	}
		if(temp_p -> next == block )                              //该内存块已放入,退出
		    return;

        if(temp_p -> next == &MES_NULL)         //到了空表最后
		{
		    temp_p -> next = block;
            block->next = &MES_NULL;		
		}
	}
}


/***************************************************************/
/* 由于创建内存时表示已接收到一条最新的并且需要存贮的信息,所以*/
/* 要无条件的得到内存块                                        */
/* 功能:从free_tcb_list或从disp_tcb_list中得到一内存块用于存贮*/
/* 信息,且将其重新挂入disp_tcb_list                           */
/***************************************************************/

struct  MES_CON_BLOCK xdata *Create_tcb_block(void)
{
	struct  MES_CON_BLOCK xdata *p1;
	if(free_tcb_list == &MES_NULL)      //free_tcb_list中已无可用控制块
       p1 = Get_disp_last_block();     
    	
	else
	{
	   p1 = free_tcb_list ;
	   free_tcb_list = p1->next ;
	   
	}
    Insert_disp_tcb_block(p1);           //放到显示链中
    return(p1);

    
}


/***************************************************************/
/* 该函数只有当需要内存块而无空的内存块时被调用,机理是把接收到的
/* 最早信息内存块用于作为存贮最新信息的内存块
/***************************************************************/

struct  MES_CON_BLOCK xdata *Get_disp_last_block(void)
{
    struct  MES_CON_BLOCK xdata *p=disp_tcb_list ;
	
    if(p == (struct  MES_CON_BLOCK xdata *)&MES_NULL)
	    while(1);                                    //如果无显示内存块又无存贮内存块
		                                                //很显然是系统出错,待重新复位
	else 
	{
        while(p->next != &MES_NULL)
		      p=p->next;

        p->prev->next = &MES_NULL;
		return(p);
	}
}









⌨️ 快捷键说明

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