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

📄 pa888_24.c

📁 电表程序:三路显示
💻 C
字号:
//三显示,通讯,三PWM功能,无报警

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

#define mima_code1 2005
#define mima_code2 1999
#define mima_code3 2006
#define led_xsdA 0x50
#define led_xsdB 0x70
#define led_xsdC 0x30
#define ledpreA  0x80
#define ledpreB  0xc0
#define ledpreC  0x40

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

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

sbit P0_7      =  P0^7;
sbit CLK_7281  =  P1^2;
sbit DAT_7281  =  P0^1;
sbit KEY_7281  =  P2^6;

sbit CS1_5460  =  P0^5;
sbit CS2_5460  =  P0^4;
sbit RES_5460  =  P0^6;
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 i);      //短延时
void delay_long(unsigned char i); //长延时
void key_deal();
void key_seting();
void key_shifting();
void key_incing();
void key_exiting();

void Display(unsigned char xsd_value,unsigned char ledpre);
void xsd_fun(unsigned int L,unsigned char X,unsigned char ledxsd);
void transmit();
void zhuanhuan();
void clrwdt();
void init_wdt();

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 init_and_res();
void UART_INIT();
void take_E2PROM();
void SET_SPI();
void LPC932_PWM();
void LPC932PWM();

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);
//unsigned int JISUAN(void);
long ji_suan(void);
void baocun();

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

unsigned int liangchengAH,liangchengAL;
unsigned int liangchengBH,liangchengBL;
unsigned int liangchengCH,liangchengCL;
unsigned int liangchengAHL,liangchengBHL,liangchengCHL;
unsigned int biansongAH,biansongAL;
unsigned int biansongBH,biansongBL;
unsigned int biansongCH,biansongCL;
unsigned int biansongAHL,biansongBHL,biansongCHL;
unsigned char resloveA[2],resloveB[2],resloveC[2];
unsigned char led_code[4],chcode[4];
unsigned char led_number;
unsigned char led_preB[]={0xc0,0xd0,0xe0,0xf0};   //定义显示数码管的位
unsigned char led_flash[4]={0xef,0xdf,0xbf,0x7f}; //定义闪烁寄存器
unsigned char keymark;
unsigned char key_value;
long xdata reg_numberA,reg_numberB,reg_numberC;
long xdata read_A,read_B,read_C;
float ShowNum;
unsigned int crc;
unsigned int PWM_value;
unsigned char pwmH,pwmL;
unsigned int conn;
unsigned char xsd_valueA;//小数点的值,0为不设小数点,1为小数点在左起第3个数码管
                         //2为小数点在左起第2个数码管,3为小数点在左起第1个数码管
unsigned char xsd_valueB;
unsigned char xsd_valueC;
unsigned char brgr1,brgr0;

bit shift_flag;    //移位键使能标志
bit inc_flag;      //加1键使能标志
bit mima_flag1;
bit mima_flag2;
bit mima_flag3;
bit Display_flag;  //显示标志
bit xsd_flag;
bit addr_flag;
bit baud_flag;
bit set_flag;
bit PWMA_flag;
bit PWMB_flag;
bit PWMC_flag;

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

void main()
{
   	init_and_res();
	init_wdt();
	SET_SPI();
	take_E2PROM();
	LPC932_PWM();
	MSEND_COMM(0x4a);              //写周期计数寄存器1000
	MSEND_DAT(0x00,0x03,0xe8);
	write7281(0x12,0x88);          //7281写控制字
	MSEND_COMM(0xe8);
	Display_flag=1;
	while(1)
	{
		if(KEY_7281==0)
		key_deal();
		clrwdt();
		if(Display_flag)
		{
			CS1_5460=0;
			CS2_5460=1;
			MSEND_COMM(0x16);      
			MRCV_DAT();
			read_A=ji_suan();
			//计算A相量程范围内的显示值
			ShowNum=(float)read_A/(float)reg_numberA;
			ShowNum=liangchengAHL*ShowNum+liangchengAL;
			PWM_value=(float)biansongAHL/(float)liangchengAHL*ShowNum+biansongAL;
			LPC932PWM();
			//判断有无设置小数点
			EA=0;
			OCRBH=pwmH;
			OCRBL=pwmL;
			TCR21|=0x80;
			xsd_fun(liangchengAH,xsd_valueA,led_xsdA);
			if(ShowNum<10) ShowNum=0;
			Display(xsd_valueA,ledpreA);
			EA=1;
			delay_long(200);

			//把采样到的A相数据分成高8位和低8位保存在E2PROM中3b开始的4单元
			baocun();
			resloveA[0]=chcode[0];
			resloveA[1]=chcode[1];

			MSEND_COMM(0x18);      
			MRCV_DAT();
			read_B=ji_suan();
			//计算B相量程范围内的显示值
			ShowNum=(float)read_B/(float)reg_numberB;
			ShowNum=liangchengBHL*ShowNum+liangchengBL;
			PWM_value=(float)biansongBHL/(float)liangchengBHL*ShowNum+biansongBL;
			LPC932PWM();
			//判断有无设置小数点
			EA=0;
			OCRCH=pwmH;
			OCRCL=pwmL;
			TCR21|=0x80;
			xsd_fun(liangchengBH,xsd_valueB,led_xsdB);
			if(ShowNum<10) ShowNum=0;
			Display(xsd_valueB,ledpreB);
			EA=1;
			delay_long(200);

			//把采样到的B相数据分成高8位和低8位保存在E2PROM中3f开始的4单元
			baocun();
			resloveB[0]=chcode[0];
			resloveB[1]=chcode[1];

			CS1_5460=1;
			CS2_5460=0;
			MSEND_COMM(0x16);      
			MRCV_DAT();
			read_C=ji_suan();
			//计算C相量程范围内的显示值
			ShowNum=(float)read_C/(float)reg_numberC;
			ShowNum=liangchengCHL*ShowNum+liangchengCL;
			PWM_value=(float)biansongCHL/(float)liangchengCHL*ShowNum+biansongCL;
			LPC932PWM();
			//判断有无设置小数点
			EA=0;
			OCRDH=pwmH;
			OCRDL=pwmL;
			TCR21|=0x80;
			xsd_fun(liangchengCH,xsd_valueC,led_xsdC);
			if(ShowNum<10) ShowNum=0;
			Display(xsd_valueC,ledpreC);
			EA=1;
			delay_long(200);

			//把采样到的C相数据分成高8位和低8位保存在E2PROM中43开始的4单元
			baocun();
			resloveC[0]=chcode[0];
			resloveC[1]=chcode[1];
		}
	}
}

void baocun()
{
	chcode[0]=(unsigned int)ShowNum/256;
	chcode[1]=(unsigned int)ShowNum%256;
}

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

void init_and_res()
{
	P0M1=0x42;
	P0M2=0x72;//0x42
	P1M1=0xe4;
	P1M2=0xc4;
	P2M1=0x42;
	P2M2=0x42;
	IEN0=0x90;
}

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

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;          //开中断 
}

//---------------------------------------//
// 名称: 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 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;
	//RI=0;
	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(0x1b,0x01);
	*s=Serial_data=Receive_Data();        //接收地址
	calccrc(*s);
	if(*s!=chcode[0]) return 0;
	else
	{		
 		*(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));
	}
	if(*(s+2)==0x60)
	{Send_Data(xsd_valueA); //发送小数点位
	calccrc(xsd_valueA);
	crch=crc/256;
	crcl=crc%256;
	Send_Data(crch); //发送校验高字节
	Send_Data(crcl); //发送校验低字节
	P0_7=1;          //一帧发送完毕,恢复信道切换功能
    REN=1;
	return;}
	if(*(s+2)==0x62)
	{Send_Data(xsd_valueB); //发送小数点位
	calccrc(xsd_valueB);
	crch=crc/256;
	crcl=crc%256;
	Send_Data(crch); //发送校验高字节
	Send_Data(crcl); //发送校验低字节
	P0_7=1;          //一帧发送完毕,恢复信道切换功能
    REN=1;
	return;}
	if(*(s+2)==0x64)
	{Send_Data(xsd_valueC); //发送小数点位
	calccrc(xsd_valueC);
	crch=crc/256;
	crcl=crc%256;
	Send_Data(crch); //发送校验高字节
	Send_Data(crcl); //发送校验低字节
	P0_7=1;          //一帧发送完毕,恢复信道切换功能
    REN=1;
	return;}
}

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

⌨️ 快捷键说明

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