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

📄 host.c

📁 智能数字电流表。双CPU工作
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************
 程序名:host
 功能:测量电流,并发数据发送给LED595程序,接受用户键盘输入跟设置。
 创建时间:2004-3-30
 作者:华明 
 ******************************************************************/

#include <reg52.h>
#include <intrins.h>
#include "host.h"
#include "SEGCODE.h"

#define SIZE_OF_KEYBD_MENU 30   //菜单长度
//#define nop2() _nop_();_nop_();

KbdTabStruct code KeyTab[SIZE_OF_KEYBD_MENU] = 
{
	{0,  0,  0,  0,  1, (*OptionProg)},
	{1,  5,  2,  0,  6, (*OptionAYS)},
	{2,  1,  3,  0,  7, (*OptionIn_Out)},
	{3,  2,  4,  0,  9, (*OptionALR)},
	{4,  3,  5,  0, 11, (*OptionSecr)},
	{5,  4,  1,  0, 12, (*OptionAdBd)},
	{6,  6,  6,  1,  1, (*AutoZero)},
	{7,  8,  8,  2, 14, (*InputX)},
	{8,  7,  7,  2, 15, (*OutputX)},
	{9, 10, 10,  3,  3, (*ALROFF)},
	{10, 9,  9,  3, 16, (*ALRON)},  
	{11,11, 11,  4,  4, (*Passward)},
	{12,13, 13,  5, 18, (*AddrX)}, 
	{13,12, 12,  5, 19, (*BaudX)},
	{14,14, 14,  7, 20, (*Inp)}, 
	{15,15, 15,  8, 21, (*Oup)},
	{16,17, 17, 10, 22, (*ALRLX)},
	{17,16, 16, 10, 23, (*ALRHX)},
    {18,18, 18, 12, 24, (*Address)},
	{19,19, 19, 13, 25, (*Baud)},
	{20,20, 20, 14,  7, (*SetInput)},
	{21,21, 21, 15, 26, (*SetOutput)},
	{22,22, 22, 16, 27, (*AL_L)},
	{23,23, 23, 17, 28, (*AL_H)},
	{24,24, 24, 18, 19, (*SetAddress)},
	{25,25, 25, 19, 18, (*SetBaud)},
	{26,26, 26, 21, 29, (*Point)},
	{27,27, 27, 22, 23, (*SetAL_L)},
	{28,28, 28, 23, 22, (*SetAL_H)},
	{29,29, 29, 26,  8, (*SetPoint)}
};

 /*25045操作子程序集*/
/*;*******************************************************************************************
*
;* Name: WREN_CMD
;* Description: Set write enable latch
;* Function: This routine sends the command to enable writes to the EEPROM memory array or
;* status register
;* Calls: outbyt
;* Input: None
;* Outputs: None
;* Register Usage: A
;*******************************************************************************************
*/
/*写使能子程序*/
void wren_cmd(void)
{
 uchar aa;
 SCK=0;/* Bring SCK low */
 CS=0;/* Bring /CS low */
 aa=WREN_INST;
 outbyt(aa);/* Send WREN instruction */
 SCK=0;/* Bring SCK low */
 CS=1;/* Bring /CS high */
}


/*;*******************************************************************************************
*
;* Name: WRDI_CMD
;* Description: Reset write enable latch
;* Function: This routine sends the command to disable writes to the EEPROM memory array or
;* status register
;* Calls: outbyt
;* Input: None
;* Outputs: None
;* Register Usage: A
;*******************************************************************************************
*/
/*写使能复位子程序*/

//void wrdi_cmd(void)
//{
// uchar aa;
// SCK=0;/* Bring SCK low */
// CS=0;/* Bring /CS low */
// aa=WRDI_INST;
// outbyt(aa);/* Send WRDI instruction */
// SCK=0;/* Bring SCK low */
// CS=1;/* Bring /CS high */
//}

/*;*******************************************************************************************
*
;* Name: WRSR_CMD
;* Description: Write Status Register
;* Function: This routine sends the command to write the WD0, WD1, BP0 and BP0 EEPROM
;* bits in the status register
;* Calls: outbyt, wip_poll
;* Input: None
;* Outputs: None
;* Register Usage: A
;*******************************************************************************************
*/
/*写状态寄存器子程序*/
void wrsr_cmd(void)
{
 uchar aa;
 SCK=0;/* Bring SCK low */
 CS=0;/* Bring /CS low */
 aa=WRSR_INST;
 outbyt(aa) ;/* Send WRSR instruction */
 aa=STATUS_REG;
 outbyt(aa);/* Send status register */
 SCK=0;/* Bring SCK low */
 CS=1;/* Bring /CS high */
 wip_poll();/* Poll for completion of write cycle */
}

/*;*******************************************************************************************
*
;* Name: RDSR_CMD
;* Description: Read Status Register
;* Function: This routine sends the command to read the status register
;* Calls: outbyt, inputbyt
;* Input: None
;* Outputs: A = status registerXicor Application Note AN21
;* Register Usage: A
;*******************************************************************************************
*/
/*读状态寄存器,读出的数据放入到aa中*/
uchar rdsr_cmd (void)
{
 uchar aa;
 SCK=0;
 CS=0;
 aa=RDSR_INST;
 outbyt(aa);
 aa=inputbyt();
 SCK=0;
 CS=1;
 return aa;
}

/*;*******************************************************************************************
*
;* Name: BYTE_WRITE
;* Description: Single Byte Write
;* Function: This routine sends the command to write a single byte to the EEPROM memory
array
;* Calls: outbyt, wip_poll
;* Input: None
;* Outputs: None
;* Register Usage: A, B
;*******************************************************************************************
*/
/*字节写入,aa为写入的数据,dd为写入的地址,对于25045而言为000-1FF*/
void byte_write(aa,dd)
uchar aa;
uint dd;
{
 SCK=0;
 CS=0;
 outbyt((uchar)(dd>255?(0x08|WRITE_INST):WRITE_INST));
 //outbyt((((uchar)(dd-0XFF))<<3)|WRITE_INST);/* Send WRITE instruction including MSB of address */
 /*将高位地址左移3位与写入先导字相或,得到正确的先导字写入25045*/
 outbyt((uchar)(dd&0x00ff));
 /*输出低位地址到25045*/
 outbyt(aa);
 /*写入数据到25045的对应单元*/
 SCK=0;
 CS=1;
 wip_poll();
 /*检测是否写完*/
}

/*;*******************************************************************************************
*
;* Name: BYTE_READ
;* Description: Single Byte Read
;* Function: This routine sends the command to read a single byte from the EEPROM memory
array
;* Calls: outbyt, inputbyt
;* Input: None
;* Outputs: A = read byte
;* Register Usage: A, BXicor Application Note AN21
;*******************************************************************************************
*/
/*字节读出,其中dd为读出的地址,返回的值为读出的数据*/
uchar byte_read(dd)
uint dd;
{
 uchar cc;
 SCK=0;
 CS=0;
 outbyt((uchar)(dd>255?(0x08|READ_INST):READ_INST));
 //outbyt((((uchar)(dd-0XFF))<<3)|READ_INST);/* Send READ_INST instruction including MSB of address */
 /*将高位地址左移3位与读出先导字相或,得到正确的先导字写入25045*/
 outbyt((uchar)(dd&0x00ff));
 /*输出低位地址到25045*/
 cc=inputbyt();/*得到读出的数据*/
 SCK=0;
 CS=1;
 return cc;
}

/*;*******************************************************************************************
*
;* Name: PAGE_WRITE
;* Description: Page Write
;* Function: This routine sends the command to write three consecutive bytes to the EEPROM
;* memory array using page mode
;* Calls: outbyt, wip_poll
;* Input: None
;* Outputs: None
;* Register Usage: A, B
;*******************************************************************************************
*/
/*页面写入,其中aa1,aa2,aa3,aa4为需要写入的4个数据(最大也就只能一次写入4个字,dd为写入的首地址*/
void page_write(aa1,aa2,aa3,aa4,dd)
uchar aa1,aa2,aa3,aa4;
uint dd;
{
 SCK=0;
 CS=0;
  outbyt((uchar)(dd>255?(0x08|WRITE_INST):WRITE_INST));
 //outbyt((((uchar)(dd-0XFF))<<3)|WRITE_INST);/* Send WRITE instruction including MSB of address */
 /*将高位地址左移3位与写入先导字相或,得到正确的先导字写入25045*/
 outbyt((uchar)(dd&0x00ff));
 /*写入低位地址到25045*/
 outbyt(aa1);
 /*写入数据1到25045的对应单元*/
 outbyt(aa2);
 /*写入数据2到25045的对应单元*/
 outbyt(aa3);
 /*写入数据3到25045的对应单元*/
 outbyt(aa4);
 /*写入数据4到25045的对应单元*/
 SCK=0;
 CS=1;
 wip_poll();
}

/*;*******************************************************************************************
*
;* Name: RST_WDOG
;* Description: Reset Watchdog Timer
;* Function: This routine resets the watchdog timer without sending a command
;* Calls: None
;* Input: None
;* Outputs: None
;* Register Usage: None
;*******************************************************************************************
*/
/*复位DOG*/
void rst_wdog (void)
{
     CS=0;
     CS=1;
}

/*;*******************************************************************************************
*
;* Name: WIP_POLL
;* Description: Write-In-Progress Polling
;* Function: This routine polls for completion of a nonvolatile write cycle by examining the
;* WIP bit of the status register
;* Calls: rdsr_cmdXicor Application Note AN21
;* Input: None
;* Outputs: None
;* Register Usage: R1, A
;*******************************************************************************************
*/
/*检测写入的过程是否结束*/
void wip_poll(void)
{
 uchar aa;
 uchar idata my_flag;
 for (aa=1;aa<MAX_POLL;aa++)
 {
  my_flag=rdsr_cmd();
  if ((my_flag&&0x01)==0) {aa=MAX_POLL;}/*判断是否WIP=0,即判断是否写入过程已经结束,若结束就跳出,否则继续等待直到达到最大记数值*/
 }
}

/*;*******************************************************************************************
*
;* Name: OUTBYT
;* Description: Sends byte to EEPROM
;* Function: This routine shifts out a byte, starting with the MSB, to the EEPROM
;* Calls: None
;* Input: A = byte to be sent
;* Outputs: None
;* Register Usage: R0, A
;*******************************************************************************************
*/
/*输出一个数据到25045,此数据可能为地址,先导字,写入的数据等*/
void outbyt(aa)
uchar aa;
{
	uchar Data, i;
	Data = aa;
	for (i=0; i<8; i++)
	{
		SCK=0;
    	SI = (bit)(Data & 0x80);
		Data = Data << 1;
		SCK=1;
	}
    SI=0;/*使SI处于确定的状态*/ 
}

/*;*******************************************************************************************
*
;* Name: INPUTBYT
;* Description: Recieves byte from EEPROM
;* Function: This routine recieves a byte, MSB first, from the EEPROM
;* Calls: None
;* Input: None
;* Outputs: A = recieved byte
;* Register Usage: R0, A
;*******************************************************************************************
*/
/*得到一个数据,此数据可能为状态寄存器数据,读出的单元数据等*/
uchar inputbyt(void)
{
	uchar uData;
    char i;
    for (i=0; i<8; i++)
    {
         SCK=1;
         SCK=0; 
         uData *= 2;
	 	 if (SO)  
	 	     uData ++;
    }
    return uData;	
}

void WriteParams()    //保存参数
{
	//保存零位到地址0;
	wren_cmd();
	page_write(Param.wZero.b[0], Param.wZero.b[1],
		Param.wZero.b[2], Param.wZero.b[3], 0);
	//保存校准信号到地址4;
	wren_cmd();
	page_write(Param.wInCount.b[0], Param.wInCount.b[1],
		Param.wInCount.b[2], Param.wInCount.b[3], 4);
	//保存输入值到地址8, 输出值到10;
	wren_cmd();
	page_write(Param.wInput.b[0], Param.wInput.b[1],
		Param.wOutput.b[0], Param.wOutput.b[1], 8);
	//保存报警下限到地址12,报警上限到地址14;
	wren_cmd();
	page_write(Param.wALR_L.b[0], Param.wALR_L.b[1],
		Param.wALR_H.b[0], Param.wALR_H.b[1], 12);
	//保存报警标志位,波特率下标,小数点位置,地址到地址16
	wren_cmd();
	page_write(Param.bAlert, Param.BaudIndex, 
		Param.PointPos, Param.bAddress, 16);
	//保存密码下标到地址20
	wren_cmd();
	byte_write(Param.Password.b[0], 20);
	wren_cmd();
	byte_write(Param.Password.b[1], 21);
}

void ReadParams()     //读参数
{
	uchar i;
	//读零位
	for (i=0; i<4; i++)
		Param.wZero.b[i] = byte_read(i);
	//读校准信号
	for (i=0; i<4; i++)
		Param.wInCount.b[i] = byte_read(i+4);
	//读输入值
	Param.wInput.b[0] = byte_read(8);
	Param.wInput.b[1] = byte_read(9);
	//读输出值
	Param.wOutput.b[0] = byte_read(10);
	Param.wOutput.b[1] = byte_read(11);
	//读报警下限
	Param.wALR_L.b[0] = byte_read(12);
	Param.wALR_L.b[1] = byte_read(13);
	//读报警上限
	Param.wALR_H.b[0] = byte_read(14);
	Param.wALR_H.b[1] = byte_read(15);
	//读报警标志位
	Param.bAlert = byte_read(16);
	//读波特率下标
	Param.BaudIndex = byte_read(17);
	//读小数点位置
	Param.PointPos = byte_read(18);
	//读地址
	Param.bAddress = byte_read(19);
	//读密码
	Param.Password.b[0] = byte_read(20);
	Param.Password.b[1] = byte_read(21);
}

void Delay(uint utime, uint utime2) reentrant
{ 
	uint utimein;
	while (utime --)
	{
		rst_wdog();    
		utimein = utime2;
		while(utimein --)
			rst_wdog();
	}
	return;
}

void I_Send(byte Data)
{
     register byte i;
	 //发送8位数据
	 for (i=0; i<8; i++)
	 {
	 	 CLK = 0;
		 _nop_();
		 _nop_();
		 _nop_();
		 _nop_();
		 _nop_();
		 DATA = (bit)(Data & 0x80);
		 Data = Data << 1;
		 CLK = 1;
	 }
	 CLK = 0;
	 return;
}

//显示数据
void Display(dword Data, uchar PointIndex) reentrant
{
	byte Value, i;
	uchar Array[5];
	//换算段码
	for (i=0; i<5; i++)
	{
		Value = Data % 10;
		Data = Data / 10;
		if ((i == 4 - PointIndex) && (PointIndex < 4))
		    Array[i] = uLEDChar[Value] | 0x40;
		else
		    Array[i] = uLEDChar[Value];
		rst_wdog();
	}
	//去除开始的0
	while (i--)
	{
		if ((Array[i] == 0x3f) && (i > 4-PointIndex))
		{    
			Array[i] = 0x00;
			rst_wdog();
		}
		else
		{
			rst_wdog();
			break;
		}
	}
	TRG = 1;
	TRG = 0;
	I_Send('T');
	Delay(1, 5);
    for (i=0; i<5; i++)
	{
		 I_Send(Array[i]);
		 rst_wdog();
	}
	return;
}

void GetKeyInput()
{
	uchar KeyValue;
	KeyValue = P2 & 0xF0;   //去掉低4位
	if (KeyValue != 0xF0)
	{
		flag = 0;
		Delay(15, 500);
		KeyValue = P2 & 0xF0;
    	while ((P2 & 0xF0) != 0xF0)
		     rst_wdog();
		switch (KeyValue)
		{
		case 0xE0:  //左键
			KeyFuncIndex = KeyTab[KeyFuncIndex].KeyLeftState;
			if (KeyFuncIndex == 0) 
			    flag = 1;	
			break;
		case 0xD0:  //右键
			KeyFuncIndex = KeyTab[KeyFuncIndex].KeyRightState;
			if (KeyFuncIndex == 0) 
			    flag = 1;	
			break;
		case 0xB0:  //MENU
			KeyFuncIndex = KeyTab[KeyFuncIndex].KeyMenuState;	
			break;
		case 0x70:  //回车
			KeyFuncIndex = KeyTab[KeyFuncIndex].KeyEnterState;

⌨️ 快捷键说明

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