久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3640|回復: 0
打印 上一主題 下一主題
收起左側

看百度文庫上430的MODBUS程序這個文檔挺多的,可是我發現函數不全,好像不完整,

[復制鏈接]
跳轉到指定樓層
樓主
ID:65446 發表于 2014-9-22 17:46 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
看百度文庫上這個文檔挺多的,可是我發現函數不全,好像不完整,有人編過430的MODBUS程序嗎,測試通過的,我看過這個程序了,
其中缺少函數,感覺這個不是完整的,有用這個程序試成功過的嗎,歡迎探討
#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;

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 综合久久av | 久久成人精品 | 九色在线观看 | 亚洲综合大片69999 | 国产精品高潮呻吟久久aⅴ码 | 自拍偷拍亚洲视频 | 婷婷久久网| 欧美精品a∨在线观看不卡 欧美日韩中文字幕在线播放 | 亚洲日日夜夜 | 蜜桃视频在线观看www社区 | 久久久久亚洲 | 国产在线视频一区二区 | 国产精品美女久久久久aⅴ国产馆 | 精品一区二区在线视频 | 亚洲欧美视频一区 | 国产欧美在线视频 | 不卡视频一区二区三区 | 久久精品天堂 | 免费观看毛片 | 午夜激情免费视频 | 亚洲免费在线观看 | 日韩精品一区二区三区在线播放 | 国产精品影视在线观看 | 亚洲成人免费 | 久久99精品久久久久久狂牛 | 国产一区二区久久 | 国产精品www | 国产精品视频网 | 欧美炮房 | 午夜不卡福利视频 | 国产精品有限公司 | 一级欧美| 日本不卡免费新一二三区 | 国产在线www| 日日干日日色 | 精品久久香蕉国产线看观看亚洲 | 91精品国产一区二区三区 | 日本亚洲一区 | 国产超碰人人爽人人做人人爱 | 一区二区高清在线观看 | 欧美成人激情 |