版主可以帮我看看我的程序还有什么欠缺么,有些地方实在不知道怎么写了,能帮忙改一下。谢谢
#include "msp430x14x.h"
#define uchar unsigned char
#define uint unsigned int
/****************************************************************************/
#define P3_0_WDI 0x01 //WDT
#define P3_1_BEEP 0x02 //蜂鸣
#define P3_2_RTS1 0x04 //RS485A控制
#define P3_3_RTS 0x08 //RS485B控制
#define P5_5_DAT 0x20 //LED DAT BC7281B接口
#define P5_6_KEY 0x40 //LED KEY
#define P5_7_CLK 0x80 //LED CLK
/****************************************************************************/
uchar CAddress; //仪表地址
uchar Cbps=3,Cbpss=4;
uchar Cdata8=0,Cdata8s=0;
uchar Cmima[4];//密码
typedef enum
{
SYS_Idle,//空闲
SYS_Txd,//发送数据
SYS_Twait1,//发送等待
SYS_Twait2, //发送等待
SYS_Rwait,//接收等待
}SYS_STATE;
SYS_STATE systemState;
uchar Rxok=0;
uchar Cflag,Crep=0,Cdscon=0;
uint Csearch[16];
uint nHmax[16]; //20mA液位值
uint fXiuZheng[16];//修正系数
uchar CregArry[32];//液位值
uchar Cmnumber=12;
uchar Ckey_number;
uchar FlashWord[10];
uchar CDispBuff[12];
uint *pq=(uint *)0xfd00;//指向Flash
unsigned char aRxBuff0[16]; //接收数据缓冲区
unsigned char NRxBuff0=0;
unsigned char aTxBuff0[128]; //发送数据缓冲区
unsigned char NTxBuff0=0;
unsigned char commandPending0=0,Ntxd0=0;
uint timeoutCounter0=0;
uint RXcrc0;
uint UstarReg0,UregNum0;
uint txwait0;
uchar bUartRxErr0;
uchar Couttime,Couttime1,CdelayT,CdelayT1;
unsigned char aRxBuff1[16]; //接收数据缓冲区
unsigned char NRxBuff1=0;
unsigned char aTxBuff1[32]; //发送数据缓冲区
unsigned char NTxBuff1=0;
unsigned char commandPending1=0,Ntxd1=0;
uint timeoutCounter1=0;
uint RXcrc1;
uint UstarReg1,UregNum1;
uint txwait1;
uchar bUartRxErr1;
unsigned char *puchMsg ; /* 要进行CRC校验的消息 */
unsigned int CRC16(uchar *puchMsg, uchar usDataLen)
{
unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */
unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */
unsigned uIndex ; /* CRC循环中的索引 */
while (usDataLen--) /* 传输消息缓冲区 */
{
uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
uchCRCLo = auchCRCLo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo) ;
}
void UpdateStateMachine(void)
{
static unsigned char CAdesm=1;
static unsigned int ia;
switch (systemState)
{
case SYS_Idle:
P3OUT|=P3_2_RTS1;
aTxBuff1[0]=CAdesm;//地址
aTxBuff1[1]=0x03;//功能代码
aTxBuff1[2]=0x00;//起始地址
aTxBuff1[3]=0x00;//起始地址
aTxBuff1[4]=0x00;//寄存器个数
aTxBuff1[5]=0x01;//寄存器个数
puchMsg=aTxBuff1;
RXcrc1=CRC16(puchMsg, 6);//字符串校验
aTxBuff1[6]=RXcrc1>>8;//功能代码
aTxBuff1[7]=RXcrc1&0x00ff;
NTxBuff1=0;
systemState=SYS_Txd;
break;
case SYS_Txd:
if (NTxBuff1<8)
{
TXBUF1=aTxBuff1[NTxBuff1];
NTxBuff1++;
systemState=SYS_Twait1;
}
else
{
ia=0;
systemState=SYS_Twait2;
}
break;
case SYS_Twait1:
if (IFG2&UTXIFG1)//查询是否发送完毕
{
systemState=SYS_Txd;
}
break;
case SYS_Twait2:
ia++;
if (ia>=CdelayT1)
{
CAdesm++;
if (CAdesm>Cmnumber)
CAdesm=1;
systemState=SYS_Rwait;
P3OUT&=~P3_2_RTS1;
Rxok=0;
ia=0;
}
break;
case SYS_Rwait:
ia++;
if ((ia>=2500)||((Rxok==1)&&(ia>=80)))
{
systemState=SYS_Idle;
}
break;
default :
systemState=SYS_Idle;
break;
}
}
void HandleUART0(void)
{
uint i;
if (NRxBuff0>0)
{
if(timeoutCounter0++ > Couttime)//接收超时
{
NRxBuff0=0;
for (i=0;i<10;i++)
{
aRxBuff0[i]=0;
}
}
}
else
{
timeoutCounter0 = 0;// Don't let timeoutCounter slowly grow over many commands.
}
if (commandPending0 == 0)//收态
{
if (NRxBuff0>=8)
{
if ((aRxBuff0[3]==0x04)&&(aRxBuff0[1]==0x06))
{
if (NRxBuff0>=10)
{
puchMsg=aRxBuff0;
RXcrc0=CRC16(puchMsg, NRxBuff0-2);//字符串校验
i=aRxBuff0[NRxBuff0-2]*0x100+aRxBuff0[NRxBuff0-1];
NRxBuff0=0;
if (RXcrc0==i)//通过CRC校验
{
if (aRxBuff0[0]==CAddress)
{
commandPending0 = 1;
}
}
}
}
else
{
puchMsg=aRxBuff0;
RXcrc0=CRC16(puchMsg, NRxBuff0-2);//字符串校验
i=aRxBuff0[NRxBuff0-2]*0x100+aRxBuff0[NRxBuff0-1];
NRxBuff0=0;
if (RXcrc0==i)//通过CRC校验
{
if (aRxBuff0[0]==CAddress)
{
commandPending0 = 1;
}
}
else
{
commandPending0 = 0;
NRxBuff0=0;
for (i=0;i<10;i++)
{
aRxBuff0[i]=0;
}
}
}
}
}
else if (commandPending0 == 1)//命令处理
{
switch(aRxBuff0[1])
{
case 3:
UstarReg0=aRxBuff0[2]*0x100+aRxBuff0[3];
UregNum0=(aRxBuff0[4]*0x100+aRxBuff0[5])<<1;
aTxBuff0[0]=CAddress;//地址
aTxBuff0[1]=0x03;//功能代码
aTxBuff0[2]=UregNum0;
for (i=0;i<UregNum0;i++)
{
aTxBuff0[i+3]=CregArry[(UstarReg0<<1)+i];
}
puchMsg=aTxBuff0;
RXcrc0=CRC16(puchMsg, UregNum0+3);//CRC计算
aTxBuff0[UregNum0+3]=(RXcrc0&0xff00)>>8; //CRC高字节
aTxBuff0[UregNum0+4]=RXcrc0&0x00ff;//CRC低字节
P3OUT|=P3_3_RTS;
Ntxd0=UregNum0+5;
NTxBuff0=0;
commandPending0 = 2;
//SendUart0(UregNum+5);//发送
break;
case 6:
UstarReg0=aRxBuff0[2]*0x100+aRxBuff0[3];
switch(UstarReg0)
{
case 0://初值
break;
case 1://地址
break;
case 2://20mA
break;
case 3://调相
break;
case 4://修正系数
break;
default :
break;
}
commandPending0 = 0;
break;
default :
commandPending0 = 0;
break;
}//功能
}
else if (commandPending0 == 2)//发态
{
TXBUF0=aTxBuff0[NTxBuff0];
NTxBuff0++;
if (NTxBuff0>=Ntxd0)
{
commandPending0 = 4;
txwait0=CdelayT;
}
else
{
commandPending0 = 3;
}
}
else if(commandPending0 == 3)//发送等待状态
{
if (IFG1&UTXIFG0)//查询是否发送完毕
{
commandPending0 =2;
}
}
else if(commandPending0 == 4)
{
if(--txwait0 == 0)
{
commandPending0 = 0;
P3OUT&=~P3_3_RTS;
}
}
}
void HandleUART1(void)
{
uint i;
if (NRxBuff1>0)
{
if(timeoutCounter1++ > Couttime1)//接收超时
{
NRxBuff1=0;
for (i=0;i<10;i++)
{
aRxBuff1[i]=0;
}
}
}
else
{
timeoutCounter1 = 0;// Don't let timeoutCounter slowly grow over many commands.
}
if (commandPending1 == 0)//收态
{
if (NRxBuff1>=7)
{
puchMsg=aRxBuff1;
RXcrc1=CRC16(puchMsg, NRxBuff1-2);//字符串校验
i=aRxBuff1[NRxBuff1-2]*0x100+aRxBuff1[NRxBuff1-1];
NRxBuff1=0;
if (RXcrc1==i)//通过CRC校验
{
commandPending1 = 1;
}
else
{
commandPending1 = 0;
NRxBuff1=0;
for (i=0;i<10;i++)
{
aRxBuff1[i]=0;
}
}
}
}
else if (commandPending1 == 1)//命令处理
{
switch(aRxBuff1[1])
{
case 3:
CregArry[(aRxBuff1[0]-1)<<1]=aRxBuff1[3];
CregArry[((aRxBuff1[0]-1)<<1)+1]=aRxBuff1[4];
Rxok=1;
commandPending1 = 0;
break;
default :
commandPending1 = 0;
break;
}//功能
}
}
/************************************************************
*Function:系统初始化
*parameter:
*Return:
*Modify:
*************************************************************/
void system_ini( void )
{
int i;
WDTCTL = WDTPW + WDTHOLD; //stop the Watch_dog counter
_BIC_SR(0x20);
BCSCTL1=0x00; //XT2 开启
do
{
IFG1 &=~OFIFG;
for (i=0;i<0xff;i++);
}
while ((IFG1&OFIFG)!=0);
BCSCTL2 = SELM1+SELS; //MCLK=XT2,SMCLK=MCLK
WDTCTL=WDTPW+WDTCNTCL+WDTSSEL; //clear the Watch_dog counter,select the 1 second period
P1DIR=0x1C;
P2DIR=0x00;
P3DIR=0x0f;
P3SEL=0xf0; //Enable USART0,1
P4DIR=0x02;
P5DIR=0xa0;
P6DIR=0x60;
P5OUT|=P5_5_DAT;
P5DIR&=~P5_5_DAT;
pq=(unsigned int *)0xfd00;
for (i=0;i<8;i++) //读出FLASH保存的参数
{
FlashWord[i]=*pq;
pq++;
}
CAddress=FlashWord[0]; //仪表地址
if (CAddress>247)
CAddress=1;
Cbps=FlashWord[1];
if (Cbps==0xff)
Cbps=3;
Cdata8=FlashWord[2];
if (Cdata8==0xff)
Cdata8=0;
Cmima[0]=FlashWord[3]&0x0f;
Cmima[1]=FlashWord[3]>>4;
Cmima[2]=FlashWord[4]&0x0f;
Cmima[3]=FlashWord[4]>>4;
Cmnumber=FlashWord[5];
if (Cmnumber==0xff)
Cmnumber=11;
Cbpss=FlashWord[6];
if (Cbpss==0xff)
Cbpss=4;
Cdata8s=FlashWord[7];
if (Cdata8s==0xff)
Cdata8s=0;
//TACTL = TASSEL0 + TACLR; //select the MCLK as the clock in
//CCTL0=CCIE; //enable the comparation interrupt of CC0
//CCTL2=CCIE;
//TACTL|=MC1; //continous increase counter
//TBCTL=TBSSEL0+TBCLR; //TB初始化
//TBCCTL0=CCIE;
//TBCTL|=MC1;
switch(Cdata8)
{
case 0:
UCTL0 = CHAR+SWRST; //8位数据,1位停止位,n校验
break;
case 1:
UCTL0 = CHAR+SWRST+PENA; //8位数据,1位停止位,奇校验
break;
case 2:
UCTL0 = CHAR+SWRST+PENA+PEV;//8位数据,1位停止位,偶校验
break;
case 3:
UCTL0 = CHAR+SWRST+SPB; //8位数据,2位停止位,n校验
break;
case 4:
UCTL0 = CHAR+SWRST+PENA+SPB; //8位数据,2位停止位,奇校验
break;
case 5:
UCTL0 = CHAR+SWRST+PENA+PEV+SPB;//8位数据,2位停止位,偶校验
break;
default :
UCTL0 = CHAR+SWRST; //8位数据,1位停止位,n校验
break;
}
switch(Cbps)
{
case 0://1200
UTCTL0 = SSEL1; //选择UCLK = SMCLK
UBR00 = 0x00; //设置波特率1200bit/s
UBR10 = 0x10;
UMCTL0 = 0x00;
Couttime=30;
CdelayT=45;
break;
case 1://2400
UTCTL0 = SSEL1; //选择UCLK = SMCLK
UBR00 = 0x00; //设置波特率2400bit/s
UBR10 = 0x08;
UMCTL0 = 0x00;
Couttime=16;
CdelayT=30;
break;
case 2://4800
UTCTL0 = SSEL1; //选择UCLK = SMCLK
UBR00 = 0x00; //设置波特率4800bit/s
UBR10 = 0x04;
UMCTL0 = 0x00;
Couttime=8;
CdelayT=16;
break;
case 3://9600
UTCTL0 = SSEL1; //选择UCLK = SMCLK
UBR00 = 0x00; //设置波特率9600bit/s
UBR10 = 0x02;
UMCTL0 = 0x00;
Couttime=4;
CdelayT=8;
break;
case 4://19200
UTCTL0 = SSEL1; //选择UCLK = SMCLK
UBR00 = 0x00; //设置波特率19200bit/s
UBR10 = 0x01;
UMCTL0 = 0x00;
Couttime=4;
CdelayT=4;
break;
default :
UTCTL0 = SSEL1; //选择UCLK = SMCLK
UBR00 = 0x00; //设置波特率19200bit/s
UBR10 = 0x01;
UMCTL0 = 0x00;
Couttime=4;
CdelayT=4;
break;
}
UCTL0 &= ~SWRST;
ME1 |= UTXE0 + URXE0; //打开模块USART0
IE1 |= URXIE0 ; //打开USART0接收中断
P3OUT&=~P3_3_RTS;
switch(Cdata8s)
{
case 0:
UCTL1 = CHAR+SWRST; //8位数据,1位停止位,n校验
break;
case 1:
UCTL1 = CHAR+SWRST+PENA; //8位数据,1位停止位,奇校验
break;
case 2:
UCTL1 = CHAR+SWRST+PENA+PEV;//8位数据,1位停止位,偶校验
break;
case 3:
UCTL1 = CHAR+SWRST+SPB; //8位数据,2位停止位,n校验
break;
case 4:
UCTL1 = CHAR+SWRST+PENA+SPB; //8位数据,2位停止位,奇校验
break;
case 5:
UCTL1 = CHAR+SWRST+PENA+PEV+SPB;//8位数据,2位停止位,偶校验
break;
default :
UCTL1 = CHAR+SWRST; //8位数据,1位停止位,n校验
break;
}
switch(Cbpss)
{
case 0://1200
UTCTL1 = SSEL1; //选择UCLK = SMCLK
UBR01 = 0x00; //设置波特率1200bit/s
UBR11 = 0x10;
UMCTL1 = 0x00;
Couttime1=30;
CdelayT1=45;
break;
case 1://2400
UTCTL1 = SSEL1; //选择UCLK = SMCLK
UBR01 = 0x00; //设置波特率2400bit/s
UBR11 = 0x08;
UMCTL1 = 0x00;
Couttime1=16;
CdelayT1=30;
break;
case 2://4800
UTCTL0 = SSEL1; //选择UCLK = SMCLK
UBR01 = 0x00; //设置波特率4800bit/s
UBR11 = 0x04;
UMCTL1 = 0x00;
Couttime1=8;
CdelayT1=16;
break;
case 3://9600
UTCTL1 = SSEL1; //选择UCLK = SMCLK
UBR01 = 0x00; //设置波特率9600bit/s
UBR11 = 0x02;
UMCTL1 = 0x00;
Couttime1=4;
CdelayT1=8;
break;
case 4://19200
UTCTL1 = SSEL1; //选择UCLK = SMCLK
UBR01 = 0x00; //设置波特率19200bit/s
UBR11 = 0x01;
UMCTL1 = 0x00;
Couttime1=4;
CdelayT1=4;
break;
default :
UTCTL1 = SSEL1; //选择UCLK = SMCLK
UBR01 = 0x00; //设置波特率19200bit/s
UBR11 = 0x01;
UMCTL1 = 0x00;
Couttime1=4;
CdelayT1=4;
break;
}
UCTL1 &= ~SWRST;
ME2 |= UTXE1 + URXE1; //打开模块USART1
IE2 |= URXIE1 ; //打开USART1接收中断
P3OUT&=~P3_2_RTS1;
TempDelay(2000);
write728x(0x12,0xc8); // 初始化BC728x为164模式,保护(RP=1),不反相,BMS=1, KMS=0
write728x(0x1b,0x00); // 初始化BC728x为不闪烁
write728x(0x10,0xff); // 初始化BC728x为不闪烁
write728x(0x1c,0xbf); // 初始化BC728x闪烁速度2Hz
write728x(0x11,0x40); // 初始化BC728x闪烁速度2Hz
write728x(0x16,0x00); // 初始化BC728x清屏
write728x(0x17,0x00); // 初始化BC728x清屏
CDispBuff[11]=0x0f;
CDispBuff[10]=0x0f;
CDispBuff[9]=0x0f;
CDispBuff[8]=0x0f;
}
/************************************************************
*Function:主程序
*parameter:
*Return:
*Modify:
*************************************************************/
void main(void)
{
system_ini();
Beep();
_EINT();
while(1)
{
dog();
key_int(); //键盘扫描
HandleUART0();
HandleUART1();
UpdateStateMachine();
mDisplay();
}
}
/************************************************************
*Function:USART0RX中断处理 modbus_RTU 通讯协议
*parameter: 01 04 00 00 00 01 31 ca(上位机指令)
*Return: 01 04 02 DD DD CRCH CRCL(下位机应答)
*Modify:RS485接口 115200 E 8 1
*************************************************************/
#pragma vector=USART0RX_VECTOR
__interrupt void UsartRx0 (void)
{
if((URCTL0&RXERR)==0)
{
aRxBuff0[NRxBuff0]=RXBUF0;
NRxBuff0++;
timeoutCounter0 = 0;
} //接收无错误发生
else
{
aRxBuff0[NRxBuff0]=RXBUF0; //接收出错
bUartRxErr0=1;
NRxBuff0=0;
timeoutCounter0 = 0;
}
}
/************************************************************
*Function: USART1接收中断
*parameter:
*Return:
*Modify:
*************************************************************/
#pragma vector=USART1RX_VECTOR
__interrupt void UsartRx1(void)
{
if((URCTL1&RXERR)==0)
{
aRxBuff1[NRxBuff1]=RXBUF1;
NRxBuff1++;
timeoutCounter1 = 0;
} //接收无错误发生
else
{
aRxBuff1[NRxBuff1]=RXBUF1; //接收出错
bUartRxErr1=1;
NRxBuff1=0;
timeoutCounter1 = 0;
}
}
/************************************************************
*Function:定时器TA0中断处理 定时1秒发波一次
*parameter:
*Return:
*Modify:
*************************************************************/
#pragma vector=TIMERA0_VECTOR
__interrupt void timerA0 (void)
{
}
/************************************************************
*Function:定时器TA1中断处理
*parameter:
*Return:
*Modify:
*************************************************************/
#pragma vector=TIMERA1_VECTOR
__interrupt void timerA1 (void)
{
switch(TAIV)
{
case 2:
break; //CCR1
case 4:
CCR2+=32768;
break; //ccr2
case 10:
break;//A1溢出
}
}
/************************************************************
*Function:定时器TB0中断处理,
*parameter:
*Return:
*Modify:
*************************************************************/
#pragma vector=TIMERB0_VECTOR
__interrupt void timerB0 (void)
{
}
/************************************************************
*Function:定时器TB1中断处理
*parameter:
*Return:
*Modify:
*************************************************************/
#pragma vector=TIMERB1_VECTOR
__interrupt void timerB1 (void)
{
switch(TBIV)
{
case 2:
break; //CCR1
case 4:
break; //ccr2
case 6:
break; //ccr3
case 8:
break; //ccr4
case 10:
break; //ccr5
case 12:
break; //ccr6
case 14:
break; //B1溢出2
}
}
/************************************************************
*Function:
*parameter:
*Return:
*Modify:
*************************************************************/
#pragma vector=COMPARATORA_VECTOR
__interrupt void comparatorA (void)
{
} |