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

📄 zl932.c

📁 这是一个输入为0-75mV的直流电表程序
💻 C
字号:
//报警和通讯功能,无变送功能
//0-75mv直流

#include <reg932.h>
#include <math.h>

#define mima_code1 2004
#define mima_code2 1999
#define mima_code3 2005
#define mima_code4 2006

#define N 10                       //通讯缓存区长度 
unsigned char idata Serial_buf[N]; //定义通讯缓存区

//---------------------------------------//
//----------------定义I/O----------------//
//---------------------------------------//

sbit P0_2      =  P0^2;
sbit P0_3      =  P0^3;
sbit P0_7      =  P0^7;
sbit CLK_7281  =  P1^2;
sbit DAT_7281  =  P0^1;
sbit KEY_7281  =  P2^6;
sbit CS_5460   =  P0^5;
sbit RES_5460  =  P0^6;
sbit P2_7      =  P2^7;
sbit PLEEN	   =  TCR20^7;

//---------------------------------------//
//------------定义函数功能---------------//
//---------------------------------------//

void write7281(unsigned char,unsigned char);
void send_byte7281(unsigned char);
unsigned char read7281(unsigned char);
unsigned char receive_byte7281(void);
void delay(unsigned char);
void delay_long(unsigned char);
void key_deal();
void key_paraing();
void key_shifting();
void key_incing();
void Dis_play(unsigned char x,unsigned char y,unsigned char z);
void Display_end();
void Display();
void transmit();

void clrwdt();
void init_wdt();
void init();
void UART_INIT();
void SET_SPI();

void calccrc(unsigned char crcbuf);
unsigned char Receive_Data();
bit Receive_One(unsigned char *s);
void Send_Data(unsigned char Serial_data);
void TXD_Int(unsigned char *s);
void Serial_Command_Run(unsigned char *s);

void take_E2PROM();
void MSEND_COMM(unsigned char ch_code);
void MRCV_DAT();
void MSEND_DAT(unsigned char comm1,unsigned char comm2,unsigned char comm3);
void jiaozhun(unsigned char jj,unsigned char kk,unsigned char mm);
void reslove_E2PROM(unsigned char kk,unsigned char mm);
void read_E2PROM(unsigned char mm,unsigned char kk);
unsigned int jisuan(void);
long ji_suan(void);
void LPC932_PWM();//unsigned char pwm1,unsigned char pwm2);
void LPC932PWM();

//---------------------------------------//
//--------------定义变量-----------------//
//---------------------------------------//

unsigned int code_dh,code_dl;
unsigned int code_eh,code_el;
unsigned int code_dhl,code_ehl;
unsigned int baojing_bh,baojing_bl;
unsigned char led_code[4];
unsigned char led_pre[4]={0x00,0x10,0x20,0x30};  //定义显示数码管的位
unsigned char led_flash[4]={0xfe,0xfd,0xfb,0xf7};//定义闪烁寄存器
unsigned char keymark=0;
unsigned char key_value,chcode[4];
unsigned char baocun[2];
long xdata reg_number,reg_number1;
float ShowNum;
unsigned int PWM_value,crc;
unsigned char led_number=0;
unsigned char xsd_value;//小数点的值,0为不设小数点,1为小数点在左起第3个数码管
                        //2为小数点在左起第2个数码管,3为小数点在左起第1个数码管
unsigned char brgr1,brgr0;
unsigned char brgr;

bit shift_flag=0;//移位键使能标志
bit inc_flag=0;//加1键使能标志
bit mima_flag1=0,mima_flag2=0;
bit mima_flag3=0,mima_flag4=0;
bit Display_flag=0;//显示标志
bit xsd_flag=0;
bit PWM_flag=0;
bit baud_flag=0;

//---------------------------------------//
//--------------主程序-------------------//
//---------------------------------------//

void main()
{
   	init();
	init_wdt();
	SET_SPI();
	CS_5460=0;
	take_E2PROM();
	UART_INIT();
	LPC932_PWM();
	MSEND_COMM(0x4a);              //写周期计数寄存器1000
	MSEND_DAT(0x00,0x03,0xe8);
	write7281(0x12,0x80);          //7281写控制字
	write7281(0x10,0xff);
	MSEND_COMM(0xe8);
	//KEY_7281=1;
	while(1)
	{
		if(KEY_7281==0)
		key_deal();
		clrwdt();
		if(!Display_flag)
		{
			//读取最新计算周期电压有效值结果
			MSEND_COMM(0x16);      
			MRCV_DAT();
			reg_number1=ji_suan();
			//计算量程范围内的显示值
			ShowNum=(float)reg_number1/(float)reg_number;
			ShowNum=code_dhl*ShowNum+code_dl;
			
			//计算PWM输出4--20mA值
			PWM_value=(float)code_ehl/(float)code_dhl*ShowNum+code_el;
			EA=0;
			LPC932PWM();
			//判断有无设置小数点
			if(xsd_value>=1)
			{
				if(code_dh<1000)
				ShowNum*=10;
				if(ShowNum<3) ShowNum=0;
				if(xsd_value==1)      //控制小数点显示位
				write7281(0x18,0x17);
				if(xsd_value==2)
				write7281(0x18,0x0f);
				if(xsd_value==3)
				write7281(0x18,0x07);
			}
			
			//判断有无超过报警值,有则打开继电器开关和报警灯
			if(ShowNum>=baojing_bh)
			{
				//write7281(0x18,0x21); //点亮上限报警灯
				//write7281(0x18,0xa0); //关闭下限报警灯
				Dis_play(0x18,0x21,0xa0);
				P0_3=1;             //打开上限报警继电器
				P0_2=0;             //关闭下限报警继电器
			}
			if(ShowNum<=baojing_bl)
			{
				//write7281(0x18,0x21); //点亮下限报警灯
				//write7281(0x18,0xa0); //关闭上限报警灯
				Dis_play(0x18,0x20,0xa1);
				P0_2=1;             //打开下限报警继电器
				P0_3=0;             //关闭上限报警继电器
			}
	
			if(ShowNum>baojing_bl&&ShowNum<baojing_bh)
			{P0_2=0;P0_3=0;Dis_play(0x18,0xa0,0xa1);}

			//调用显示程序
			Display();
			EA=1;
			delay_long(200);

			//把采样到的数据分成高8位和低8位保存在E2PROM中60和61单元
			baocun[0]=(unsigned int)ShowNum/256;
			baocun[1]=(unsigned int)ShowNum%256;
		}
	}
}

//---------------------------------------//
//--------------初始化和复位-------------//
//---------------------------------------//

void init()
{
	P0M1=0x42;
	P0M2=0x42;
	P1M1=0xe4;
	P1M2=0xc4;
	P2M1=0x42;
	P2M2=0x02;
	IEN0=0x90;
}

//---------------------------------------//
// 名称: UART_INIT                       // 
// 功能: LPC932单片机的UART初始化,       //
//       波特率9600bit/s                 // 
// 注意 单片机采用7.373MHz晶振,          //        
//      波特率采用独立的波特率发生器提供 //
//---------------------------------------//

void UART_INIT()
{
	P0_7=1;
	SSTAT=0x20;   //双缓冲禁止,独立中断使能,采用查询方式接收 
	SCON=0x50;    //串口模式3,接收使能,使能多机通讯?
	BRGCON=0; 
	BRGR1=brgr1;  //波特率在7.373MHz 
	BRGR0=brgr0; 
	BRGCON=0x03;  //启动UART的波特率发生器
}

//---------------------------------------//
//看门狗初始化子程序                     // 
//注意初始化后启动看门狗                 // 
//---------------------------------------//

void init_wdt() 
{ 
	ACC=WDCON;    //读取WDT控制寄存器 
	ACC=ACC|0x04; //置位ACC.2准备启动WDT
	WDL=0x80;     //设置8位倒计时器初值 
	WDCON=ACC;    //启动WDT 
	WFEED1=0xA5;  //清零第一部分 
	WFEED2=0x5A;  //清零第二部分 
}
 
//---------------------------------------//
//喂狗子程序                             // 
//注意程序中开启中断                     // 
//---------------------------------------//

void clrwdt() 
{ 
	EA=0;          //关闭中断 
	WFEED1=0xA5;   //执行清零第一部分 
	WFEED2=0x5A;   //执行清零第二部分 
	EA=1;          //开中断 
}

//--------------计算校验码---------------//

void calccrc(unsigned char crcbuf) 
{ 
	unsigned char i,TT; 
	crc=crc ^ crcbuf; 
	for(i=0;i<8;i++) 
	{ 
		TT=crc&1; 
		crc=crc>>1; 
		crc=crc&0x7fff; 
		if (TT==1) 
		crc=crc^0xa001; 
		crc=crc&0xffff; 
	} 
}

//---------------------------------------//
//接收一个字节通讯函数                   // 
//原型:unsigned char Receive_Data();    //
//功能:接收一个字节通讯                 //
//入口参数:无                           //
//出口参数:返回接收值                   //
//---------------------------------------//

unsigned char Receive_Data() 
{
	unsigned char temp;
	while(RI==0);
	RI=0;
	temp=SBUF;
	return (temp);  //接收一个字节,并进行偶校验
}

//---------------------------------------//
//接收一帧通讯函数                       //
//原型:void Receive_One(uchar *);       //
//功能:接收一帧通讯                     //
//入口参数:接收存取地址指针             //
//出口参数:接收正确标志,1为接收正确    //
//---------------------------------------//

bit Receive_One(unsigned char *s) 
{ 
	unsigned char Serial_data,crch,crcl;
	unsigned int Serial_data0;
    crc=0xffff;
	read_E2PROM(0x43,0x01);
	*s=Serial_data=Receive_Data();        //接收地址
	if(*s!=chcode[0]) return 0;
	else
	{
		calccrc(*s);
 		*(s+1)=Receive_Data();  		  //接收功能码
		calccrc(*(s+1));
		*(s+2)=Receive_Data();  		  //接收起始地址字节
		calccrc(*(s+2));
		*(s+3)=Receive_Data();       	  //接收通讯数据长度字节
		calccrc(*(s+3));
		crch=Receive_Data();
		crcl=Receive_Data();
		Serial_data0=crch*256+crcl;
		if(crc!=Serial_data0)             //校验正确吗? 
		return 0;
		ESR=0;
		REN=0;
		return 1;
	}//一帧接收成功,关闭接收通讯,处理一帧完后再打开
}

//---------------------------------------//
//串口接收中断服务程序                   //
//功能:接收数据                         //
//---------------------------------------//

void RXD_Int(void) interrupt 4 
{ 
	bit a;
	a=Receive_One(Serial_buf);
	if(a)
	Serial_Command_Run(Serial_buf); //帧执行
	ESR=1;	
}

//---------------------------------------//
//串口发送一个字节                       //
//功能:发送一个字节数据                 //
//入口参数:发送数据                     //
//出口参数:无                           //
//---------------------------------------//

void Send_Data(unsigned char Serial_data) 
{ 
	TI=0; 
	SBUF=Serial_data; 
	while(!TI); 
	TI=0;    //发送一个字节,并进行偶校验 
}

//---------------------------------------//
//发送一帧数据函数                       //
//原型:void TXD_Int(unsigned char *);   //
//功能:发送一帧数据                     //
//入口参数:发送数据帧地址指针           //
//出口参数:无                           //
//---------------------------------------//

void TXD_Int(unsigned char *s) 
{ 
	unsigned char i,j;
	unsigned char crch,crcl; 
	P0_7=0;           //RS485通讯,切换为发送状态 
    crc=0xffff;
	Send_Data(*s);    //发送地址
 	calccrc(*s);
	Send_Data(*(s+1));//发送功能码
	calccrc(*(s+1));
	Send_Data(*(s+2));//发送起始地址字节
	calccrc(*(s+2));
	Send_Data(*(s+3));//发送数据长度字节
	calccrc(*(s+3));
	j=*(s+3);
	for(i=0;i<j;i++)  //发送j个数据 
	{
		Send_Data(*(s+i+4));
		calccrc(*(s+i+4));
	}
	Send_Data(xsd_value); //发送小数点位
	calccrc(xsd_value);
	crch=crc/256;
	crcl=crc%256;
	Send_Data(crch); //发送校验高字节
	Send_Data(crcl); //发送校验低字节
	P0_7=1;          //一帧发送完毕,恢复信道切换功能
    REN=1;
}

//------------------------------------------//
//通讯执行函数                              //
//原型:Serial_Command_Run(unsigned char *); // 
//功能:执行通讯命令                        //
//入口参数:帧地址                          // 
//出口参数:是否正确及是否完毕

⌨️ 快捷键说明

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