#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~~~~
|