[發送]00 01 02 03 [接收]FF FD FB FB [發送]1A B2 3C D4 E5 F6 7B 8D [接收]DB BB BF D7 F5 F7 7B ED [發送]01 02 03 04 05 06 07 08 [接收]FD FB FB F7 F5 F7 F7 EF
大概是這樣的情況。
下面是我的程序,用的是lin做sci,modbus,改了很久,每次結果都是一樣的。
void main(void)
{
InitSysCtrl();
InitLinaGpio();
InitPieCtrl();
InitPieVectTable();
EALLOW;
PieVectTable.TINT0=&cpu_time0_isr;
EDIS;
InitCpuTimers();
ConfigCpuTimer(&CpuTimer0,63,1000);
PieCtrlRegs.PIEIER1.bit.INTx7=1;
IER=1;
EALLOW;
PieVectTable.LIN0INTA=&LIN0INTA_ISR;
PieVectTable.LIN1INTA=&LIN1INTA_ISR;
EDIS;
PieCtrlRegs.PIEIER9.bit.INTx4=1;
PieCtrlRegs.PIEIER9.bit.INTx3=1;
IER|=0x100;
EINT;
ERTM;
SetupSCI();
ConfigureModbus();
while(1)
{
if((CpuTimer0.InterruptCount>7)&&(ModbusModule.Status==0x01))
{
ModbusModule.Status=RECE_END;
CpuTimer0.InterruptCount=0;
RTUSlaveFrameAnalyse();
ModbusModuleRTUSlaveRun();
}
}
}
void ConfigureModbus(void)
{
int i;
for(i=0;i<256;i++)
{
ModbusModule.Buf[i]=0;
}
ModbusModule.Txlen=0x0;
ModbusModule.Rxlen=0x0;
ModbusModule.Point=0x0;
ModbusModule.ID=0x1;
ModbusModule.FunCode=0;
ModbusModule.Status=SEND_END;
}
interrupt void LIN0INTA_ISR(void)
{
int i;
if(ModbusModule.Txlen!=0)
{
if(ModbusModule.Txlen>16)
{
for(i=0;i<16;i++)
{
LinaRegs.SCITD=ModbusModule.Buf[ModbusModule.Point++];
}
ModbusModule.Txlen-=16;
ModbusModule.Status=SEND_START;
}
else
for(i=0;i<ModbusModule.Txlen;i++)
{
LinaRegs.SCITD=ModbusModule.Buf[ModbusModule.Point++];
}
ModbusModule.Txlen=0;
}
else
{
ModbusModule.Status=SEND_END;
LinaRegs.SCIGCR1.bit.RXENA = 1; //Enable RX
LinaRegs.SCIGCR1.bit.TXENA = 0; //Disable TX
ConfigureModbus();
}
//*SciaRegs.SCIFFTX.bit.TXINTCLR=1;*/
PieCtrlRegs.PIEACK.bit.ACK9=1;
}
interrupt void LIN1INTA_ISR(void)
{
Uint16 temp;
CpuTimer0Regs.TCR.bit.TSS=1;
CpuTimer0Regs.TCR.bit.TRB=1;
CpuTimer0Regs.TCR.bit.TSS=0;
temp=LinaRegs.SCIRD.all;
temp&=0xff;
switch(ModbusModule.Status)
{
case 0x00:
ModbusModule.Status=RECE_START;
ModbusModule.Buf[ModbusModule.Point++]=temp;
ModbusModule.Rxlen=ModbusModule.Point;
break;
case 0x01:
if(CpuTimer0.InterruptCount<3)
{
ModbusModule.Buf[ModbusModule.Point++]=temp;
ModbusModule.Rxlen=ModbusModule.Point;
}
if(CpuTimer0.InterruptCount<=7&&CpuTimer0.InterruptCount>3)
{
ModbusModule.Status=SEND_END;
SetupSCI();
ConfigureModbus();
}
break;
}
CpuTimer0.InterruptCount=0;
LinaRegs.SCIGCR1.bit.RXENA = 0; //Disable RX
LinaRegs.SCIGCR1.bit.TXENA = 1; //Enable TX
PieCtrlRegs.PIEACK.bit.ACK9=1;
}
Uint16 GetCRC16(Uint16 volatile* ptr,Uint16 len)
{
Uint16 i,j;
Uint16 crc=0xffff;
for(i=0;i<len;i++)
{
crc^=(*ptr);
for(j=0;j<8;j++)
{
if(crc&1)
{
crc>>=1;
crc&=0xA001;
}
else
crc>>=1;
}
ptr++;
}
return(crc);
}
void ModbusSlaveSetNHIdRegAnswer(Uint16 board_adr,Uint16 start_address,Uint16 lenth)
{
Uint16 i,j;
i=0;j=0;
ModbusModule.Buf[i++]=board_adr;
ModbusModule.Buf[i++]=SET_N_HLD_REG;
ModbusModule.Buf[i++]=WORD_HI(start_address);
ModbusModule.Buf[i++]=WORD_LO(start_address);
ModbusModule.Buf[i++]=WORD_HI(lenth);
ModbusModule.Buf[i++]=WORD_LO(lenth);
j=GetCRC16(ModbusModule.Buf,i);
ModbusModule.Buf[i++]=WORD_HI(j);
ModbusModule.Buf[i++]=WORD_LO(j);
ModbusModule.Txlen=i;
ModbusModule.Point=0;
}
void ModbusSlaveReadNHIdRegAnswer(Uint16 board_adr,Uint16 lenth)
{
Uint16 i,j,firstaddr;
Uint16 *FirstAddr;
i=0;j=0;
firstaddr=(ModbusModule.Buf[2]<<8)+ModbusModule.Buf[3];
FirstAddr=(Uint16 *)firstaddr;
ModbusModule.Buf[i++]=board_adr;
ModbusModule.Buf[i++]=READ_HLD_REG;
ModbusModule.Buf[i++]=(lenth<<1);
for(j=0;j<lenth;j++)
{
ModbusModule.Buf[i++]=WORD_HI(*(j+FirstAddr));
ModbusModule.Buf[i++]=WORD_LO(*(j+FirstAddr));
}
j=GetCRC16(ModbusModule.Buf,i);
ModbusModule.Buf[i++]=WORD_HI(j);
ModbusModule.Buf[i++]=WORD_LO(j);
ModbusModule.Rxlen=i;
ModbusModule.Point=0;
}
Uint16 WORD_HI(Uint16 i)
{
return(i>>8);
}
Uint16 WORD_LO(Uint16 i)
{
i<<=8;
return(i>>8);
}
Uint16 RTUSlaveFrameAnalyse(void)
{
Uint16 RegsLenth;
Uint16 crc_tmp,crc_result;
Uint16 RegAddr,RegNum;
crc_tmp=(ModbusModule.Buf[ModbusModule.Rxlen-2]<<8)+ModbusModule.Buf[ModbusModule.Rxlen-1];
crc_result=GetCRC16(ModbusModule.Buf,ModbusModule.Rxlen-2);
if(crc_result!=crc_tmp)
return 1;
if(ModbusModule.ID!=ModbusModule.Buf[0])
return 2;
ModbusModule.FunCode=ModbusModule.Buf[1];
switch(ModbusModule.FunCode)
{
case 03:
RegsLenth=(ModbusModule.Buf[ModbusModule.Rxlen-4]<<8)+ModbusModule.Buf[ModbusModule.Rxlen-3];
ModbusSlaveReadNHIdRegAnswer(ModbusModule.ID,RegsLenth);
break;
case 16:
RegAddr=(ModbusModule.Buf[2]<<8)+ModbusModule.Buf[3];
RegNum=(ModbusModule.Buf[4]<<8)+ModbusModule.Buf[5];
if((RegNum<<1)!=ModbusModule.Buf[6])
{
return 4;
}
ModbusSlaveSetNHIdRegAnswer(ModbusModule.ID,RegAddr,RegNum);
break;
}
return 0;
}
void ModbusModuleRTUSlaveRun(void)
{
if(RTUSlaveFrameAnalyse()==0)
{
ModbusModule.Status=SEND_START;
LinaRegs.SCIGCR1.bit.RXENA = 0; //Disable RX
LinaRegs.SCIGCR1.bit.TXENA = 1; //Enable TX
}
else
{
ModbusModule.Status=SEND_END;
ConfigureModbus();
}
}
interrupt void cpu_time0_isr(void)
{
CpuTimer0.InterruptCount++;
EALLOW;
SysCtrlRegs.WDKEY=0xAA;
SysCtrlRegs.WDKEY=0x55;
EDIS;
PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;
}
void SetupSCI(void)
{
//Allow write to protected registers
EALLOW;
LinaRegs.SCIGCR0.bit.RESET = 0; //Into reset
LinaRegs.SCIGCR0.bit.RESET = 1; //Out of reset
LinaRegs.SCIGCR1.bit.SWnRST = 0; //Into software reset
//SCI Configurations
LinaRegs.SCIGCR1.bit.COMMMODE = 0; //Idle-Line Mode
LinaRegs.SCIGCR1.bit.TIMINGMODE = 1; //Asynchronous Timing
LinaRegs.SCIGCR1.bit.PARITYENA = 0; //No Parity Check
LinaRegs.SCIGCR1.bit.PARITY = 0; //Odd Parity
LinaRegs.SCIGCR1.bit.STOP = 0; //One Stop Bit
LinaRegs.SCIGCR1.bit.CLK_MASTER = 1; //Enable SCI Clock
LinaRegs.SCIGCR1.bit.LINMODE = 0; //SCI Mode
LinaRegs.SCIGCR1.bit.SLEEP = 0; //Ensure Out of Sleep
LinaRegs.SCIGCR1.bit.MBUFMODE = 1; //Buffered Mode
LinaRegs.SCIGCR1.bit.LOOPBACK = 1; //Internal Loopback
LinaRegs.SCIGCR1.bit.CONT = 1; //Continue on Suspend
LinaRegs.SCIGCR1.bit.RXENA = 1; //Enable RX
LinaRegs.SCIGCR1.bit.TXENA = 1; //Enable TX
//Ensure IODFT is disabled
LinaRegs.IODFTCTRL.bit.IODFTENA = 0x0;
//Set transmission length
LinaRegs.SCIFORMAT.bit.CHAR = 7; //Eight bits
LinaRegs.SCIFORMAT.bit.LENGTH = 7; //Eight bytes
//Set baudrate
LinaRegs.BRSR.bit.P = 96; //19.2 kbps for SYSCLKOUT = 60 MHz
LinaRegs.BRSR.bit.M = 10;
//Enable interrupts
LinaRegs.SCISETINT.bit.SETRXINT = 1; //Enable RX interrupt
//Set interrupt priority
LinaRegs.SCICLEARINTLVL.all = 0xFFFFFFFF; //Set Int level of all interrupts to LVL 0
LinaRegs.SCIGCR1.bit.SWnRST = 1; //bring out of software reset
//Disable write to protected registers
EDIS;
|