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

📄 sart.c

📁 此源码为商用的电力抄表系统的主机端源程序。通过电力载波模块
💻 C
字号:

/* //////////////////////////////////////////////////////////////////////////
// sart.c  - source file for lme2200 API
// 
// Copyright 2005, Leaguer MicroElectronics Co., Ltd
// www.leaguerme.com
//////////////////////////////////////////////////////////////////////////// */
#include <REG922.H>

#include "sart.h"
#include "timer.h"
#define uint unsigned int
#define uchar unsigned char

#define MAX_FRAME_SZ 28

#define STAT_PREAMBLE	1
#define STAT_SYNC		2
#define STAT_SYNC1		3
#define STAT_DATALEN	4
#define STAT_DATA		5

#define FRAME_PREAMBLE 	0xFE
#define FRAME_SYNC		0x68
#define FRAME_END		0x16

idata uchar amr_frame[MAX_FRAME_SZ];	// amr frame rx buffer
//bit amr_recved;					// amr frame received flag

// variables used during amr frame reception
idata uchar amr_stat;
idata uchar amr_len;				
idata uchar amr_count;


idata uchar uart_buf[16];
idata uchar uart_wptr, uart_rptr;

/*=============================================================================*/

void  uart_init()
{
   
	SCON =0xd0;				// select BRG as UART Baud Rate Gen
	SSTAT=0xe0;			
	BRGR0=0xf0;				// setup BRG for 9600 baud @ 7.373MHz external Crystal
	BRGR1=0x02;

//	BRGR0=0xf0;				// setup BRG for 4800 baud @ 7.373MHz external Crystal
//	BRGR1=0x05;

//	BRGR0=0xf0;				// setup BRG for 2400 baud @ 7.373MHz external Crystal
//	BRGR1=0x0b;

	BRGCON = 0x03;     		// enable BRG
   	
	IP0H = 0x12;		   //中断优先级,串口3级,定时器0为2级,外为1级
	IP0  = 0x14;

	TI = 0;	  // do not allow transmit 	
	EA = 1;
    ES = 1;

    amr_stat = STAT_PREAMBLE;	   //<-------------设接收的初始计数1
//	amr_recved = 0;

	D_SYNC = 1;//--------------设同步输入无效

	uart_wptr = 0;
	uart_rptr = 0;

}

/*=============================================================================*/

/* Serial port ISR */
void serial_int (void) interrupt 4
{
    //unsigned char c;

	/* 
	 * The interrupt was generated. First, check the RI flag to see if it was 
	 * because a new character was received.
	 */

	if (RI == 1) {	/* it was a receive interrupt */

		RI = 0;		/* clear the received interrupt flag */

		uart_buf[uart_wptr++] = SBUF;
		uart_wptr &= 0x0f;

	}

#ifdef xxx
	else if (TI == 1)	/* otherwise, assume it was a transmit interrupt */
	{
		TI = 0;	/* clear the transmit interrupt flag */
		if (chr != '\0')	/* if there's something in the local buffer... */
		{
			if (chr == '\r') chr = '\n';	/* convert <CR> to <LF> */
			SBUF = chr;		/* put the character into the transmit buffer */
			chr = '\0';
		}
	}

#endif

}

/*=============================================================================*/

int uart_recved() 
{
  if (uart_wptr == uart_rptr)   return 0;

  return 1;

}


/*=============================================================================*/

// Call this function only when uart_recved() is true
unsigned char uart_getchar(void)
{
   uchar c;
 
   c = uart_buf[uart_rptr++];
   uart_rptr &= 0x0f;

   return c;
}
/*
int uart_processed()
{
  amr_recved = 0;
  uart_wptr = 0;
  uart_rptr = 0;
  return 1;
}
*/
/*=============================================================================*/

int recv_amr_frame(void)
{
  uchar c;

  c = uart_getchar();
  // uart_sendchar(c);
  if (amr_stat == STAT_PREAMBLE) {		 //1
  // Searching for preamble...
    if (c == FRAME_PREAMBLE) { //fe uart_sendchar(c);
       amr_stat = STAT_SYNC;
       amr_count = 0;	          
    }
  }
  else if (amr_stat == STAT_SYNC) { //2		 检测到68
    // Searching for frame sync ...
    amr_count++;
    if (c == FRAME_SYNC) {	//68
	  amr_count = 0;
	  amr_stat = STAT_SYNC1;   //3 uart_sendchar(c);
	}
	else if (amr_count >= 4) {
      // re-start
      amr_stat = STAT_PREAMBLE; //1
	  }
    }
	/*
    else if (amr_stat == STAT_SYNC1) {	//3
      // Receive address bytes
      amr_frame[amr_count++] = c;
      if (amr_count == 7) {				 //4个表地址+C+L
        if (c == FRAME_SYNC) {	  // 68uart_sendchar(c);
          amr_count = 0;
          amr_stat = STAT_DATALEN;	//4
        }
        else amr_stat = STAT_PREAMBLE; 	//1
      }
    } */
    else if (amr_stat == STAT_SYNC1) {//3
      amr_frame[amr_count++] = c;	  //收数据
      if (amr_count == 6) {
        amr_len = c + 1;     //收取长度值
        amr_count = 0;
        amr_stat = STAT_DATA;		//  uart_sendchar(c);
      }
    }
    else if (amr_stat == STAT_DATA) {  //5
    amr_frame[6+amr_count++] = c;
    if (amr_count == amr_len) {
      amr_count = 0;
      amr_stat = STAT_PREAMBLE; //1
	  if (c == FRAME_END){	//16h	uart_sendchar(c);
      // uart_sendblock(amr_frame,amr_len+6);
        return 1;         	
      }
    }	
  }   
	   
  return 0;

}

/*=============================================================================*/

// Transmit a single byte
void uart_sendchar(uchar chr)
{

//	unsigned char i , a;
	/* Disable serial interrupts for a while */
	ES   = 0;
	/* 
	 * Clear the Transmit Interrupt flag to prepare the serial port
	 * to send a new character.
	*/

	TI = 0;
	ACC=chr;                  /*从缓冲中发送串行口数据*/
	TB8=P;    			/*---------------------  *偶校验位设置*/
	SBUF=ACC;	

	/* Wait until tx buffer is empty */
	while (TI != 1) {;}

	// Clear it
	TI = 0; 

	/* Enable serial interrupts*/
    ES = 1;
 
}
/*=============================================================================*/


void uart_sendblock(uchar buf[], int len)
{
  uchar i;

  for (i = 0; i < len; i++)   uart_sendchar(buf[i]);   

}
/*=============================================================================*/

// Sync transmit/receiving
/*=============================================================================*/

void sync_sendchar(uchar c)
{
  int i;
  EA = 0;
  SDATA = 1;
  while (D_RDY == 0);      // wait for D_RDY to become high
  D_SYNC = 0;

  for (i = 0; i < 8; i++) { 
  	SDATA=(c & 0x01) ? 1:0 ;  // put data bit
	SCLK=0;
	SCLK=0;
	SCLK=0;
	SCLK=0;

	c >>= 1;	// next bit
	SCLK=1;
	SCLK=1;
	SCLK=1;
	SCLK=1;
  }

  D_SYNC = 1;

  SDATA=1;
 EA = 1;
}

/*=============================================================================*/

int sync_recved()
{
  return (RX_RDY == 0) ? 1 : 0;
}

/*=============================================================================*/

int sync_data_ready()
{
  return (D_RDY == 0) ? 1 : 0;
}

/*=============================================================================*/

// Call this function only when sync_recved() returns 1
int sync_getchar(void)
{
  
  uchar l;
  int c;
  EA = 0;
  D_SYNC = 1;
   
//  while(D_RDY!=0);

  for  (l = 0; l < 8; l++) {
	SCLK = 0;
	SCLK = 0;
	SCLK = 0;
	SCLK = 0;
	SCLK = 0;
	SCLK = 0;
	SCLK = 0;
	SCLK = 0;
	SCLK = 0;
	SCLK = 0;
	c >>= 1;
	if (SDATA) c |= 0x80;
	else c &= 0x7f;
	SCLK = 1;
	SCLK = 1;
	SCLK = 1;
	SCLK = 1; 
  } 
  D_SYNC = 1;	
  EA = 1;		
  return c;

}
/*=============================================================================*/


int sync_getblock(uchar buf[], int len)
{
  unsigned char i;

  for (i = 0; i < len; i++) {
    if (sync_data_ready())  buf[i] = sync_getchar();
	else return -1;
  }

  return len;

}


/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$<<<<<软件说明>>>>>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$* /


!!!!!!重复特别注意:写表的地址必须从串口写入才有效!!!!!
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$<<<<<软件说明>>>>>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/



⌨️ 快捷键说明

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