cyberjok 发表于 2009-3-11 15:56:25

发一个老农的通用单片机程序的AVR移槙-ModbusRTU应用

#include <inavr.h>
    #include <ioavr.h>
    #include <intrinsics.h>
    #include <pgmspace.h>
    #include <stdbool.h>
    #include <math.h>

    #define DISABLE_INTERRUPT()         __disable_interrupt()
    #define ENABLE_INTERRUPT()          __enable_interrupt()

    struct QueueBuffer{
      unsigned char *aBufferStart;
      unsigned char *aBufferEnd;   
      unsigned char *pIn;            
      unsigned char *pOut;      
      unsigned char mCount;      
    };

    extern void Queue_Init(void);
    extern void Queue_Destory(void);
    extern void Queue_Register(struct QueueBuffer *pQueueBuffer,unsigned char QueueBuffer[],unsigned int mSize);
    extern void Queue_Push( struct QueueBuffer *pQueueBuffer, unsigned char mData );
    extern unsigned char Queue_Pop( struct QueueBuffer *pQueueBuffer );
    extern unsigned char Queue_Read( struct QueueBuffer *pQueueBuffer, unsigned char mId );
    extern unsigned int Queue_Num( struct QueueBuffer *pQueueBuffer );
    extern void Queue_Clear( struct QueueBuffer *pQueueBuffer );


void Queue_Init(void)
{
}

void Queue_Destory(void)
{
}

void Queue_Register(struct QueueBuffer *pQueueBuffer,unsigned char QueueBuffer[],unsigned int mSize)
{
    //struct QueueBuffer *pQueueBuffer;

    //pQueueBuffer = (struct QueueBuffer *)Memory_Malloc(sizeof(struct QueueBuffer));
    //Memory_Memset((unsigned char *)pQueueBuffer,0,sizeof(struct QueueBuffer));

    //pQueueBuffer->aBufferStart = pQueueBuffer->pIn = pQueueBuffer->pOut=Memory_Malloc(mSize);
    //pQueueBuffer->aBufferEnd   = pQueueBuffer->aBufferStart+mSize;

    //return pQueueBuffer;
    pQueueBuffer->aBufferStart = QueueBuffer;
    pQueueBuffer->pIn          = QueueBuffer;
    pQueueBuffer->pOut         = QueueBuffer;
    pQueueBuffer->aBufferEnd   = QueueBuffer + mSize;
}

void Queue_Push(struct QueueBuffer *pQueueBuffer,unsigned char mData)
{
    //bit fEaReg;

    //fEaReg = EA;
    //EA = 0;
    *pQueueBuffer->pIn++ = mData;
    if(pQueueBuffer->pIn == pQueueBuffer->aBufferEnd)
    {
      pQueueBuffer->pIn = pQueueBuffer->aBufferStart;
    }
    DISABLE_INTERRUPT();
    pQueueBuffer->mCount++;
    ENABLE_INTERRUPT();
    //EA = fEaReg;
}

unsigned char Queue_Pop(struct QueueBuffer *pQueueBuffer)
{
    unsigned char mData;
//    bit fEaReg;

    mData = *pQueueBuffer->pOut;
    if(++pQueueBuffer->pOut == pQueueBuffer->aBufferEnd)
    {
      pQueueBuffer->pOut = pQueueBuffer->aBufferStart;
    }

//    fEaReg = EA;
//    EA = 0;
    DISABLE_INTERRUPT();
    pQueueBuffer->mCount--;
    ENABLE_INTERRUPT();
//    EA = fEaReg;

    return mData;
}

unsigned char Queue_Read(struct QueueBuffer *pQueueBuffer,unsigned char mId)
{
    unsigned char *pTemp;
   
    pTemp = pQueueBuffer->pOut+mId;
    if(pTemp < pQueueBuffer -> aBufferEnd)
    {
      return *pTemp;
    }
    else
    {
      return (*(pTemp-pQueueBuffer->aBufferEnd+pQueueBuffer->aBufferStart));
    }
}

unsigned int Queue_Num (struct QueueBuffer *pQueueBuffer)
{
    unsigned int cnt;
//    bit fEaReg;

//    fEaReg = EA;
//    EA = 0;
    DISABLE_INTERRUPT();
    cnt = pQueueBuffer->mCount;
    ENABLE_INTERRUPT();
//    EA = fEaReg;

    return cnt;
}

void Queue_Clear(struct QueueBuffer *pQueueBuffer)
{
    //bit fEaReg;

    //fEaReg = EA;
    //EA = 0;
    DISABLE_INTERRUPT();
    pQueueBuffer->pIn = pQueueBuffer->pOut = pQueueBuffer->aBufferStart;
    pQueueBuffer->mCount = 0;
    ENABLE_INTERRUPT();
    //EA = fEaReg;
}



    #define TX0_BUFFER_SIZE    32
    #define RX0_BUFFER_SIZE    32
#define DISABLE_RX()    (UCSR0B_Bit4 = 0)
#define ENABLE_RX()   (UCSR0B_Bit4 = 1)
    //modbus constant   
    #define SLAVE_ID                   0x01
    #define MIN_RX_LENGTH            0x08
    #define MAX_RX_LENGTH            0x10   
    #define READ_COIL_STATUS         0x01
    #define READ_INPUT_STATUS          0x02   
    #define READ_HOLDING_REGISTERS   0x03
    #define READ_INPUT_REGISTERS       0x04
    #define WRITE_SINGLE_COIL          0x05
    #define WRITE_SINGLE_REGISTER      0x06
    #define WRITE_MULTIPLE_COILS       0x15
    #define WRITE_MULTIPLE_REGISTERS   0x16
   
    #define TMR2_START()               (TCCR2=0x05)
    #define TMR2_STOP()                (TIFR_Bit6 = 1,TCCR2=0x00)
    #define TMR2_RST()               (TIFR_Bit6 = 1,TCNT2=0x00)
    #define IS_TIMEOUT()               (TIFR_Bit6)

    extern void Usart0_Init(void);
    extern void Usart0_FrameCtrl(void);


      
      #define UART0_RX_PUSH(x)    Queue_Push(&sQueueRx0Buf,x)
      #define UART0_RX_POP()      Queue_Pop(&sQueueRx0Buf)
      #define UART0_RX_READ(x)    Queue_Read(&sQueueRx0Buf,x)
      #define UART0_RX_NUM()      Queue_Num(&sQueueRx0Buf)
      #define UART0_RX_CLR()      Queue_Clear(&sQueueRx0Buf)
   
      #define UART0_TX_PUSH(x)    Queue_Push(&sQueueTx0Buf,x)
      #define UART0_TX_POP()      Queue_Pop(&sQueueTx0Buf)
      #define UART0_TX_READ(x)    Queue_Read(&sQueueTx0Buf,x)
      #define UART0_TX_NUM()      Queue_Num(&sQueueTx0Buf)
      #define UART0_TX_CLR()      Queue_Clear(&sQueueTx0Buf)
   
      struct QueueBuffer sQueueTx0Buf;
      struct QueueBuffer sQueueRx0Buf;
   
      unsigned char g_QueueTx0Buf;
      unsigned char g_QueueRx0Buf;

//
void Usart0_Init(void)
{
    // USART0 initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART0 Receiver: On
    // USART0 Transmitter: On
    // USART0 Mode: Asynchronous
    // USART0 Baud Rate: 4800
    UCSR0A=0x00;
    UCSR0B=0xD8;
    UCSR0C=0x06;
    UBRR0H=0x00;
    UBRR0L=0xCF;

    Queue_Register(&sQueueTx0Buf,g_QueueTx0Buf,TX0_BUFFER_SIZE);
    Queue_Register(&sQueueRx0Buf,g_QueueRx0Buf,RX0_BUFFER_SIZE);
    TMR2_RST();
    TMR2_STOP();
}



void FrameHeaderCheck(void)
{
    if(UART0_RX_NUM() == 1)
    {
      if(UART0_RX_READ(0) == SLAVE_ID)
      {
            TMR2_RST();
            TMR2_START();
      }
      else
      {
            UART0_RX_POP();
      }
    }
}

bool IsFrameTrailer(void)
{
    if(IS_TIMEOUT())
    {
      TMR2_STOP();
      return 1;
    }
    else
    {
      return 0;
    }
}

void Usart0_FrameCtrl(void)
{
    unsigned char rx_length;
    unsigned int regAddr;
    unsigned int regNum;
    unsigned char i;
    unsigned int crc16;

    //if(!IsFrameHeader()) return;
    if(!IsFrameTrailer())return;
    DISABLE_RX();
    rx_length = UART0_RX_NUM();
    if((rx_length < MIN_RX_LENGTH)||(rx_length > MAX_RX_LENGTH))
    {
      ENABLE_RX();
      UART0_RX_CLR();
      return;
    }
    if(CRC16_Calculator(g_QueueRx0Buf,rx_length) != 0)
    {   
      ENABLE_RX();
      UART0_RX_CLR();
      return;
    }
    regAddr = (UART0_RX_READ(2)<<8)|UART0_RX_READ(3);
    regNum= (UART0_RX_READ(4)<<8)|UART0_RX_READ(5);

    switch(UART0_RX_READ(1))
    {
      case READ_HOLDING_REGISTERS:
            UART0_RX_CLR();
            UART0_TX_CLR();
            if((regAddr + regNum) > 6)//register address 0-5 and number = 6
            {
                break;
            }
            UART0_TX_PUSH(SLAVE_ID);
            UART0_TX_PUSH(READ_HOLDING_REGISTERS);
            UART0_TX_PUSH(regNum*2);
            for(i=0; i<regNum; i++)
            {
                UART0_TX_PUSH(LiBATT.bVoltTab>>8);
                UART0_TX_PUSH(LiBATT.bVoltTab);
                //Queue_Push(&sQueueTx0Buf,LiBATT.bVoltTab>>8);
                //Queue_Push(&sQueueTx0Buf,LiBATT.bVoltTab);
            }
            crc16 = CRC16_Calculator(g_QueueTx0Buf,regNum*2+3);
            UART0_TX_PUSH(crc16);
            UART0_TX_PUSH(crc16>>8);
            UDR0 = UART0_TX_POP();
            //Queue_Push(&sQueueTx0Buf,crc16>>8);
            //Queue_Push(&sQueueTx0Buf,crc);
            //UDR0 = Queue_Pop(&sQueueTx0Buf);
            break;
      default:
            break;
    }
}

/*!
* __interrupt void USART0_RXC_ISR (void)
* describe:
*
*
*
*
* \author
*
* \
*/
#pragma vector = USART0_RXC_vect
__interrupt void USART0_RXC_ISR(void)
{
    unsigned char udr;
    udr = UDR0;
    UART0_RX_PUSH(udr);
    FrameHeaderCheck();
    TMR2_RST();
}

/*!
* __interrupt void USART0_TXC_ISR (void)
* describe:
*
*
*
*
* \author
*
* \
*/
#pragma vector = USART0_TXC_vect
__interrupt void USART0_TXC_ISR(void)
{
    if(UART0_TX_NUM() != 0)
    {
      UDR0 = UART0_TX_POP();   
    }
    else
    {
      ENABLE_RX();
    }
}

这里只是展示一下Queue.c的具体应用~~这个程序经调试的~~~

cyberjok 发表于 2009-3-11 16:49:01

没有人感兴趣啊~~

usbfish 发表于 2009-3-11 17:07:02

一句注释都没有,可读性太差了,即便程序再好。

cyberjok 发表于 2009-3-11 17:19:01

呵呵,这个程序很容易实现各种各样的串行通讯协议~~~

zlei 发表于 2009-3-11 18:58:51

好的代码,是不需要太多的注释……

eddia2000 发表于 2009-3-11 19:59:21

顶一个!

jimtien 发表于 2009-3-12 07:46:45

怎么用,楼主给个使用范例才好

cyberjok 发表于 2009-3-12 08:12:02

这里就是一个应用啊~~

lg1318617 发表于 2009-3-13 16:20:23

怎么样与自己的程序结合起来理解呢?

C.Ronaldo 发表于 2009-3-13 16:34:16

可读性太差!

lg1318617 发表于 2009-3-13 16:40:59

我那个注释还可以 谁帮我补补

wisebaby 发表于 2009-3-13 16:52:49

写的不错,不过还真厉害,一个注释没有啊.

cyberjok 发表于 2009-3-13 17:22:06

呵呵,老农的代码有注释的,被我DELETE了~~~

gxy508 发表于 2010-9-6 13:55:26

mark

DoDo915 发表于 2010-9-6 14:59:26

Mark

k10k10k10 发表于 2010-10-7 15:35:38

回复【4楼】zlei
好的代码,是不需要太多的注释……
-----------------------------------------------------------------------

谬论~

358763471 发表于 2010-12-24 10:19:33

你这叫发的啥啊

cuikai12345 发表于 2011-5-22 10:45:51

mark

zheniantou 发表于 2011-5-22 11:04:49

老农是谁?

steven_wangsr 发表于 2011-5-23 12:14:10

modbusrtu 很好,触摸屏通讯可以考虑

xcodes 发表于 2011-5-23 13:19:44

好代码,无需注释
本人一目十行看过来 都能明白个大概

xchkj 发表于 2012-4-5 16:40:00

俺是新手,没有注释,再好的源码,俺看了也晕!

shin555 发表于 2012-4-5 16:46:19

mark~~~~~~

CK345 发表于 2012-4-5 16:52:36

估计没人看{:shy:}{:shy:}

lavenderfr 发表于 2012-8-22 13:57:35

mark~~~~~~~

zhang8198 发表于 2012-9-20 23:39:29

{:smile:}{:smile:}{:smile:}{:smile:}

blueskyzz 发表于 2012-11-26 23:25:34

看看,读代码就头痛

糖烧熊 发表于 2012-11-27 13:01:14

如果能给我们程序框图就容易明白了

foxpro2005 发表于 2012-11-27 21:14:22

是用IAR写的.....
页: [1]
查看完整版本: 发一个老农的通用单片机程序的AVR移槙-ModbusRTU应用