📄 comm.c
字号:
/****************************************************
* 功能描述: 定义串口模式设置数据结构 *
*---------------------------------------------------*/
#include "config.h"
#include "comm.h"
#include "register.h"
volatile uchar hex_tbl[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',};
volatile uchar uhex_tbl[] = { 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15,};
volatile uchar rbufc; // 0x02开始计数
volatile uchar rbufce; // 0x03开始计数
volatile uchar rsbuf[32]; // 接收数据用
volatile uchar rsdatac; // 接收数据数
volatile U16 relay; // M线圈值
volatile uchar relaysd; // 发送M线圈值
volatile uchar rsdata[32]; // 接收后数据存放用
volatile uchar flag_rss; // 0x02开始后正在接收
volatile uchar flag_rsdata; // 数据已接收完毕
extern U16 DREG[MAXDREG];
extern void SetY(U16 d);
extern void ClrY(U16 d);
/*------------------------------------------*/
/* Function : UART0_Ini */
/* Description: 串口0初始化 */
/*------------------------------------------*/
uchar UART0_Ini(U32 baud, UARTMODE set)
{
U32 bak;
if((0==baud)||(baud>11500)) return(0);
if((set.datab<5)||(set.datab>8))return(0);
if((0==set.stopb)||(set.stopb>2))return(0);
if(set.parity>2)return(0);
U0LCR = 0x80;
bak = (Fpclk>>4)/baud;
U0DLM = bak>>8;
U0DLL = bak&0xff;
bak = set.datab - 5;
if(2==set.stopb) bak |= 0x04;
if(0!=set.parity){
set.parity = set.parity-1;
bak |= 0x08;
bak |= set.parity<<4;
}
U0LCR = bak;
relaysd = 0;
return(1);
}
/*------------------------------------------*/
/* Function : IRQ_UART0 */
/* Description: 外部中断处理 */
/*------------------------------------------*/
void __irq IRQ_UART0(void)
{
uint32 bak;
uchar i, sbuf;
bak = VICIntEnable; // 备份当前VICIntEnable的值
VICIntEnClr = (1<<6);
VICVectAddr = 0x00; // 清除中断逻辑,以便VIC可以响应更高优先级IRQ中断
FIO0SET = RSLED;
if(0x04==(U0IIR&0x0f)){
sbuf = U0RBR;
if(rbufc > 31){ rbufc = 0; rbufce =0; flag_rss = 0; flag_rsdata = 0;}
if(sbuf == 0x02){ flag_rss = 1; rbufc = 0; rbufce = 0; }
else if(sbuf == 0x03) rbufce = 1;
if(flag_rss) rsbuf[rbufc] = sbuf ; rbufc++;
if(rbufce){
rbufce++;
if(rbufce >= 4){
for(i=0; i<rbufc; i++) rsdata[i] = rsbuf[i];
rsdatac = rbufc;
flag_rss = 0;
rbufce = 0;
flag_rsdata = 1;
rbufc = 0;
}
}
}
FIO0CLR = RSLED;
VICIntEnable = bak;
}
/*------------------------------------------*/
/* Function : UART0_UART0_SendByte */
/* Description: 串口0送一个字节数据 */
/*------------------------------------------*/
void UART0_SendByte(U8 dat)
{
U0THR = dat;
while((U0LSR&0x20)==0);
}
/*------------------------------------------*/
/* Function : UART0_ISendBuf */
/* Description: 串口0送一个字符串 */
/*------------------------------------------*/
void UART0_ISendBuf(U8 len)
{
U8 i;
for(i=0; i<len; i++) U0THR = rsbuf[i];
while((U0LSR&0x20)==0);
}
/*------------------------------------------*/
/* Function : SendRS */
/* Description: 串口接收后返回数据 */
/*------------------------------------------*/
void SendRS(void)
{
uchar i, error = 0x15;
uchar chsum = 0x00, chsum1, chsum2;
if(flag_rsdata){
if(rsdata[0] == 0x02 && rsdata[rsdatac-3]==0x03 && rsdatac > 7){
for(i=1; i<rsdatac-2; i++){
chsum += rsdata[i];
}
chsum1 = hex_tbl[chsum/16];
chsum2 = hex_tbl[chsum%16];
if(chsum1 == rsdata[rsdatac-2] && chsum2 == rsdata[rsdatac-1]) error = 0;
}
if(error==0){
switch(rsdata[1]){
case 0x30: if(rsdata[2] == 0x31) PC_read(); // read D register
else if(rsdata[2] == 0x30) PC_readM(); // read M register
break;
case 0x31: PC_write(); break; // write D register
case 0x37: PC_SETM(); break; // set M register
case 0x38: PC_RESETM(); break; // reset M register
// default : UART0_SendByte(0x15);
}
} else UART0_SendByte(error);
flag_rsdata = 0;
}
}
// 继电器输出
void PC_SETM(void)
{
if(rsdata[4]==0x30 && rsdata[5]==0x38){
if(uhex_tbl[rsdata[2]-'0'] == DREG[0]){
switch(uhex_tbl[rsdata[3]-'0']){
case 0 : relay |= 0x0001; break;
case 1 : relay |= 0x0002; break;
case 2 : relay |= 0x0004; break;
case 3 : relay |= 0x0008; break;
case 4 : relay |= 0x0010; break;
case 5 : relay |= 0x0020; break;
case 6 : relay |= 0x0040; break;
case 7 : relay |= 0x0080; break;
case 8 : relay |= 0x0100; break;
case 9 : relay |= 0x0200; break;
case 10 : relay |= 0x0400; break;
case 11 : relay |= 0x0800; break;
case 12 : relay |= 0x1000; break;
case 13 : relay |= 0x2000; break;
case 14 : relay |= 0x4000; break;
case 15 : relay |= 0x8000; break;
}
UART0_SendByte(0x06);
}
}
}
// 继电器复位
void PC_RESETM(void)
{
if(rsdata[4]==0x30 && rsdata[5]==0x38){
if(uhex_tbl[rsdata[2]-'0'] == DREG[0]){
switch(uhex_tbl[rsdata[3]-'0']){
case 0 : relay &= 0xfffe; break;
case 1 : relay &= 0xfffd; break;
case 2 : relay &= 0xfffb; break;
case 3 : relay &= 0xfff7; break;
case 4 : relay &= 0xffef; break;
case 5 : relay &= 0xffdf; break;
case 6 : relay &= 0xffbf; break;
case 7 : relay &= 0xff7f; break;
case 8 : relay &= 0xfeff; break;
case 9 : relay &= 0xfdff; break;
case 10 : relay &= 0xfbff; break;
case 11 : relay &= 0xf7ff; break;
case 12 : relay &= 0xefff; break;
case 13 : relay &= 0xdfff; break;
case 14 : relay &= 0xbfff; break;
case 15 : relay &= 0x7fff; break;
}
UART0_SendByte(0x06);
}
}
}
// 接收后发送数据D0-D48
void PC_read(void)
{
uint add;
void *p;
uchar sbyte;
uchar i, rbyte, sbyteC, chsum;
add = (uhex_tbl[rsdata[2]-'0'])*0x1000 + ((uhex_tbl[rsdata[3]-'0'])*0x100 + (uhex_tbl[rsdata[4]-'0'])*0x10 + (uhex_tbl[rsdata[5]-'0']))/2-0x1000;
rbyte = (uhex_tbl[rsdata[6]-'0'])*0x10 + (uhex_tbl[rsdata[7]-'0']);
if(rbyte < 0x20){
if(add/MAXDREG == DREG[0] && add%MAXDREG < MAXDREG){
add = add%MAXDREG;
UART0_SendByte(0x02);
chsum = 0;
p = (uint16 *)&DREG[0];
for(i=0; i<rbyte; i=i+2){
sbyte = *((unsigned char *)p + add*2);
sbyteC = hex_tbl[sbyte/16]; chsum += sbyteC; UART0_SendByte(sbyteC);
sbyteC = hex_tbl[sbyte%16]; chsum += sbyteC; UART0_SendByte(sbyteC);
sbyte = *((unsigned char *)p + add*2 + 1);
sbyteC = hex_tbl[sbyte/16]; chsum += sbyteC; UART0_SendByte(sbyteC);
sbyteC = hex_tbl[sbyte%16]; chsum += sbyteC; UART0_SendByte(sbyteC);
add++;
}
UART0_SendByte(0x03);
chsum += 0x03;
UART0_SendByte(hex_tbl[chsum/16]);
UART0_SendByte(hex_tbl[chsum%16]);
}
}
}
// 接收数据D0-D48
void PC_write(void)
{
uint add;
uint16 *p;
uchar i, rbyte, c;
// uchar ibuf;
add = (uhex_tbl[rsdata[2]-'0'])*0x1000 + ((uhex_tbl[rsdata[3]-'0'])*0x100 + (uhex_tbl[rsdata[4]-'0'])*0x10 + (uhex_tbl[rsdata[5]-'0']))/2-0x1000;
rbyte = (uhex_tbl[rsdata[6]-'0'])*0x10 + (uhex_tbl[rsdata[7]-'0']);
if(rbyte < 0x20){
if(add/MAXDREG == DREG[0] && add%MAXDREG < MAXDREG){
add = add%MAXDREG;
p = (uint16 *)&DREG[0];
i = 0;
c = rbyte*2;
while(i<c){
*(p+add) = (((uhex_tbl[rsdata[i+10]-'0'])*16 + uhex_tbl[rsdata[i+11]-'0'])*16 +
uhex_tbl[rsdata[i+8]-'0'])*16 + uhex_tbl[rsdata[i+9]-'0'];
i = i+4;
// FM_WByte(add*2, U8 dat)
FM_WriteSeq(add*2, ((U8 *)&DREG[0])+add*2, 2);
// FM_WriteSeq(add, (U8 *)(p+add), 2);
// ibuf = reepromint(add*2);
// if(ibuf != *(p+add)) weepromint(add*2, *(p+add));
add++;
}
UART0_SendByte(0x06);
}
}
}
// 接收后发送数据M0
void PC_readM(void)
{
uint add;
uchar sbyte;
uchar sbyteC, chsum;
// 0230303130303031033535 read M0
if(rsdata[2]==0x30 && rsdata[3]==0x31 && rsdata[6]==0x30 && rsdata[7]==0x31){
add = (uhex_tbl[rsdata[4]-'0'])*0x10 + (uhex_tbl[rsdata[5]-'0']);
if(add == DREG[0]){
UART0_SendByte(0x02);
chsum = 0;
sbyte = relaysd;
sbyteC = hex_tbl[sbyte/16]; chsum += sbyteC; UART0_SendByte(sbyteC);
sbyteC = hex_tbl[sbyte%16]; chsum += sbyteC; UART0_SendByte(sbyteC);
UART0_SendByte(0x03);
chsum += 0x03;
UART0_SendByte(hex_tbl[chsum/16]);
UART0_SendByte(hex_tbl[chsum%16]);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -