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

📄 morse.c

📁 用在EM78860单片机制作的摩斯密码机源文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	and a,#0xE0
	or	a,%bank_num
	iow 0x0a
	mov a,%offset
	mov	0x0c,a
	mov	a,%data
	mov 0x0d,a	//address IOCA+RC,write data(RD)
	*/
	regdata=IOCA;
	regdata&=~bank_mask;
	if(len <(256-offset))
	{
	//current page;
		regdata |=bank_num;
		IOCA=regdata;
		for(i=0;i<len;i++)
		{
			RC=offset+i;
			RD=inbuf[i];
		}
	}
	else
	{
	//first write current page remnant
		regdata |=bank_num;
		IOCA=regdata;
		for(i=0;i<(256-offset);i++)
		{
			RC=offset+i;
			RD=inbuf[i];
		}
		len_remnant=len-(256-offset);
	//write next band ..,band +1
		bank_add=bank_add +1;
		bank_add <<=1;
		regdata&=~bank_mask;
		regdata |=bank_add;
		IOCA=regdata;
		for(i=0;i<len_remnant;i++)
		{
			RC=offset+i;
			RD=inbuf[len-len_remnant+i];
		}
			
	}
	
	//end array opreate 
	_asm{
	//restore rpage, iopage and bank reg step
	mov a, %nbuf
	mov 0x03, a
	mov a, %nbuf + 1
	mov 0x04, a
	
	mov a,%nbuf+2
	iow	0x0A	//restore IOCA 
	
	}	
}

//maxlen is 32.
void array_get(short pos,char *outbuf,short len)
{
	short i;
	/*
	char bank_num=0;
	char offset=0;
	char nbuf;//use save and restore 
	char bank_add;
	short len_remnant;
	*/
		
	bank_num = pos/256;
	bank_add = bank_num;
	bank_num <<=1;
	offset=pos%256;

	_asm
	{
	mov a,0x0
	mov %nbuf, a
	mov a, 0x04
	mov %nbuf+1, a
	bs 0x03, 7
	bs 0x03, 6 //change to other(rpages)
	
	IOR	0x0A
	mov %nbuf+2,a //save band ram
	}
	//start array opreate

	regdata=IOCA;
	regdata&=~bank_mask;
	if(len <(256-offset))
	{
	//current page;
		regdata |=bank_num;
		IOCA=regdata;
		for(i=0;i<len;i++)
		{
			RC=offset+i;
		//	RD=inbuf[i];
			outbuf[i]=RD;
		}
	}
	else
	{
	//first write current page remnant
		regdata |=bank_num;
		IOCA=regdata;
		for(i=0;i<(256-offset);i++)
		{
			RC=offset+i;
		//	RD=inbuf[i];
			outbuf[i]=RD;
		}
		len_remnant=len-(256-offset);
	//write next band ..,band +1
		bank_add=bank_add +1;
		bank_add <<=1;
		regdata&=~bank_mask;
		regdata |=bank_add;
		IOCA=regdata;
		for(i=0;i<len_remnant;i++)
		{
			RC=offset+i;
		//	RD=inbuf[len-len_remnant+i];
			outbuf[len-len_remnant+i]=RD;
		}
			
	}
	
	//end array opreate 
	_asm{
	//restore rpage, iopage and bank reg step
	mov a, %nbuf
	mov 0x03, a
	mov a, %nbuf + 1
	mov 0x04, a
	
	mov a,%nbuf+2
	iow	0x0A	//restore IOCA 
	
	}	
}


void emc_memcpy(short dst,short src,short len)
{
	char buf[1];
	short i;
	
	if(dst ==0 ||src ==0)
		return ;
	for(i=0;i<len;i++)
	{
	array_get(src+i, buf,1);
	array_set(dst+i, buf,1);
	}
}

/*
*	in send_buff ,form send data,including character code,device id,destination Id,length,data,checksum.
*	not include start 10ms high level!!!
*	only checksum device_id+dest_id+ch_count.
*/
void begin_send_words(short device_id,short dest_id)
{
	short offset=0;
	char buf[2];

	//buf[0]=(char)0xA5;
	//array_set(SEND_BUFF_ADDR+offset,buf,1);
//	offset =offset +1;
	array_set(SEND_BUFF_ADDR+offset,(char*)(&device_id),2);
	offset=offset +2;
	array_set(SEND_BUFF_ADDR+offset,(char*)(&dest_id),2);
	offset=offset +2;
	buf[0]=ch_count;
	array_set(SEND_BUFF_ADDR+offset,buf,1);
	offset=offset+1;
	emc_memcpy(SEND_BUFF_ADDR+offset,INPUT_WORD_ADDR,ch_count);
	offset=offset+ch_count;
	buf[0]=1+~(device_id+dest_id+ch_count);
	array_set(SEND_BUFF_ADDR+offset,buf,1);
//	send_valid = true;
//	send_index = 0;
 //   	send_bit = 0;
 //   	send_bit_phase = false;
 //  	send_head = false;
 //  	send_sync = false;
//	send_timer = 0;
//	send_count = ch_count+6;
//	send_ch_count=0;
	
}

 void init_key()
{
	//char regdata;

	regdata=IOC7;
	regdata|=0x87;
	IOC7=regdata;
	regdata=IOCD;
	regdata|=0x87;
	IOCD=regdata;
	regdata=IOC9;
	regdata&=~0x60;
	IOC9=regdata;
	regdata=PORT9;
	regdata|=0x60;
	PORT9=regdata;
}
	

char scan_key()
{
	char keydata=(char)0xFF;
	
	regdata=PORT9;
	regdata&=~0x20;
	regdata|=0x40;
	PORT9=regdata;
	keydata=PORT7;
	if(keydata !=(char)0xFF)
	{
		if(!(keydata&(1<<0)))
			return (char)key_morse_di;
		else if(!(keydata&(1<<1)))
			return (char)key_morse_dah;
		else if(!(keydata&(1<<2)))
			return (char)key_morse_end;
		else if(!(keydata&(1<<7)))
			return (char)key_left;
	}
	//	return keydata;
	regdata=PORT9;
	regdata&=~0x40;
	regdata|=0x20;
	PORT9=regdata;
	keydata=PORT7;
	if(keydata !=(char)0xFF)
	{
		if(!(keydata&(1<<0)))
			return key_right;
		else if(!(keydata&(1<<1)))
			return key_up;
		else if(!(keydata&(1<<2)))
			return key_down;
		else if(!(keydata&(1<<7)))
			return key_switch;
	}		
	return keydata;
}


void write_cont(char data)
{
	regdata =0;

	regdata |=data;
	_asm
	{
		mov a,%regdata
		CONTW
	}
}
char read_cont(void)
{
	char data;
	
	_asm
	{
		CONTR 
		mov %data,a
	}
	return data;
}
/*
*	config port9.4 and port9.3 is output 
*/

void init_i2c()
{
	regdata=IOC9;
	regdata &=~0x18;
	IOC9=regdata;
}
#if 1
/*******************************************************************
                     起动总线函数               
函数原型: void  Start_I2c();  
功能:     启动I2C总线,即发送I2C起始条件.  
********************************************************************/
void Start_I2c()
{
//  SDA=1;   	/*发送起始条件的数据信号*/
   regdata =PORT9;
  regdata |=SDA;
  PORT9=regdata;

  _Nop();
//  SCL=1;
    regdata =PORT9;
  regdata |=SCL;
  PORT9=regdata;

  _Nop();    	/*起始条件建立时间大于4.7us,延时*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();    
  //SDA=0;   	/*发送起始信号*/
    regdata =PORT9;
  regdata &=~SDA;
  PORT9=regdata;

  _Nop();    	/* 起始条件锁定时间大于4μs*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();       
//  SCL=0;   	/*钳住I2C总线,准备发送或接收数据 */
    regdata =PORT9;
  regdata &=~SCL;
  PORT9=regdata;

  _Nop();
  _Nop();
}

/*******************************************************************
                       结束总线函数               
函数原型: void  Stop_I2c();  
功能:     结束I2C总线,即发送I2C结束条件.  
********************************************************************/
void Stop_I2c()
{
//  SDA=0;  	/*发送结束条件的数据信号*/
    regdata =PORT9;
  regdata &=~SDA;
  PORT9=regdata;

  _Nop();   	/*发送结束条件的时钟信号*/
  //SCL=1;  	/*结束条件建立时间大于4μs*/
    regdata =PORT9;
  regdata |=SCL;
  PORT9=regdata;

  _Nop();
  _Nop();
  _Nop();
  _Nop();
  _Nop();
 // SDA=1;  	/*发送I2C总线结束信号*/
    regdata =PORT9;
  regdata |=SDA;
  PORT9=regdata;

  _Nop();
  _Nop();
  _Nop();
  _Nop();
}

/*******************************************************************
                 字节数据发送函数               
函数原型: void  SendByte(uchar c);
功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
          此状态位进行操作.(不应答或非应答都使ack=0)     
     	  发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void  SendByte(char c)
{
 uchar BitCnt;
 
 for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
    {
  //   if((c<<BitCnt)&0x80)SDA=1;   /*判断发送位*/
      if((c<<BitCnt)&0x80)
      	{
    	regdata =PORT9;
  	regdata |=SDA;
  	PORT9=regdata;
      	}
   //    else  SDA=0;  
    else {
    	regdata =PORT9;
  	regdata&=~SDA;
  	PORT9=regdata;
    }
     _Nop();
 //    SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
       regdata =PORT9;
  	regdata |=SCL;
  	PORT9=regdata;

      _Nop(); 
      _Nop();             /*保证时钟高电平周期大于4μs*/
      _Nop();
      _Nop();
      _Nop();         
   //  SCL=0; 
       regdata =PORT9;
  	regdata &=~SCL;
  	PORT9=regdata;

    }
    
    _Nop();
    _Nop();
   // SDA=1;                /*8位发送完后释放数据线,准备接收应答位*/
      regdata =PORT9;
  	regdata |=SDA;
  	PORT9=regdata;

    _Nop();
    _Nop();   
   // SCL=1;
      	regdata =PORT9;
  	regdata |=SCL;
  	PORT9=regdata;

    _Nop();
    _Nop();
    _Nop();
  //if(SDA==1)ack=0;     
     if( PORT9 & SDA)ack=0;     
       else ack=1;        /*判断是否接收到应答信号*/
 //   SCL=0;
      	regdata =PORT9;
  	regdata &=~SCL;
  	PORT9=regdata;
    
    _Nop();
    _Nop();
}

/*******************************************************************
                 字节数据接收函数               
函数原型: uchar  RcvByte();
功能:  	  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
          发完后请用应答函数应答从机。  
********************************************************************/	
uchar  RcvByte()
{
  uchar retc;
  uchar BitCnt;
  
  retc=0; 
//  SDA=1;             		/*置数据线为输入方式*/
	regdata=IOC9;
	regdata |=0x8;
	IOC9=regdata;
/*
  regdata =PORT9;
  regdata |=SDA;
  PORT9=regdata;
  */
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        _Nop();           
     //   SCL=0;                  /*置时钟线为低,准备接收数据位*/
    	 regdata =PORT9;
  	regdata &=~SCL;
 	 PORT9=regdata;
     
        _Nop();
        _Nop();                 /*时钟低电平周期大于4.7μs*/
        _Nop();
        _Nop();
        _Nop();
       // SCL=1;                  /*置时钟线为高使数据线上数据有效*/
        regdata =PORT9;
  	regdata |=SCL;
  	PORT9=regdata;

        _Nop();
        _Nop();
        retc=retc<<1;
     //   if(SDA==1)retc=retc+1;  /*读数据位,接收的数据位放入retc中 */
     	 if((PORT9 & SDA))retc=retc+1;  
        _Nop();
        _Nop(); 
      }
    	 regdata =PORT9;
  	regdata &=~SCL;
 	 PORT9=regdata;
  _Nop();
  _Nop();
  	regdata=IOC9;
	regdata &=~0x8;
	IOC9=regdata;

  return(retc);
}


/********************************************************************
                     应答子函数
函数原型:  void Ack_I2c(bit a);
功能:      主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(char a)
{
  
//  if(a==0)SDA=0;     	     /*在此发出应答或非应答信号 */
  //      else SDA=1;

  if(a==0)
  	{
  	regdata =PORT9;
  	regdata &=~SDA;
  	PORT9=regdata;

  	}
  else
  	{
      	regdata =PORT9;
  	regdata |=SDA;
  	PORT9=regdata;
		
  	}
  _Nop();
  _Nop();
  _Nop();      
 // SCL=1;
     	regdata =PORT9;
  	regdata |=SCL;
  	PORT9=regdata;

  _Nop();
  _Nop();                    /*时钟低电平周期大于4μs*/
  _Nop();
  _Nop();
  _Nop();  
 // SCL=0;                     /*清时钟线,钳住I2C总线以便继续接收*/
      	regdata =PORT9;
  	regdata &=~SCL;
  	PORT9=regdata;

 _Nop();
  _Nop();    
}



/*******************************************************************
                 用户接口函数                                   
*******************************************************************/

#if 0
/*******************************************************************
                 向无子地址器件发送字节数据函数               
函数原型: bit  ISendByte(uchar sla,uchar c);  
功能:     从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
          如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
char  ISendByte(uchar sla,uchar c)
{
   Start_I2c();               /*启动总线*/
   SendByte(sla);             /*发送器件地址*/
   if(ack==0)return(0);
   SendByte(c);               /*发送数据*/
   if(ack==0)return(0);
   Stop_I2c();                /*结束总线*/ 
   return(1);
}
#endif 

/*******************************************************************
                    向有子地址器件发送多字节数据函数               
函数原型: bit  ISendStr(uchar sla,uchar suba,uchar *s,uchar no);  
功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
          地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
          如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
char  ISendStr(uchar sla,uchar suba,char *s,uchar no)
{
   uchar i;

   Start_I2c();               /*启动总线*/
   SendByte(sla);             /*发送器件地址*/
   if(ack==0)return(0);
   SendByte(suba);            /*发送器件子地址*/
   if(ack==0)return(0);

   for(i=0;i<no;i++)
   {   
     SendByte(*s);            /*发送数据*/
     if(ack==0)return(0);
     s++;
   } 
   Stop_I2c();                /*结束总线*/ 
   return(1);
}

#if 0
/*******************************************************************
                    向无子地址器件读字节数据函数               
函数原型: bit  IRcvByte(uchar sla,ucahr *c);  
功能:     从启动总线到发送地址,读数据,结束总线的全过程,从器件地
          址sla,返回值在c.
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
char  IRcvByte(uchar sla,uchar *c)
{
   Start_I2c();                /*启动总线*/
   SendByte(sla+1);            /*发送器件地址*/
   if(ack==0)return(0);
   *c=RcvByte();               /*读取数据*/
   Ack_I2c(1);                 /*发送非就答位*/
   Stop_I2c();                 /*结束总线*/ 
   return(1);
}

#endif 

/*******************************************************************
                    向有子地址器件读取多字节数据函数               
函数原型: bit  ISendStr(uchar sla,uchar suba,uchar *s,uchar no);  
功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
          地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
char  IRcvStr(uchar sla,uchar suba,char *s,uchar no)
{
   uchar i;

   Start_I2c();                  /*启动总线*/
   SendByte(sla);                /*发送器件地址*/
   if(ack==0)return(0);
   SendByte(suba);               /*发送器件子地址*/
   if(ack==0)return(0);

   Start_I2c();			 /*重新启动总线*/
   SendByte(sla+1);
   if(ack==0)return(0);

⌨️ 快捷键说明

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