打印

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

[复制链接]
1702|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
crazybee|  楼主 | 2009-3-11 13:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    #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[TX0_BUFFER_SIZE];
        unsigned char g_QueueRx0Buf[RX0_BUFFER_SIZE];

//
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[regAddr+i]>>8);
                UART0_TX_PUSH(LiBATT.bVoltTab[regAddr+i]);
                //Queue_Push(&sQueueTx0Buf,LiBATT.bVoltTab[regAddr+i]>>8);
                //Queue_Push(&sQueueTx0Buf,LiBATT.bVoltTab[regAddr+i]);
            }
            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 Huang wenhuo
 * 
 *  
 */
#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 Huang wenhuo
 * 
 *  
 */
#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里省去了,Memory_Malloc~~~~

相关帖子

沙发
crazybee|  楼主 | 2009-3-11 13:17 | 只看该作者

感还不错啊

感还不错啊,呵呵,怎么不见出书啊,如果可以看完整的项目拿讲习解受益的人会很多~~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

149

主题

800

帖子

5

粉丝