📄 emu-tdd.c
字号:
/**********************************************************************************
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 + -