📄 源程序0.c
字号:
#include "sjaregb1.h.h"
#include "intrins.h"
#include "ctype.h"
#include "string.h"
#include <AT898252.h>
#include <absacc.h>
#define TURE 1
#define FALSE 0
/*数据类型定义*/
#define uchar unsigned char
#define ulong unsigned long
#define uint unsigned int
/*指示告警输出,根据各自的标志位进行相与输出以控制指示灯或蜂鸣器*/
#define LADD XBYE[0xbuff]
#define led1 0xfe /*压仪表1的指示灯,若亮要压,不亮则不压*/
#define led2 0xfd
#define led3 0xfb
#define led4 0xf7
#define ledready 0xdf
#define ledover 0xbf
#define beepon 0x7f
#define beepoff 0x80
/*CAN接点地址定义*/
#define ID 0xa0 /*本节点ID(识别号)*/
#define TOID 0xa1 /*目标节点ID*/
/*按键键值定义*/
#define YB1 0X01 /*压仪表1键*/
#define YB2 0X0A /*压仪表2键*/
#define YB3 0X0F /*压仪表3键*/
#define YB4 0X10 /*压仪表4键*/
#define NUM0 0X11 /*数字键0*/
#define NUM1 0X0E /*数字键1*/
#define NUM2 0X0D /*数字键2*/
#define NUM3 0X0C /*数字键3*/
#define NUM4 0X09 /*数字键4*/
#define NUM5 0X08 /*数字键5*/
#define NUM6 0X07 /*数字键6*/
#define NUM7 0X02 /*数字键7*/
#define NUM8 0X03 /*数字键8*/
#define NUM9 0X04 /*数字键9*/
#define FUNC OXO5 /*功能键*/
#define PARA 0X14 /*参数键*/
#define ENTER 0X06 /*确认键*/
#define CLS 0X0B /*清除键*/
#define UNVAL OXFF /*无效键*/
/************************************
液晶显示模块接口定义
*************************************/
/*液晶模块接口地址定义*/
#define LCDCOM_R XBYTE[0X7F01]
#define LCDCOM_W XBYTE[0X7F00]
#define LCDDATA_R XBYTE[0X7F03]
#define LCDDATA_W XBYTE[0X7F02]
/*液晶忙标志位*/
sbit BF=ACC^7;
/*变量及缓冲区定义*/
static uchar data canbuf[13]; /*CAN接收数据缓冲区*/
static uchar data cantxbuf[13]; /*CAN发送数据缓冲区*/
uchar buf_rom[8] ; /*仪表压力值显示缓冲区*/
uchar ADH_1; /*A/D转换结果存储高字节,1通道*/
uchar ADH_1; /*A/D转换结果存储低字节,1通道*/
uchar ADH_2; /*A/D转换结果存储高字节,2通道*/
uchar ADH_2; /*A/D转换结果存储低字节,2通道*/
uchar cursorxy; /*光标位置*/
/**********************************************
标志定义
**********************************************/
/*标志定义*/
uchar bdata flag1,flag2; /*标志字节1,2*/
sbit recok = flag1^0; /*成功接收报文标志*/
sbit huisong = flag1^1; /*报文是否不要回送标志*/
sbit f_no1 = flag1^2; /*发送到NO1标志*/
sbit f_no2 = flag1^3; /*发送到NO2标志*/
sbit f_no3 = flag1^4; /*广播标志*/
sbit ch_flag = flag1^5; /*通道号标志,等于0为通道1,等于1为通道2*/
sbit f_qd = flag1^6; /*是否处于启动工作状态*/
sbit modified = flag1^7; /*参数被编辑修改标志(决定是否写入EEPROM)*/
sbit f_yb1 = flag2^0; /*压仪表1的标志,等于1要压,等于0则不压*/
sbit f_yb2 = flag2^1; /*压仪表2的标志,等于1要压,等于0则不压*/
sbit f_yb3 = flag2^2; /*压仪表3的标志,等于1要压,等于0则不压*/
sbit f_yb4 = flag2^3; /*压仪表4的标志,等于1要压,等于0则不压*/
sbit f_ready = flag2^5; /*系统可以工作(准备好)指示灯标志*/
sbit f_over = flag2^6; /*过压或欠压标志(过压还是欠压由液晶显示)*/
/*(0标志正常,1表示过压,2表示欠压)*/
sbit f_beep = flag2^7; /*是否要蜂鸣器报警的标志*/
/***********************************
输入/输出引脚定义
***********************************/
/*AD7705引脚的定义*/
sbit DIN7705 = P3^4; /*AD7705的数据输入端*/
sbit DOUT7705 = P3^4; /*AD7705的数据输出端*/
sbit CLK7705 = P3^5; /*AD7705的时钟输入*/
sbit AD7705_DRDY = P1^5; /*AD7705的状态线*/
/*按键引脚定义*/
sbit row1 = p1^1;
sbit row2 = p1^0;
sbit row3 = p1^3;
sbit row4 = p1^2;
sbit col1 = p3^2;
sbit col2 = p1^6;
sbit col3 = p1^7;
sbit col4 = p1^4;
sbit col5 = p1^5;
sbit qd1 = p3^4; /*带互锁的启动按钮*/
sbit dq2 = p3^5;
sbit tz = p3^0; /*停止按钮*/
/*************************************
函数说明
*************************************/
void init(void); /*系统初始化*/
void wait(void);
void delay(void);
void init_lcd(void);
void display(void);
void can_init(void);
void tdata_init(void);
void trdata_can(void);
void delay1ms(void);
void delay20ms(void);
void message(void);
void warnbeep(uchar wtype );
void cantransfer(void);
void readfromlcd(uchar itemid);
void writelcd(uchar dat);
void setcursor(uchar xy);
void keyhandle(void);
void canscan(void);
void disp_yl(uchar lcdaddr);
void tobcd(ulong m);
void displayeeprom(void);
uchar readbyte_eeprom(uint addr);
bit writebyte_eeprom(uint addr,uchar val);
void readeeprom(uchar xx);
/****************************************************************
主函数
(1)CAN发送采用非中断法,接收采用外中断1中断法,提高相应的实时性;
(2)系统主频为6MHZ ,SJA1000的晶阵为12MHZ
*****************************************************************/
void main(void)
{
uchar i,j,k,yl;
ulong bcdint; /*将16位压力数值转化为十进制数*/
for(k=0;k<10;k++)
for(i=0;i<225;i++)
for(j=0;j<225;j++); /*延时以等待系统外围电路复位完成*/
for(i=0;i<13;i++)
{
canbuf[i]=0; /*缓冲区清0*/
cantxbuf[i]=0;
}
sys_init(); /*系统初始化*/
can_init(); /*CAN控制器初始化*/
init_lcd();
display(); /*主显示*/
displayeeprom(); /*显示EEPROM中各仪表的上、下限参数*/
flag2=0;
message(); /*默认指示状态*/
mjx:keyhandle(); /*等待按键并进行处理,如果参数改变了则回存*/
wait();
LCDCOM_W =0x0c; /*非编辑关光标和闪烁*/
f_ready=1; /*转为工作状态*/
message(); /*指示灯电亮*/
f_qd=1;
recok=0; /*为下次接收做准备*/
while(f_qd)
{
if(recok)
{
recok=0;
if(huisong)
{
for(i=0;i<13;i++)
cantxbuf[i]=canbuf[i]; /*接收数据发送缓冲区以便回送*/
trdata_can(); /*如果接收到报文则回送*/
huisong=0; /*回送完成后清回送标志*/
}
/*工作中,则实时显示压力数据*/
bcdint=canbuf[6]*256+canbuf[7];
tobcd(bcdint); /*将其转换为非压缩BCD*/
switch(canbuf[5])
{
case 0xa1:
disp_yl(0x8e);
break;
case 0xa2:
disp_yl(0xce);
break;
case 0xa3:
disp_yl(0xa2);
break;
case 0xa4:
disp_yl(0xe2);
break;
case 0xa5: f_qd=0;
switch(canbuf[6])
{
case 0xaa: yl='0';
f_over=0;
break;
case 0xff: yl='1';
f_over=1;
break;
case 0x00: yl='2';
f_over=1;
break;
}
wait();
LCDCOM_W=0x93;
wait();
LCDDATA_W=yl;
switch(canbuf[7])
{
case 0xaa: yl='0';
f_over=0;
break;
case 0xff: yl='1';
f_over=1;
break;
case 0x00: yl='2';
f_over=1;
break;
wait();
LCDCOM_W=0xd3;
wait();
LCDDATA_W=yl;
switch(canbuf[8])
{
case 0xaa: yl='0';
f_over=0;
break;
case 0xff: yl='1';
f_over=1;
break;
case 0x00: yl='2';
f_over=1;
break;
}
wait();
LCDCOM_W=0xa7;
wait();
LCDDATA_W=yl;
switch(canbuf[9])
{
case 0xaa: yl='0';
f_over=0;
break;
case 0xff: yl='1';
f_over=1;
break;
case 0x00: yl='2';
f_over=1;
break;
}
wait();
LCDCOM_W=0xe7;
wait();
LCDDATA_W=yl;
break;
}
message();
if(f_over) warnbeep(3);
}
}
while(keyscan()==UNVAL); /*等待按键任意继续(以便看到结果后开始下一个循环)*/
for(i=0;i<4;i++)
buf_yl[i]=0;
disp_yl(0x8e);
disp_yl(0xce);
disp_yl(0xa2);
disp_yl(0xe2);
wait();
LCDCOM_W=0x93;
wait();
LCDDATA_W=' ';
wait();
LCDCOM_W=0x93;
wait();
LCDDATA_W=' ';
wait();
LCDCOM_W=0xd3;
wait();
LCDDATA_W=' ';
wait();
LCDCOM_W=0xa7;
wait();
LCDDATA_W=' ';
wait();
LCDCOM_W=0xe7;
wait();
LCDDATA_W=' ';
f_ready=0;
f_over=0;
message();
goto mjx;
}
/***********************************************
显示压力函数
显示数据在BUF_YL缓冲区中,为从高到低4位BCD码
***********************************************/
void disp_yl(uchar lcdaddr)
{
uchar i;
wait();
LCDCOM_W=lcdaddr;
for(i=0;i<4;i++)
{
wait();
LCDDATA_W=buf_yl[i]+0x30;
}
}
/********************************************************
将十进制树转换为4位非压缩BCD码存入压力显示缓冲区BUF_YL
为从高到低4位BCD码,(个位不要)
********************************************************/
void tobcd(ulong ttt)
{
uchar xxx;
xxx=ttt/10000;
buf_yl[0]=xxx;
ttt=ttt%10000;
xxx=ttt/1000;
buf_yl[1]=xxx;
ttt=ttt%1000;
xxx=ttt/100;
buf_yl[2]=xxx;
ttt=ttt%100;
xxx=ttt/10;
buf_yl[4]=xxx;
}
/********************************************************************************************
CAN初始化函数
(1) 采用PEILCAN模式;
(2) 波特率为50KBPS;
(3) 双滤波验收,前两个字节为目标接点的ID,后两个字节为自身节点的ID,广播报文的ID为0000;
(4) 帧格式为扩张帧
********************************************************************************************/
void can_init(void)
{
uchar i;
SJA_adr=MODE;
*SJA_adr=0x01;
while(!(*SJA_adr&0x01));
SJA_adr=CDR;
*SJA_adr=0x88;
SJA_adr=IER;
*SJA_adr=0x0d;
SJA_adr=AMR;
for(i=0;i<4;i++)
{
*(SJA_adr+i)=0x00;
}
SJA_adr=ACR;
*SJA_adr=0x00;
SJA_adr=ACR+1;
*SJA_adr=0x00;
SJA_adr=ACR+2;
*SJA_adr=0x00;
SJA_adr=ACR+3;
*SJA_adr=ID;
SJA_adr=BTR0;
*SJA_adr=0x07;
SJA_adr=BTR1;
*SJA_adr=0xFF;
SJA_adr=OCR;
*SJA_adr=0xaa;
SJA_adr=RBSA;
*SJA_adr=0x00;
SJA_adr=TXERR;
*SJA_adr=0x00;
SJA_adr=ECC;
i=*SJA_adr;
SJA_adr=MODE;
*SJA_adr=0x00;
}
/***************************************
CAN发送函数
**************************************/
void tdata_can(void)
{
uchar st,i,tt;
SJA_adr=SR;
do
{
st=*SJA_adr;
}
while(st&0x10);
do
{
while(st&0x10);
}
while(st&0x08);
do
{
st=*SJA_adr;
}
while(st&0x04);
SJA_adr=TXB;
*SJA_adr=tt=cantxbuf[0];
tt=tt&0x0f;
tt+=4;
for(i=1;i<=tt;i++)
{
*(SJA_adr+i)=cantxbuf[i];
}
SJA_adr=CMR;
*SJA_adr=0x01;
/*************************************************************
报文回送函数
向发送报文节点返回接收到的报文,以便发送节点确认并决定是否重发
**************************************************************/
void trdata_can(void)
{
cantxbuf[0]=0x88;
cantxbuf[1]=0;
cantxbuf[2]=TOID;
cantxbuf[3]=0;
cantxbuf[4]=ID;
cantxbuf[5]=0xAA;
tdata_can();
}
/***********************************************************
中断接收函数
采用外中断1,寄存器组为1
***********************************************************/
void rec_can(void) interrupt 2 using 1
{
uchar st,i;
SJA_adr=SR;
st=*SJA_adr;
st&=0xc3;
recok=0;
huisong=0;
if(st)
{
if(st&0x80)
{
SJA_adr=IR;
st=*SJA_adr;
SJA_adr=MODE;
*SJA_adr=0x00;
}
else
{
SJA_adr=IR;
st=*SJA_adr;
if(st&0x08)
{
SJA_adr=CMR;
*SJA_adr=0x0c;
}
else
{
if(st&0x01)
{
SJA_adr=RXB;
st=*SJA_adr;
canbuf[0]=st;
st&=0x0f;
st=st+4;
for(i=1;i<=st;i++)
{
canbuf[i]=*SJA_adr+i)
}
if(canbuf[5]==0x55)
huisong=0;
else
huisong=1;
recok=1;
SJA_adr=CMR;
*SJA_adr=0x04;
SJA_adr=ALC;
st=*SJA_adr;
SJA_adr=ECC;
st=*SJA_adr;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -