📄 comm_module.c
字号:
/*===========================================================================
* 2006年。三星仪表SOC芯片开发项目
*
*
* 文件名称:Comm_Module.c
* 文件标识:
* 摘 要: 1、红外与rs485共用uart口
2、通常在RS485口,红外接收RX低电平时引起INT0中断,通信口切换到红外通信(关闭INT0中断),
在一定时间后,自动切换到RS485(同时开INT0中断接收)。
3、红外与RS485切换是由(IR_CTRL=1 RS485_CTRL = 0)切换到红外,(IR_CTRL=1 RS485_CTRL = 0)切换到RS485
*
* 当前版本:Ver 1.0
* 作 者:罗冬生
* 修改内容:
* 修改日期:
* 完成日期:
===============================================================================================*/
#ifndef _Comm_Module_
#define _Comm_Module_
//===============================================================================================
#include "includes.h"
//-----------------------------------------------------------------------------------------
#define iD_err 0x02 //数据标识错误
#define Password_err 0x04 //密码错误
#define Data_err 0x01 //非法数据
#define SysData_err 0x07 //系统数据错误
//-----------------------------------------------------------------------------------------
void Read_Response(void);
void Write_Response(void); //"04"写命令处理
void DL645_Command(void);
void DL645_DataSend(void);
//===============================================================================================
unsigned char RxTxBuf[RxTxLenMax]; //收发数据缓冲区
__idata unsigned char RxTxFlg; //通信状态标志,0=空闲,1=正在接收,2=已接收完一帧数据,3=正在发送
__idata unsigned char RxTxLen; //收发数据长度
unsigned char *RxTxAdr; //收发数据地址指针
// Comm_Time; // 通信接收与发送之间延时:nn(MS)*10
// CommByte_Time; // 通信字节之间延时:nn(ms)*10
//===============================================================================================
// 串行通信端口初始化 ,默认通信端口为RS485
void UartInit(void)
{
EPCFG_bit.MODE38_TxD = 0; //38KHz不输出到发送端口
IR_CTRL =0; // 红外通信不使能, 即关闭红外
RS485_CTRL = 1; // RS585通信使能控制,使能RS485
IE_bit.ES = 0; //关闭UART收发中断
//RxTxAdr = RxTxBuf; //置接收指针
RxTxFlg = 0; //标志清零,处于接收状态
SCON = 0xD0; //MODE3通信模式,接收使能。11010000B: SM0 SM1 SM2 REN TB8 RB8 TI RI
SBAUDT = 0x07; //波特率参数:DIV+SBTH = 7,DC = 0
SBAUDF = 0xAB; //使能uart内部时钟(0x80)作波特率发生器,SBAUDF =43=0x2B(不使用定时器1作波特率发生器)
IE_bit.ES = 1; //使能UART收发中断
TCON_bit.IT0 = 1; //外部输入(0为边沿触发)控制红外与RS485之间的切换
TCON_bit.IE0 =0; // 1; //外部输入0中断使能
// INTPR =1;
}
//===============================================================================================
// 外部中断0的中断程序
#pragma vector=0x03
__interrupt void INT0_ISR(void)
{
CommHWDelyTime = 250; //设置2s钟
RS485_CTRL =0; // 开通RS585通信 ,关闭
IR_CTRL =1; //关闭红外通信 ,使能控制
TCON_bit.IE0 = 0; // 关闭外部输入0中断使能
}
/*=====================================================================================================
串口通信中断程序
* 函数名称:UART_ISR
*
* 摘 要: 接收和发送中断处理程序
*
* 当前版本:Ver 1.0
* 作 者:罗冬生
* 修改内容:
* 修改日期:
* 完成日期:
======================================================================================================*/
#pragma vector=0x23
__interrupt void UART_ISR(void)
{
unsigned char i;
//-----------------------------------------------------------------------------------------
if(SCON_bit.RI) //接收中断处理程序
{
i=SBUF;
SCON_bit.RI=0;
CommByte_Time = 8; //80ms(字节之间通信最大等待时间500ms)
G_LED ^= 1;
if (IR_CTRL)
CommHWDelyTime = 250; //2000ms(红外通信延时)
switch (RxTxFlg) //判断接收标志状态
{
case 0: //空闲状态
if (i==0x68)
{ //第一个68字符处理
RxTxFlg = 1;
RxTxBuf[0] =0x68;
RxTxLen =1;
}
break;
case 1: //正在接收状态
if (RxTxLen >= RxTxLenMax) //接收长度判断?
RxTxFlg=0; //超出接收缓冲区清接收标志。
else
{
RxTxBuf[RxTxLen] =SBUF; //保存接收数据
RxTxLen++; //修改计数值
if (RxTxLen==8)
{
if (i!=0x68) // 第二个68判断
RxTxFlg=0; // 接收错误
}
else if (RxTxLen>=12) // 长度单元接收数据判断处理
{
if (RxTxLen == RxTxBuf[9]+12 )
{
if (i==0x16) //最后一个接收字符是否是"16"判断?
RxTxFlg=2; //接收正确,置一帧接收标志
else
RxTxFlg=0; //接收字符超过应接收长度
}
else if (RxTxLen > RxTxBuf[9]+12 )
{
RxTxFlg=0; //接收字符超过应接收长度
}
}
}
break;
case 2:
break; //已有一帧数据待处理
case 3:
break; //正在发送数据
default :
RxTxFlg=0; //非正确数据,复位标志
}
}
//-----------------------------------------------------------------------------------------
if (SCON_bit.TI) // 发送中断服务程序
{
SCON_bit.TI = 0; //清发送中断
if ((RxTxLen) && (RxTxFlg==3))
{
CommByte_Time =8; //80ms(发送一个字节最大等待时间80ms)
SendByte(*RxTxAdr); //发送一个字节
RxTxAdr++;
RxTxLen--;
if (IR_CTRL) //是否为红外通信?
{
CommHWDelyTime = 250;
}
}
else if (RxTxFlg==3)
{
SCON_bit.RI=0;
SCON_bit.REN = 1; //开接收
EPCFG_bit.MODE38_TxD = 0; //关闭38KHz输出到发送端口
RxTxFlg = 0 ;
}
}
}
/*=====================================================================================================
* 函数名称:CommModule_645
*
* 摘 要: 国标645通信处理程序 ,中断接收到一帧完整数据后进行处理
*
* 当前版本:Ver 1.0
* 作 者:罗冬生
* 修改内容:
* 修改日期:
* 完成日期:
======================================================================================================*/
void CommModule(void)
{
if (Key_Prog) //编程按键测试
Key = 0;
else
{
LcdBuffer[11] |= 0x08; //显示按键符号
LcdUpData(); //刷新显示
DelayMs(5);
if (!Key_Prog)
{
Key_Flg = 1; //置编程允许标志
Key_Time = KeyMaxTime; //编程开关有效时间
}
}
switch (RxTxFlg)
{
case 1:
if (!CommByte_Time)
RxTxFlg = 0; //接收超时,清标志
break;
case 2: //有一帧通信命令要处理
DL645_Command(); // DL/T 645命令处理
if (RxTxFlg !=3)
RxTxFlg = 0; //没有数据发送清标志
break;
case 3:
if (!CommByte_Time)
UartInit (); //在设定的时间内没有发送完毕,初始化UART串口
break;
default:
Comm_Flg=0 ;
}
}
//--------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -