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

📄 485_0103.c

📁 485通信程序
💻 C
字号:
/****************************************************************************************************
			                  uPD78F0881 Uart61 transmit/Receive programme module
 uart61 test programme module  
 manipulate: send several byte data by computer Com tools.
  MCU when receive these data,it will send back  0x01,0x02,0x03,0x04 to computer.
*****************************************************************************************************/
#pragma SFR
#pragma EI
#pragma DI
#pragma NOP
#pragma	interrupt  INTSR61  Uart_INTSR61 RB1
#pragma interrupt  INTTM50  Timer_INTTM50 RB2

#include "Uart61.h"

void main(void);
callt void Uart61_Init( void );
callt void UartSend_Byte( uchar ch );
callt void Uart_Send( uchar* txbuf, uchar txnum );

uchar try[4]={0x01,0x02,0x03,0x04};
uchar Uart_Rx[20];
uchar pointer = 0;
bit  Uart_Rx_Flag;  //recevie ok
unsigned long int L;

//CRC
unsigned char CRC_L,CRC_H,CRC_i,CRC_DATA;

void hdwinit( void )  //PM == 0 output
{						                 
	DI();
	IMS = MEMORY_IMS_SET;    
	IXS = MEMORY_IXS_SET;
										// Clock operation port mode (OSCCTL register)
	AMPH   = 0;       // select the external Clock frequency range(4MHz < fXH <= 10MHz)
    EXCLK  = 0;       //select the externa High-speed system clock operation mode(fX or fEXCLK or STOP)
    OSCSEL = 1;                         // External resonator connected to fX1 and fX2 input
	EXCLKS = 0;                         //(fXT or fEXCLKS or STOP)
	OSCSELS = 0;						// XT1 stop working
	
	// (permit) High-speed input clock operating (X1)
    MOC  = 0x00;                        
                                        // 00000000 = 0x00
                                        // |-------   High-speed input clock operation
                                        // |-------   --------------------------------
                                        // |-------   fXH input clock             | External clock input
                                        // |-------   ----------------------------+-------------------------
                                        // 0 -------- fXH input clock oscillating | External clock operating
                                        // 1 -------- fXH input clock stopped     | External clock stopped

// Check Oscillation stabilization time status

//waiting for the X1 clock oscillation stabilization time 
//--------------------------------------------
// The necessary oscillation stabilization time must be known beforehand.
// Pls. refer to the DS or UM of the oscillator manufacturer.
    while(OSTC < 0x1f)                  // Wait until fXH clock stabilization
    {                                   // time has been elapsed

        //----------------------------------------------------------
        // During X1 oscillation stabilization time status check
        // some other initializations, e.g. ports, can be done,
        // dependent on the needed X1 oscillation stabilization time
        // 102.4祍...3.28ms @ 20MHz
        //----------------------------------------------------------

        NOP();
    }

  //Oscillation stabilization time after STOP mode release
  //The wait time set by OSTS is valid only after the STOP mode is released with the X1 clock selected as the CPU clock. 
    OSTS = 0x01;                        // 512us@4MHz wait after STOP mode release (RESET value)
                                        // 00000101 = 0x05
                                        // -----|||   Osc. stabilization time
                                        // -----|||   -----------------------
                                        // -----001 - 2^11/fx
                                        // -----010 - 2^13/fx
                                        // -----011 - 2^14/fx
                                        // -----100 - 2^15/fx
                                        // -----101 - 2^16/fx
                                        // -----other settings prohibited



//This register is used to select the CPU clock and the division ratio
//---------------------------------------------
    PCC  = 0x00;                        // Use high speed mode fCPU = 4MHz
                                        // 00000000 = 0x00
                                        // -----|||   CPU clock selection fCPU
                                        // -----|||   ------------------------
                                        // -----000 - fx
                                        // -----001 - fx/2
                                        // -----010 - fx/2^2
                                        // -----011 - fx/2^3
                                        // -----100 - fx/2^4
                                        // -----other settings prohibited


// selects the main system clock supplied to CPU clock and clock supplied to peripheral hardware clock. 
//-----------------------------------------------------------------
// The maximum time required to switch between ring oscillator clock and
// fXH clock is 2 clocks

 // fXH clock supplied to the peripherals
    XSEL = 1;                         

    do
    {
        MCM0 = 1;                       // fXH clock supplied to CPU
                                        // 00000001 = 0x01
                                        // -----|||   CPU clock status
                                        // -----|||   ----------------
                                        // -----||0 - Operates with ring oscillator clock
                                        // -----||1 - Operates with X1 input clock
                                        // -----||
                                        // -----||    Selection of clock supplied to CPU and peripherals
                                        // -----||    --------------------------------------------------
                                        // -----00 -- fCPU = fRH / fPRS = fRH
                                        // -----01 -- fCPU = fRH / fPRS = fRH
                                        // -----10 -- fCPU = fRH / fPRS = fXH
                                        // -----11    fCPU = fXH / fPRS = fXH <---
                                        //      |
                                        //      +---- XSEL

    }
   while(MCS != 1);                    // Check if CPU operates with fXH clock( bit MCS IS read-only)
                                        // If no  => Retry to switch CPU clock
                                        // If yes => continue

// Switch off the high-speed and the low-speed Ring-OSC
//-----------------------------------------------------
// select the operation mode of internal oscillator  (all stop) 
    RCM  = 0x01;                        // High-speed Ring-OSC oscillating
                                        // High-speed Ring-OSC low accuracy (stop)
                                        // Low-speed Ring-OSC oscillating (stop)
                                        // 00000000 = 0x00
                                        // |-----||   High-speed Ring-OSC operation
                                        // |-----||   -----------------------------
                                        // |-----|0 - High-speed Ring-OSC oscillating
                                        // |-----|1 - High-speed Ring-OSC stopped
                                        // |-----|
                                        // |-----|    Low-speed Ring-OSC operation
                                        // |-----|    ----------------------------
                                        // |-----0 -- Low-speed Ring-OSC oscillating
                                        // |-----1 -- Low-speed Ring-OSC stopped
                                        // |
                                        // |          High-speed Ring-OSC accuracy status
                                        // |          -----------------------------------
                                        // 0 -------- High-speed Ring-OSC low accuracy
                                        // 1 -------- High-speed Ring-OSC high accuracy
	EI();
}

void Lvi_Init( void )
{
	LVIMK = 1;					//disable LVI interrupt
	LVISEL = 0;					//Detect level of supply voltage
	LVIS = 0X02;				//detection voltage level:3.93V
	//LVIIF = 0;
	//LVIMK = 0;
	//LVIPR = 1;
	LVIMD = 0;					//generates intenal reset when the level is detected
	LVION = 1;					//enable LVI operation
}

//Init receive enable,transmit disable  
callt void Uart61_Init( void )
{
	PM1.0 = 0;     //output TX
	P1.0 = 1;						/* port setting in transmit mode */
	PM1.1 = 1;	//input	 RX				/* port setting in receive mode */
	PU1.1 = 1;						//on-chip pull-up resistor connected	
	
	ASIM61 = 0; //TXE61) and bit 5 (RXE61) of the ASIM61 register = 0 when rewriting the MDL671 to MDL601 bits.   
	/* baudrate selection = 9600 */
	CKSR61 = 0x00;		   //4MHZ 2M    
	BRGC61 = 0xd0;         // BAUD=2M/0xd0

	ASIM61 = 0x04;					/* data length 8 bits;stop length 1 bits;Does not output parity bit mode */
	ASICL61.1 = 1;					/* LSB first transfer */
	ASICL61.0 = 0;					/* normal output of TxD61 */

//interrupt setting
	STMK61 = 1;						/* transfer end interrupt disable */
	STIF61 = 0;
	
	SRIF61 = 0;						/* receive end interrupt enable */
	SRMK61 = 0;                     //0 Interrupt servicing enabled 
						
	SREIF61 = 0;
	SREMK61 = 1;					/* error interrupt disable */
	
	SRPR61 = 0;						/* interrupt high */
	SREPR61 = 0;					/* interrupt high */

//open when need
	POWER61 = 1;
	RXE61 = 1;						// Receive enable   
	TXE61 = 0;						/* transmit disable */
	
}

void Motor_Init(void)
{
  PM0.0=0;P0.0=0;                //Up rotation initialize
  PM0.1=0;P0.1=0;               //Down rotation initialize
  PM3.0=0;P3.0=0;               //Left rotation initialize
  PM3.3=0;P3.3=0;               //Right rotation initialize
}

callt void UartSend_Byte( uchar ch )
{
	TXB61 = ch;
	while(!STIF61);
	STIF61 = 0;
}

/* Data transfer */
//enable send,disable receive(when send data),after send enable receive
callt void Uart_Send( uchar* txbuf, uchar txnum )
{
	POWER61 = 1;
	TXE61 = 1;//enable send,disable receive
	RXE61 = 0;
	
	//Delay( 2 );						//delay 1ms,wait until hardware work stably
	if( txnum < 1)
	{
		return;
	}
	else
	{
		do
		{
			UartSend_Byte( *txbuf++ );
			txnum--;
		}while( txnum != 0 );
	}
	//Delay( 2 );						//delay 1ms,wait until the last byte was transmited
	TXE61 = 0;
	RXE61 = 1;							//disable send,enable receive
}


void Timer50_Init( void )
{
	TMIF50 = 0;   				//clear the Timer50 interrupt flag
	TMMK50 = 0;					/*enable interrupt INTTM50*/
	TMPR50 = 0;					/*interrupt INTTM50 High*/
	
	//Timer clock selection register
	TCL50 = 0x06;				/*TM50 count clock=fprs/2^8*/
	//8-bit timer compare register 
	CR50 = 0xeb;				/*interval time*fprs/2^8-1,interval time = 15ms*/
	//8-bit timer mode control register
	TMC50 = 0x00;	/*clears and starts on match between TM50 and CR50;output disabled*/
	//TCE50 = 1;     //Count operation start 
}

void CRC(void)					//CALCULATE:THE CRC INPUT:CRC_L,CRC_H,CRC_DATA, OUTPUT:CRC_L,CRC_H
{
	CRC_L=CRC_L^CRC_DATA;
	for(CRC_i=0;CRC_i<8;CRC_i++)
	{	if(CRC_L%2)
		{	CRC_L=CRC_L>>1;		//	/2;
			if(CRC_H%2)
			{
				CRC_H=CRC_H>>1;	//	/2;
				CRC_L=CRC_L|0x80;
			}
			else CRC_H=CRC_H>>1;	// /2;		
			CRC_L=CRC_L^0x01;
			CRC_H=CRC_H^0xA0;
		}
		else
		{
			CRC_L=CRC_L>>1;			// /2;		
			if(CRC_H%2)
			{
				CRC_H=CRC_H>>1;		// /2;
				CRC_L=CRC_L|0x80;
			}
			else CRC_H=CRC_H>>1;	// /2;	
		}
	}
}

void Check(void)
{  unsigned char i;
   CRC_L=0xFF;CRC_H=0xFF; //Set the initial value of the verify
   for(i=0;i<=1;i++)
    {CRC_DATA=Uart_Rx[i];
     CRC();
     if(Uart_Rx[i+1]!=CRC_L)	return;
     if(Uart_Rx[i+2]!=CRC_H)	return;
    }
}

__interrupt void Timer_INTTM50( void )//interval between Uart receive byte overflow 15ms
{
	EI();
	TCE50 = 0;							//disable Timer50
	Uart_Rx_Flag = 1;
	//disable UART61
	RXE61 = 0;
	TXE61 = 0;
	POWER61 = 0;						//disable UART61
	
}

/* UART61 receive end interrupt handler */
__interrupt void Uart_INTSR61( void )
{
	uchar tmp,ErrUart61;
	//interrupt will close when go into interrupt handler programmes, so open again is necessary
	EI();   
	//restart Timer50
	TCE50 = 0;  //clear the Timer            
	TCE50 = 1;	//Count operation start
	ErrUart61 = ASIS61; //will be cleared when read.if is not cleared,uart61 will not receive new data to RXB61
	
	tmp = RXB61;
	Uart_Rx[pointer] = tmp;
	pointer ++;
	Check();
	
	if(pointer> Uart_Rx_Len)   //over the size of Uart_Rx[]
	{
		//disable UART61
		pointer = 0;
		RXE61 = 0;
		TXE61 = 0;
		POWER61 = 0;
		Uart_Rx_Flag = 1;
	}
}

callt void System_Init()
{	
	 Lvi_Init();
	 Timer50_Init();
	 Uart61_Init();
	 Motor_Init();
}

void Motor_Control(void)
 { if(Uart_Rx[0x0]==0x01)
     {//Up Control
       P0.0=1;
	   L=2000;
	   while(L--) {;}
	   P0.0=0;
	 }
    else if(Uart_Rx[0x0]==0x02)
	 {  //Down control
	   P0.1=1;
	   L=2000;
	   while(L--) {;}
	   P0.1=0;
     }
	else if(Uart_Rx[0x0]==0x03)
      { //Left control
         P3.0=1;
		 L=2000;
	     while(L--) {;}
	     P3.0=0;
	  }
	else if(Uart_Rx[0x0]==0x04)
      { //Right control
          P3.3=1;
		  L=2000;
		  while(L--) {;}
		  P3.3=0;
	  }
    else
    {
          NOP();
    }
		           
     }

void main(void)
{
	DI();
	System_Init();
	EI();
	PM4.0=0;
	P4.0 = 0;
	//TCE50 = 1;
	while(1)
	{
		WDTE = 0xac; //clear the WDT 
		if(Uart_Rx_Flag)
		{
			pointer = 0;
			Uart_Rx_Flag = 0;
			P4.0 = 1;
			Uart_Send(Uart_Rx,4);
			P4.0=0;
			Motor_Control();
		   }
		}
		NOP();
}

⌨️ 快捷键说明

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