📄 zl932.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 + -