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

📄 emu-tdd.c

📁 keil c51 keil c51
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************************
	Copyright (c) 2006,Waycom Technology Development Co., Ltd.
	All rights reserved

	FileName: membank.c
	Summary: Process the data from laser telemeter and display the related distance
			data on LEDs.

	Old version: 1.1
	Programmer: Zorc
	Complete time: 3.14

	Original version: 1.0
	Programmer: Cui Haijing
	Complete time: 3rd March 2006
**********************************************************************************/
/**********************************************************************************
	Modification: Add the function of transferring the distance data to the train
				information device with CRC.

	Current version: 1.2
	Programmer: Zorc
	Complete time: 4.13
**********************************************************************************/
///////////////////////////// INCLUDE FILES //////////////////////////////////

#include <intrins.h>
#include <REGX55.H>
#include <math.h>

////////////////////////////// MACRO DEFINE //////////////////////////////////
 
#define uchar unsigned char
#define uint unsigned int

#define UART_CFG_W 0xc40a       // 1|1|enable fifo|disable shutdown|disable tx irq|enalbe rx irq|mask parity|disable ir mode|1 stop bit|disable parity bit|8-bit data|9600bps
#define UART_INT_EN 0

#define REG7281_MODE_ADD 0X12   // MODE REGISTER ADDRESS
#define REG7281_MODE_SET 0X82   // MODE=0,INV=1,SCEN=1
#define REG7281_BCD_ADD 0X14    // BCD REGISTER ADDRESS  
#define REG7281_SEG_ADD 0X18    // SEGMENT REGISTER ADDRESS

#define DP_ON 0X1F              // DISPOINT ON
#define DP_OFF 0x9f             // DISPOINT OFF

#define C66_EN 1                // ENABLE AT93C66 CHIP
#define C66_DIS 0               // DISABLE A93C66 CHIP  
#define C66_READ 0Xd000         // READ DATA AT ADDRESS=0X1000 ON AT93C66 
#define C66_EWEN 0X9800         // ERASE ENABLE FOR AT93C66
#define C66_WRITE 0Xb000        // WRITE DATA INSTRUCTION ADDRESS=0X1000 ON AT93C66
#define C66_ERASE 0Xf000        // ERASE DATA AT ADDRESS=0X1000 ON AT93C66
#define C66_EWDS 0X8000         // DISABLE WRITE AND ERASE 
#define C66_WRALL 0X8100        // WRITE ALL ADDRESS

#define SENSOR_FAULT 0          // SENSOR IS FAULTY
#define SENSOR_OK    1          // SENSOR IS OK
////////////////////////////// I/O DEFINE ////////////////////////////////////

sbit KEY_REP = P0^1;
sbit KEY_1 = P0^2;
sbit KEY_2 = P0^3;							
sbit BC_DATA = P0^4;
sbit BC_CLK = P0^5;
sbit SENSOR_DET = P0^6;  // sensor error light
sbit WDT_FEED = P0^7;  // watch-dog feeding flag
sbit DIN = P1^5;
sbit DOUT = P1^6;
sbit SCLK = P1^7;
sbit FIFO_CS1 = P2^0;
sbit FIFO_CS2 = P2^1;
sbit ADC_CS = P2^2;
sbit SSTRB = P2^3;
sbit EEPROM_CS = P2^4;
sbit FIFO_INT1 = P3^2;
sbit FIFO_INT2 = P3^3;

////////////////////////////// VARIABLES DECLARATION ///////////////////////////
bit cpu_ok = 0;  // cpu initialization flag
bit testFlag = 0;  // test the whole device when power on
bit key1_state = 0,key2_state = 0;  // increase and decrease key
uchar dis_dig[6] = {0,0,0,0,0,0};  // LED data
uint adc_data = 0;  // analog data: current * 200
int dstValue = 0;  // analog data: distance
int orgValue = 0;  // original data:distance
uint abCounter = 0;  // abnormity counter
uint tempCrc = 0;
bit displayMode = 0; // LED displaying mode
uchar modeCounter = 0;  // mode counter
uchar rxBuff = 0;  // received buffer
uchar rxNum = 0;  // number of received data
uchar rxData[4] = {0,0,0,0};  // received data
float zorcData = 0;
uchar uartByte[8] = {0x7E,0x91,0x21,0x02,0x03,0x04,0x05,0x7E};  // bytes transferred by uart
////////////////////////////// SUB-FUNCTION ////////////////////////////////////

void cpu_ini(void);  // initialize cpu

void delay(unsigned int mm);  // system delay function
 
void W_Config_uart(uchar chip_cs, uint config_data);   // configure MAX3100
uint R_Config_uart(uchar chip_cs, uint config_data);  // read the configuration of MAX3100
uint Write_uart(uchar chip_cs, uchar *frame_tx, uchar frame_len);  // write data into MAX3100
uint Read_uart(uchar chip_cs, uchar *frame_rx);  // read data out of MAX3100

void Send_7281(uchar reg_add, uchar reg_data);  // refresh

// operation on nonvolatile memory: c66
uchar Read_c66(uint read_addr);  // get current compensated value
void Write_c66(uint write_addr,uchar write_data);  // set compensated value
void Ewen_c66(uint ewen_ins);  // erase and write enable
void Erase_c66(uint erase_addr);  // erase current compensated value

uint Analog_input(uchar ch);  // analog data sampling

uint calCRC(uchar *ptr, uchar len);  // generate CRC code
///////////////////////////// MAIN //////////////////////////////////////////////

main()
{
    uchar tempMain;  // temporary variable in main function
	uchar tempArray;  // temporary variable of array
	float tempData = 0;  // data convert
	uchar timerFactor = 0;  // timer factor
	uchar testTemp = 0;  // test temporary value
	int tempValue = 0;  // temporary variable for distance value

    if(cpu_ok == 0)  // cpu uninitialized then do initialization
    {
        cpu_ini();
        W_Config_uart(1,UART_CFG_W);  // select chip 1
        W_Config_uart(2,UART_CFG_W);  // select chip 2
    }

	while(!testFlag)
	{
		if(TF1)     // 10ms timer 
        {
            TF1=0;
            TH1 = 50176 / 256;
            TL1 = 50176 % 256;

			if(++timerFactor == 30)  // timer factor
            {
                timerFactor = 0;

				Send_7281(REG7281_SEG_ADD,DP_OFF);  // turn on radix point light
				for(tempArray=0; tempArray<6; tempArray++)
				{
					dis_dig[tempArray] = testTemp;
					tempMain= tempArray << 4;
					tempMain= dis_dig[tempArray] | tempMain;
					Send_7281(REG7281_BCD_ADD, tempMain);
				}

				testTemp++;
				if(testTemp == 10)
				{
					testFlag = 1;
				}
			}
			WDT_FEED = !WDT_FEED;
		}
	}

	tempMain = Read_c66(C66_READ);
	dis_dig[4] = (tempMain / 10) % 10;	
	dis_dig[5] = tempMain % 10;

    while(testFlag)
    {
        if(TF1)     // 10ms timer
        {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		if(KEY_1 == 0)  // response to up-key operation
		{
			key1_state = 1;
		}
		else  // respond on keyup
		{
			if(key1_state == 1)
			{
				modeCounter = 0;
				if(dis_dig[5] == 9)
				{
					if(dis_dig[4] < 9)  // max compensation: 9.9m
					{
						dis_dig[4]++;
						dis_dig[5] = 0;
					}
				}
				else
				{
					dis_dig[5]++;
				}
				key1_state = 0;
				// record current compensation
				Ewen_c66(C66_EWEN);
				_nop_();
				Write_c66(C66_WRITE,dis_dig[4] * 10 + dis_dig[5]);
			}
		}
		if(KEY_2 == 0)  //  response to down-key operation
		{
			key2_state = 1;
		}
		else  // respond on keyup
		{
			if(key2_state == 1)
			{
				if(dis_dig[5] == 0)
				{
					if(dis_dig[4] >0)  // min compensation: 0.0m
					{
						dis_dig[4]--;
						dis_dig[5] = 9;
					}
					else
					{
						modeCounter++;  // keep pressing this key for 20 times will cause mode conversion
						if(modeCounter == 20)  // any other operation unqualified will clear this counter to zero
						{
							displayMode = !displayMode;
							modeCounter = 0;
						}
					}
				}
				else
				{
					dis_dig[5]--;
				}
				key2_state = 0;
				// record current compensation
				Ewen_c66(C66_EWEN);
				_nop_();
				Write_c66(C66_WRITE,dis_dig[4] * 10 + dis_dig[5]);
			}
		}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            TF1=0;
            TH1 = 50176 / 256;
            TL1 = 50176 % 256;

			adc_data += Analog_input(0);  // keep sampling for 16 times, then average these numbers
            if(++timerFactor == 16)  // timer factor
            {
                timerFactor = 0;
				if(displayMode == 0)  // normal mode
				{
					tempData = (float)adc_data / 16;
					tempData = tempData * 0.78125 - 625;  // 4-20mA => 0-2500cm
					dstValue = ceil(tempData / 10);  // round float to integer
					adc_data = 0;
				}
				else  // advanced mode
				{
					dstValue = ceil(zorcData / 10);
				}

				if(orgValue == 0)
					orgValue = dstValue;
				tempValue = dstValue - orgValue;
				if((tempValue > 4) || (tempValue < -20))
				{
					abCounter++;
					if(abCounter >= 100)
					{
						orgValue = dstValue;
					}
					else
					{
						dstValue = 0;
					}
				}
				else
				{
					orgValue = dstValue;
				}

				if((dstValue == 0) || (dstValue == -62))
				{
					dis_dig[0] = 11;
					dis_dig[3] = 11;
					dis_dig[2] = 11;
					dis_dig[1] = 11;

					SENSOR_DET = SENSOR_FAULT;
				}
				else
				{
					SENSOR_DET = SENSOR_OK;
					dstValue = dstValue - dis_dig[4] * 10 - dis_dig[5];  // compensation
					if(dstValue <= 0)
					{
						dis_dig[0] = 0;
						dis_dig[3] = 0;
						dis_dig[2] = 0;
						dis_dig[1] = 0;
					}
				//	else if(dstValue <= 100)	// removed by cui,JUNE.07
					else if(dstValue <= 200)	//
					{
						dis_dig[0]= dstValue % 10;
						dis_dig[3]= (dstValue / 10) % 10;
						dis_dig[2]= (dstValue / 100) % 10;
						dis_dig[1]= 0;
				 	}
				 	else
				 	{
				 		dis_dig[0]= 11;
						dis_dig[3]= 11;
						dis_dig[2]= 11;
						dis_dig[1]= 11;
					}
				 }
				 Send_7281(REG7281_SEG_ADD,DP_ON);  // turn on radix point light
				 for(tempArray=0; tempArray<6; tempArray++)		
				 {
				 	tempMain= tempArray << 4;
					tempMain= dis_dig[tempArray] | tempMain;
					Send_7281(REG7281_BCD_ADD, tempMain);
				 }

				 // transfer data by uart
				 uartByte[3] = dis_dig[2];  // Infor1 lower 4 bits
				 testTemp = dis_dig[3] & 0x07;
				 testTemp <<= 5;
				 uartByte[3] |= testTemp;  // Infor1 upper 3 bits
				 uartByte[4] = dis_dig[0] << 2;  // Infor2 middle 4 bits
				 uartByte[4] |= 0x02;  // middle number radix point
				 testTemp = dis_dig[3] >> 3;
				 uartByte[4] |= (testTemp & 0x01);  // Infor2 lowest bit

				 tempCrc = calCRC(&uartByte[1],4);	// added by cui.JUN.21.06
//				 uartByte[6] = calCRC(&uartByte[1],4) && 0xFF;  // removed by cui,JUN.21.06,FCS upper 8 bits
 				 uartByte[6] = tempCrc>>8;  //  FCS upper 8 bits, added by cui.JUN.21.06	   	
	
//				 uartByte[5] = (calCRC(&uartByte[1],4) >> 8) && 0xFF;  //removed by cui,JUN.21.06, FCS lower 8 bits
				 uartByte[5] = tempCrc ;	// FCS lower 8 bits,added by cui,JUN.21.06

				 Write_uart(1,&uartByte[0],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(1,&uartByte[1],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(1,&uartByte[2],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(1,&uartByte[3],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(1,&uartByte[4],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(1,&uartByte[5],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(1,&uartByte[6],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(1,&uartByte[7],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(2,&uartByte[0],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(2,&uartByte[1],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(2,&uartByte[2],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(2,&uartByte[3],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(2,&uartByte[4],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(2,&uartByte[5],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(2,&uartByte[6],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 Write_uart(2,&uartByte[7],1);
				 for(testTemp=0;testTemp<200;testTemp++)
				 	_nop_();
				 //Write_uart(2,&uartByte[1],6);
			}

			WDT_FEED = !WDT_FEED;
			/* if(++timerMode == 20)
			{
				timerMode = 0;
				SBUF = 0x73;  // s
				while(TI == 0);
				TI = 0;
				SBUF = 0x30;  // 0
				while(TI == 0);
				TI = 0;
				SBUF = 0x67;  // g
				while(TI == 0);
				TI = 0;
				SBUF = 0x0d;  // enter
				while(TI == 0);
				TI = 0;
				SBUF = 0x0a;  // newline
				while(TI == 0);
				TI = 0;
			} */
        }
    }
}


////////////////////////////// SUB-FUNTION //////////////////////////////////////
void cpu_ini()
{
	SCON=0x50;	// configurate the serial port to 8-bit at mode 1

	T2CON=0x30;  // configurate the timer2 to baud generator 
	TH2=65506/256;  // 19200bps at OSC=18.432Mhz
	TL2=65506%256;   //
	RCAP2H=65506/256;  //
	RCAP2L=65506%256;
	
	TR2=1;

    TMOD = 0X10;
    TH1 = 50176 / 256;  // 10ms timer
    TL1 = 50176 % 256;

    TR1=1;

    while(TF1==0);TF1=0;    // delay 10ms for bc7281 initialization
    TH1 = 50176 / 256;  // reload timer1,10ms timer
    TL1 = 50176 % 256; 
        

    FIFO_CS2=1;      // disable uart 
    FIFO_CS1=1;      // disable uart
    SCLK=0;
    DIN=0;
    DOUT=0;
    BC_DATA=1;
    BC_CLK=1;
    EEPROM_CS=C66_DIS;


    Send_7281(REG7281_MODE_ADD,REG7281_MODE_SET);

    
	EA=1;
	ES=1;
//    DO_CS=0;
//    DI_CS=1;
	
	cpu_ok=1;
}

serial () interrupt 4 using 1  // interrupt signal
{
	if(RI==1)
	{
		RI=0;
		rxBuff = (uchar)SBUF;
		if(rxBuff == 0x2b)
		{
			rxNum = 1;
		}
		if((rxNum >= 4) && (rxNum <= 7))
		{
			rxData[rxNum - 4] = rxBuff - 30;
		}
		if(rxBuff == 0x0d)
		{
			rxNum = 0;
			zorcData = (float)(rxData[0] * 1000 + rxData[1] * 100 + rxData[2] * 10 + rxData[3]);
		}
		else
		{
			if(rxNum != 0)
			{
				rxNum++;
			}
		}
		rxBuff = 0;
	}
}

void W_Config_uart(uchar chip_cs,uint config_data)   // configure MAX3100
{
   uchar i;
 	
   EA=0;
   if(chip_cs==1)   // chip select ,enable MAX3100
   {
        FIFO_CS1=1;
        _nop_();

⌨️ 快捷键说明

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