本帖最后由 hbzjt2012 于 2015-4-2 22:41 编辑
#include "synth.h"
- //------------------------------------------------------------------------------
- bool CommState; // 通讯状态
- bool Request; // 允许接收
- bool Response; // 允许发送
- bool EnCommWrite; // 允许通讯写
- uchar UDRBuf; // 通讯接收寄存器缓存
- uchar CommIndex; // 通讯索引
- uchar CrcLow; // CRC低字节
- uchar CrcHigh; // CRC高字节
- uchar Interval; // 3.5字符时间间隔
- uchar CommWrEntry; // 通讯写入口
- uchar CommBuf[BUF_SIZE]; // 通讯缓冲区
- uint StartAddr; // 起始地址
- uint RegNum; // 寄存器数量
- int bAudBuf; // 通讯波特率缓存
- int FormBuf; // 通讯数据格式缓存
- extern const StrKeybd Keybd[];
- //------------------------------------------------------------------------------
- void ResetInterval(void) // 重置3.5字符时间间隔
- {
- switch(bAudBuf)
- {
- case 0: Interval = (uchar)(1000/( 1200/11.0)*3.5/TBASE); break;
- case 1: Interval = (uchar)(1000/( 2400/11.0)*3.5/TBASE); break;
- case 2: Interval = (uchar)(1000/( 4800/11.0)*3.5/TBASE); break;
- default: Interval = (uchar)(1000/( 9600/11.0)*3.5/TBASE); break;
- case 4: Interval = (uchar)(1000/(19200/11.0)*3.5/TBASE); break;
- }
- }
- //******************************************************************************
- void OpenComm(void) // 打开或关闭通讯
- {
- ResetInterval();
- UCA0CTL1 |= (UCSSEL_2 + UCRXEIE);
- switch(FormBuf)
- {
- default: UCA0CTL0 = UCSPB; break; // N-2
- case 1: UCA0CTL0 = UCPEN; break; // O-1
- case 2: UCA0CTL0 = UCPEN + UCPAR; break; // E-1
- case 3: UCA0CTL0 = 0; break; // N-1
- }
- switch(bAudBuf)
- {
- case 0: UCA0BR1 = (uint)(BRCLK/1200) >> 8;
- UCA0BR0 = (uchar)((uint)(BRCLK/1200));
- UCA0MCTL = (uint)((BRCLK/1200-(uint)(BRCLK/1200))*8)<<1;
- break;
- case 1: UCA0BR1 = (uint)(BRCLK/2400) >> 8;
- UCA0BR0 = (uchar)((uint)(BRCLK/2400));
- UCA0MCTL = (uint)((BRCLK/2400-(uint)(BRCLK/2400))*8)<<1;
- break;
- case 2: UCA0BR1 = (uint)(BRCLK/4800) >> 8;
- UCA0BR0 = (uchar)((uint)(BRCLK/4800));
- UCA0MCTL = (uint)((BRCLK/4800-(uint)(BRCLK/4800))*8)<<1;
- break;
- default: UCA0BR1 = (uint)(BRCLK/9600) >> 8;
- UCA0BR0 = (uchar)((uint)(BRCLK/9600));
- UCA0MCTL = (uint)((BRCLK/9600-(uint)(BRCLK/9600))*8)<<1;
- break;
- case 4: UCA0BR1 = (uint)(BRCLK/19200) >> 8;
- UCA0BR0 = (uchar)((uint)(BRCLK/19200));
- UCA0MCTL = (uint)((BRCLK/19200-(uint)(BRCLK/19200))*8)<<1;
- break;
- }
- UCA0CTL1 &= ~UCSWRST;
- IE2 |= UCA0RXIE;
- }
- //******************************************************************************
- void Communication(void) // 通讯
- {
- if((SMM.out1 == COMM) || (SMM.out2 == COMM) || (SMM.out3 == COMM))
- {
- if((bAudBuf != SMM.bAud) || (FormBuf != SMM.ForM) || (!CommState))
- {
- bAudBuf = SMM.bAud;
- FormBuf = SMM.ForM;
- UCA0CTL1 = UCSWRST;
- OpenComm();
- CommState = true;
- }
- }
- else
- {
- UCA0CTL1 = UCSWRST;
- CommState = false;
- }
- }
- //******************************************************************************
- void SingleCRC(uchar data) // 计算单字节CRC校验码
- {
- uchar c = CrcLow ^ data;
- CrcLow = TabCRC[c] ^ CrcHigh;
- CrcHigh = TabCRC[c + 0x100];
- }
- //******************************************************************************
- __monitor void SilentInterval(void) // 检测通讯3.5字符时间间隔
- {
- if(CommState)
- {
- if(Interval == 0)
- {
- ResetInterval();
- CrcLow = 0xFF;
- CrcHigh = 0xFF;
- CommIndex = 0;
- if(Response)
- {
- Response = false;
- IE2 |= UCA0TXIE;
- }
- else
- {
- IE2 &= ~UCA0TXIE;
- Request = true;
- }
- }
- else
- --Interval;
- }
- }
- //******************************************************************************
- bool CheckDataValid(void) // 检测写入数据的有效性
- {
- uchar c, index = StartAddr + OFFSET;
- for(c = 0; c < RegNum; ++c, ++index)
- {
- uchar buf = c * 2;
- int data = ((int)CommBuf[7 + buf] << 8) | CommBuf[8 + buf];
- if((data < Keybd[index].LowerLimit) || (data > Keybd[index].HigherLimit))
- return(false);
- }
- return(true);
- }
- //******************************************************************************
- void GetDataToMenu(void) // 更新参数值
- {
- uchar c, *ta = &SB[(StartAddr + OFFSET) * 2], *src = &CommBuf[8];
- for(c = RegNum; c; --c)
- { // 低字节
- *ta = *src;
- ta += 2; src += 2;
- }
- ta = &SB[(StartAddr + OFFSET) * 2 + 1], src = &CommBuf[7];
- for(c = RegNum; c; --c)
- { // 高字节
- *ta = *src;
- ta += 2; src += 2;
- }
- }
- //******************************************************************************
- void GetDataToBuff(void) // 取参数值
- {
- uchar c, *ta = &CommBuf[4], *src = &SB[(StartAddr + OFFSET) * 2];
- for(c = RegNum; c; --c)
- { // 低字节
- *ta = *src;
- ta += 2; src += 2;
- }
- ta = &CommBuf[3], src = &SB[(StartAddr + OFFSET) * 2 + 1];
- for(c = RegNum; c; --c)
- { // 高字节
- *ta = *src;
- ta += 2; src += 2;
- }
- }
- //******************************************************************************
- void ManageWrite(void) // 写指令
- {
- uchar c = REGNUM * 2 + 7; // 指向CRCL
- if(CommIndex < c)
- {
- SingleCRC(UDRBuf);
- CommBuf[CommIndex++] = UDRBuf;
- }
- else if(CommIndex == c)
- {
- if(CrcLow == UDRBuf)
- {
- StartAddr = STARTADDR;
- RegNum = REGNUM;
- ++CommIndex;
- }
- else
- Request = false;
- }
- else
- {
- Request = false;
- if(CrcHigh == UDRBuf)
- {
- if((RegNum >= 1) && (RegNum <= 0x7B) && (CommBuf[6] == (RegNum * 2)))
- {
- if((StartAddr + RegNum) <= COMM_WL_WR)
- {
- if(!CheckDataValid())
- {
- CMD |= 0x80; CommBuf[2] = ERR_DATA; // 非法数据
- }
- else
- {
- GetDataToMenu();
- if(StartAddr < (COMM_WL_WR - 2))
- {
- switch(StartAddr+RegNum)
- {
- case COMM_WL_WR : RegNum -= 2; break;
- case (COMM_WL_WR-1): RegNum -= 1; break;
- default : break;
- }
- CommWrEntry = ENTRY;
- EnCommWrite = true;
- }
- }
- }
- else
- {
- CMD |= 0x80; CommBuf[2] = ERR_ADDR; // 非法地址
- }
- }
- else
- {
- CMD |= 0x80; CommBuf[2] = ERR_NUM; // 非法数量
- }
- Response = true;
- }
- }
- }
- //******************************************************************************
- void ManageRead(void) // 读指令
- {
- if(CommIndex == 6)
- {
- if(CrcLow == UDRBuf)
- {
- StartAddr = STARTADDR;
- RegNum = REGNUM;
- CommBuf[2] = RegNum * 2;
- ++CommIndex;
- }
- else
- Request = false;
- }
- else
- {
- Request = false;
- if(CrcHigh == UDRBuf)
- {
- if((RegNum >= 1) && (RegNum <= 0x7D))
- {
- if((StartAddr + RegNum) <= COMM_WL_RD)
- GetDataToBuff();
- else
- {
- CMD |= 0x80; CommBuf[2] = ERR_ADDR; // 非法地址
- }
- }
- else
- {
- CMD |= 0x80; CommBuf[2] = ERR_NUM; // 非法数量
- }
- Response = true;
- }
- }
- }
- //******************************************************************************
- #pragma vector = USCIAB0TX_VECTOR
- __interrupt void UART_transmit(void) // 通讯发送
- {
- uchar c;
- TACCTL0 &= ~CCIE;
- IE2 &= ~UCA0TXIE;
- __enable_interrupt();
- ResetInterval();
- if(CMD == READ) // 读指令
- c = CommBuf[2] + 3; // 指向CRCL
- else if(CMD == WRITE) // 写指令
- c = 6;
- else // 错误的指令
- c = 3;
- if(CommIndex <= (c + 1))
- {
- if(CommIndex < c)
- {
- c = CommBuf[CommIndex];
- SingleCRC(c);
- UCA0TXBUF = c;
- }
- else if(CommIndex == c)
- UCA0TXBUF = CrcLow;
- else
- UCA0TXBUF = CrcHigh;
- ++CommIndex;
- __disable_interrupt();
- IE2 |= UCA0TXIE;
- TACCTL0 |= CCIE;
- }
- else
- {
- __disable_interrupt();
- TACCTL0 |= CCIE;
- }
- }
- //******************************************************************************
- #pragma vector = USCIAB0RX_VECTOR
- __interrupt void UART_receive(void) // 通讯接收
- {
- UDRBuf = UCA0RXBUF;
- TACCTL0 &= ~CCIE;
- IE2 &= ~UCA0RXIE;
- __enable_interrupt();
- ResetInterval();
- if(Request)
- {
- switch(CommIndex)
- {
- case 0: if(UDRBuf != SMM.Addr)
- {
- Request = false;
- break;
- }
- case 1:
- case 2:
- case 3:
- case 4:
- case 5: SingleCRC(UDRBuf);
- CommBuf[CommIndex++] = UDRBuf;
- break;
- default: if(CMD == READ) // 读指令
- ManageRead();
- else if(CMD == WRITE) // 写指令
- ManageWrite();
- else // 非法指令
- {
- Request = false;
- CMD |= 0x80; CommBuf[2] = ERR_CMD;
- Response = true;
- }
- break;
- }
- }
- __disable_interrupt();
- IE2 |= UCA0RXIE;
- TACCTL0 |= CCIE;
- }
|