📄 comm._c
字号:
/*******************************************************
/*ICC-AVR application builder : 2004-3-11 12:02:11
// Target : atMega16
// Crystal: 8.0000Mhz
通讯模块 单工双向485接口
******************************************************/
#include <string.h>
#include <iom32v.h>
#include <math.h>
#include <stdlib.h>
#include <macros.h>
#include <eeprom.h>
#include "eeprom_l.h"
#include "comm.h"
#include "main.h"
#include "delay.h"
#include "key.h"
#pragma data:data
unsigned char state2;
//state2.0 disable_data //1:输入数据无效,0有效;
//state2.1 remote //1:遥控输入有效,0:本地输入有效
//state2.7 p99 //P99指令使能
unsigned char state1;
//state1.2 PE
//state1.3 DOR
//state1.4 FE
//state1.5
//state1.6
unsigned char pump_tab; //机器号
extern unsigned int speed;
extern unsigned char state_other;
extern unsigned char state0;
extern unsigned char key;
extern unsigned char in_out_number;
extern unsigned char state;
//state0.5接收消息有效标志
/* 通信变量定义 */
char txd_frm[15]; //物理层发送缓冲区
char txd_frm_len; //物理层发送数据长度
char rxd_frm[15]; //物理层接收缓冲区
char rxd_frm_len; //物理层接收数据长度
char tx485_busy; //485发送工作判忙
char txd_cnt; //发送数据计数器
char rxd_cnt; //接收数据计数器
char rxd_ins_flag; //一帧接收数据中有E8或E9标志
char txd_ins_flag; //一帧发送数据中有E8或E9标志
char txd_ins_data; //发送数据
char rxd_data; //接收数据
char mac_txd_th; //发送状态 0发送完毕,1发送帧头,2发送中间数据
char rxd_h_ok; //接收开始标志
char fcs1; //异或校验
char rxd_mesg_addr; //接收地址
char rxd_mesg_len; //应用层接收数据长度
char rxd_mesg[15]; //应用层接收数据缓冲区
char txd_mesg_addr; //发送地址
char txd_mesg_len; //应用层发送数据长度
char txd_mesg[15]; //应用层发送数据缓冲区
/*********任务管理*************/
char pri[16];
char act[16]; //任务寄存器
char rxd_llc_job; //物理层收任务寄存器
char txd_llc_job; //物理层发任务寄存器
char rs485_app_job; //应用层任务寄存器
char att_n_max;
extern struct cal
{
unsigned int test_time;
unsigned long int dispvol;
unsigned long int test_dispvol;
float dispk;
unsigned long int run_time;
};
extern struct cal cal0;
/*****************************************************************
功能: serial_int
描述: 运行串行口 FSAs.
参数: 无.
返回无.
影响无.
*****************************************************************/
#pragma interrupt_handler serialri_int:iv_USART_RX
#pragma interrupt_handler serialti_int:iv_USART_TX
/* 通信物理层发送中断程序模块 */
void serialti_int(void)
{
char i;
UCSRA=RS485_UCSRA|0b01000000; /*清发送完中断标志位*/
if(mac_txd_th==1)
{ UDR=0xe9;
txd_cnt=0;
txd_ins_flag=0;
tx485_busy=1;
mac_txd_th=2;
}
else
{ if(mac_txd_th==2)
{ if(txd_ins_flag==1)
{ txd_ins_flag=0;
UDR=txd_ins_data;
}
else
{ if(txd_cnt<=(txd_frm_len-1))
{ if(txd_frm[txd_cnt]==0xe8||txd_frm[txd_cnt]==0xe9)
{ txd_ins_flag=1;
txd_ins_data=txd_frm[txd_cnt]-0xe8;
UDR=0xe8;
}
else
{ UDR=txd_frm[txd_cnt];}
txd_cnt=txd_cnt+1;
}
else
{ tx485_busy=0;
mac_txd_th=0;
PORTC&=~(1<<DE_485);
}
}
}
else
{ tx485_busy=0;
mac_txd_th=0;
PORTC&=~(1<<DE_485);
}
}
}
/* 通信物理层接收中断程序模块 */
void serialri_int(void)
{
char i;
UCSRA=RS485_UCSRA&0b00111111; /*清接收完中断标志位*/
rxd_data=UDR;
if(tx485_busy!=1)
{ if(rxd_data==0xe9)
{ rxd_h_ok=1;
rxd_cnt=0;
rxd_ins_flag=0;
rxd_frm_len=0;
fcs1=0;
}
else
{ if(rxd_h_ok==1)
{ if(rxd_data==0xe8)
{ rxd_frm[rxd_cnt]=0xe8;
rxd_ins_flag=1;
}
else
{ if(rxd_ins_flag==1)
{ rxd_ins_flag=0;
rxd_frm[rxd_cnt]=rxd_frm[rxd_cnt]+rxd_data;
}
else
{ rxd_frm[rxd_cnt]=rxd_data;}
fcs1=fcs1^rxd_frm[rxd_cnt];
if(rxd_cnt==1)
{ rxd_frm_len=rxd_frm[rxd_cnt]+3;}
rxd_cnt=rxd_cnt+1;
if((rxd_cnt>1)&&(rxd_cnt>=rxd_frm_len))
{ if(fcs1==0)
{
act[rxd_llc_job]=1;
}
}
}
}
}
}
}
/*********************************/
void rxd_llc_job1(void)
{
char i;
act[rxd_llc_job]=0;
if((pump_tab==rxd_frm[0])||(rxd_frm[0]==BROADCAST_ADDR)) //接收指令地址等于设备或广播地址
{ rxd_mesg_addr=rxd_frm[0];
rxd_mesg_len=rxd_frm[1];
for(i=0;i<rxd_mesg_len;i++)
{ rxd_mesg[i]=rxd_frm[i+2];}
act[rs485_app_job]=1;
}
}
/*********************************/
void txd_llc_job1(void)
{
char i,fcs;
act[txd_llc_job]=0;
txd_frm[0]=txd_mesg_addr;
txd_frm[1]=txd_mesg_len;
fcs=txd_frm[0]^txd_frm[1];
for(i=0;i<txd_mesg_len;i++)
{ txd_frm[i+2]=txd_mesg[i];
fcs=fcs^txd_frm[i+2];
}
txd_frm_len=txd_mesg_len+3;
txd_frm[txd_frm_len-1]=fcs;
txd_cnt=0;
txd_ins_flag=0;
tx485_busy=1;
mac_txd_th=2;
PORTC|=(1<<DE_485);
UDR=0xe9;
}
/*********************************/
void rs485_app_job1(void)
{
char i,fcs;
unsigned int temp;
unsigned long int flow_temp;
unsigned long int rxd_mesg_temp;
act[rs485_app_job]=0;
if((rxd_mesg_addr!=BROADCAST_ADDR)&&(rxd_mesg[0]=='R')&&(rxd_mesg[1]=='I')&&(rxd_mesg[2]=='D')) /* 读取设备地址命令e9 01 03 52 49 44 5d */
{ txd_mesg_addr=pump_tab;
txd_mesg_len=3;
txd_mesg[0]='R';
txd_mesg[1]='I';
txd_mesg[2]='D';
act[txd_llc_job]=1;
goto rs485_app_ret;
}
if((rxd_mesg[0]=='W')&&(rxd_mesg[1]=='I')&&(rxd_mesg[2]=='D')) /* 设置设备地址命令e9 1f 04 57 49 44 01 40 */
{ pump_tab=rxd_mesg[3];
do {temp=EEPROMwrite(pump_tab_romaddr,pump_tab);}
while(temp>0);
if(rxd_mesg_addr!=BROADCAST_ADDR)
{ txd_mesg_addr=pump_tab;
txd_mesg_len=3;
txd_mesg[0]='W';
txd_mesg[1]='I';
txd_mesg[2]='D';
act[txd_llc_job]=1;
}
goto rs485_app_ret;
}
if((rxd_mesg_addr!=BROADCAST_ADDR)&&(rxd_mesg[0]=='R')&&(rxd_mesg[1]=='J')) // 读取运行参数命令e9 01 2 52 47 16
{ //if(in_out_number<2)
//{
txd_mesg_addr=pump_tab;
txd_mesg_len=6;
txd_mesg[0]='R';
txd_mesg[1]='J';
txd_mesg[2]=(speed>>8);
txd_mesg[3]=speed;
txd_mesg[4]=0;
if (state&(1<<RUN_STOP))
{txd_mesg[4]|=0b00000001;}
else
{txd_mesg[4]&=0b11111110;}
txd_mesg[5]=0;
if (state&(1<<CW_CCW))
{txd_mesg[5]&=0b11111110;}
else
{txd_mesg[5]|=0b00000001;}
act[txd_llc_job]=1;
//}
//else
//{ act[rs485_app_job]=1;}
goto rs485_app_ret;
}
if((rxd_mesg[0]=='W')&&(rxd_mesg[1]=='J')) // 设置运行参数命令
{ if(in_out_number<2) //内控控制
{ //delay_cortrol_job();
all_stop();//停止所有运行
rxd_mesg_temp=rxd_mesg[2];//必须如此,rxd_mesg[4]进行常整运算时有错
speed=rxd_mesg_temp*256+rxd_mesg[3];
if ((speed==0)||(speed>600))
{speed=1;}
cal_timer1(speed);
EEPROMWriteWord(speed_romaddr,&speed);
if (rxd_mesg[4]&0b00000001)
{state|=(1<<RUN_STOP);}
else
{state&=~(1<<RUN_STOP);}
if (rxd_mesg[5]&0b00000001)
{state&=~(1<<CW_CCW);}
else
{state|=(1<<CW_CCW);}
do {temp=EEPROMwrite(state_romaddr,state);}
while(temp>0);
state_init();
if(rxd_mesg_addr!=BROADCAST_ADDR)
{ txd_mesg_addr=pump_tab;
txd_mesg_len=2;
txd_mesg[0]='W';
txd_mesg[1]='J';
act[txd_llc_job]=1;
}
}
goto rs485_app_ret;
}
rs485_app_ret:;
}
/*********************************/
/* 主调度任务程序模块 */
void job_att(char step)
{
char i,crrt_jn;
if(step==0)
{ for(i=1;i<=31;i++)
{ pri[i]=0;
act[i]=0;
}
rxd_llc_job=9;
pri[rxd_llc_job]=95;
txd_llc_job=10;
pri[txd_llc_job]=94;
rs485_app_job=11;
pri[rs485_app_job]=93;
att_n_max=12;
}
else
{ crrt_jn=0;
for(i=1;i<=att_n_max;i++)
{ if((act[i]!=0)&&(pri[i]>pri[crrt_jn]))
{ crrt_jn=i;}
}
switch (crrt_jn)
{
case 9: rxd_llc_job1();
break;
case 10: txd_llc_job1();
break;
case 11: rs485_app_job1();
break;
case 12: break;
}
}
}
/*
串口初始化
*/
void serial_init (void)
{
UBRRH=RS485_BAUDH;
UBRRL=RS485_BAUDL;
UCSRA=RS485_UCSRA;
UCSRC=RS485_UCSRC;
UCSRB=RS485_UCSRB;
UCSRB=UCSRB|0b00011000; /* 允许接收、发送 */
state1=0;
DDRC|=(1<<DE_485);
PORTC&=~(1<<DE_485);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -