#include <includes.h>
#if 1 unsigned int time_temp1; unsigned int time_temp2; #endif #if 1 int flag_temp_past[CAN_FIFO_SIZE]={0}; int temp_high[CAN_FIFO_SIZE]={0}; int past_high[CAN_FIFO_SIZE]={0}; #endif extern unsigned int GAMESCORE; extern unsigned char Image[128],ImageNull[8];
/********************************************************************************************************* VARIABLES *********************************************************************************************************/ static OS_STK GstkStart[TASK_START_STK_SIZE]; /* 启动任务的堆栈 */ static OS_STK GstkKey[TASK_KEY_STK_SIZE]; /* key任务的堆栈 */ //static OS_STK GstkLcd[TASK_LCD_STK_SIZE]; /* Lcd任务的堆栈 */ static OS_STK GstkLed[TASK_LED_STK_SIZE]; /* Led任务的堆栈 */ static OS_STK GstkCAN0[TASK_CAN0_STK_SIZE]; /* Led任务的堆栈 */ static OS_STK GstkVOLUMNDISPLAY[TASK_VOLUMN_DISPALY_STK_SIZE]; /*VOLUMN_DISPALY任务的堆栈*/ static OS_STK GSTKUart0[TASK_UART0_STK_SIZE]; /*uart0 任务的堆栈*/ /********************************************************************************************************* FUNCTION PROTOTYPES 函数声明 *********************************************************************************************************/ static void taskStart (void *parg); /* The start task 启动任务 */ static void taskKey (void *parg); static void taskLcd (void *parg); static void taskLed (void *parg); static void taskCAN0 (void *parg); static void taskvolumndisplay (void *parg); static void taskUart0(void *parg); OS_EVENT *KeyMbox; /* 传递按键信息的邮箱 */ OS_EVENT *VolMbox; /* 传递dB 信息的邮箱 */ OS_EVENT *contrMbox; /* 传递控制信息的邮箱 */
int CANReceiveFIFO(unsigned char *pucData, unsigned long ulSize); int CANTransmitFIFO(unsigned char *pucData, unsigned long ulSize); void oled_Volume_column( unsigned char audio[],int data_num);
struct { // // This holds the information for the data receive message object that is // used to receive data for each CAN controller. // tCANMsgObject MsgObjectRx; // // This holds the information for the data send message object that is used // to send data for each CAN controller. // tCANMsgObject MsgObjectTx; // // Receive buffer. // unsigned char pucBufferRx[CAN_FIFO_SIZE]; // // Transmit buffer. // unsigned char pucBufferTx[CAN_FIFO_SIZE]; // // Bytes remaining to be received. // unsigned long ulBytesRemaining; // // Bytes transmitted. // unsigned long ulBytesTransmitted; // // The current state of the CAN controller. // enum { CAN_IDLE, CAN_SENDING, CAN_WAIT_RX, CAN_PROCESS, } eState; } g_sCAN; //***************************************************************************** // // Send a string to the UART. // //***************************************************************************** void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount); void UART0IntHandler(void);
/********************************************************************************************************* ** Function name: main ** Descriptions: uC/OS main funcation ** input parameters: none ** output parameters: none ** Returned value: none *********************************************************************************************************/
int main (void) { intDisAll(); /* Disable all the interrupts */
OSInit(); /* OS-II 初始化uC/OS-II的内核 */ OSTaskCreate(taskStart,(void *)0,&GstkStart[TASK_START_STK_SIZE-1],TASK_START_PRIO); /*创建启动任务*/ KeyMbox = OSMboxCreate((void *) 0); /* 建立按键信息传输的邮箱 */ VolMbox = OSMboxCreate((void *) 0); /* 建立音量柱信息传输邮箱 */ contrMbox = OSMboxCreate((void *)0); /* 建立控制信息传输的邮箱*/ OSStart(); /* 启动uC/OS-II */ return(0) ; }
/********************************************************************************************************* ** Function name: taskStart ** Descriptions: Start task ** input parameters: *parg ** output parameters: none ** Returned value: none *********************************************************************************************************/ static void taskStart (void *parg) { (void)parg; targetInit(); /* 初始化目标单片机 */ #if OS_TASK_STAT_EN > 0 OSStatInit(); /* 使能统计功能 */ #endif /* 在这里创建其他任务 */ // OSTaskCreate(taskKey,(void *)0,&GstkKey[TASK_KEY_STK_SIZE-1],TASK_KEY_PRIO); /* 创建taskKey任务 */ OSTaskCreate(taskLed,(void *)0,&GstkLed[TASK_LED_STK_SIZE-1],TASK_LED_PRIO); /* 创建taskLed任务 */ OSTaskCreate(taskCAN0,(void *)0,&GstkCAN0[TASK_CAN0_STK_SIZE-1],TASK_CAN0_PRIO); /* 创建taskCAN0任务 */ OSTaskCreate(taskvolumndisplay,(void *)0,&GstkVOLUMNDISPLAY[TASK_VOLUMN_DISPALY_STK_SIZE-1],TASK_VOLUMN_DISPALY_PRIO); /* 创建taskvolumdisplay任务 */ OSTaskCreate(taskUart0,(void * )0,&GSTKUart0[TASK_UART0_STK_SIZE],TASK_UART0_PRIO); while (1) { OSTaskSuspend(OS_PRIO_SELF); /* 启动任务可在这里挂起 */ } }
/* Add the other tasks here*/
/********************************************************************************************************* ** Function name: taskUart0 ** Descriptions: Uart0任务 ** input parameters: *parg ** output parameters: none ** Returned value: none *********************************************************************************************************/ void taskUart0(void * parg) { (void)parg; while(1) { OSTimeDly(OS_TICKS_PER_SEC/5); } } /********************************************************************************************************* ** Function name: taskCAN0 ** Descriptions: CAN0任务 ** input parameters: *parg ** output parameters: none ** Returned value: none *********************************************************************************************************/ static void taskCAN0(void * parg) { int iIdx; int flag_feedback; int flag_error; //unsigned char voltemp[4] ; (void)parg; flag_feedback=1; flag_error=0; g_sCAN.eState = CAN_IDLE; for(iIdx = 0; iIdx < CAN_FIFO_SIZE; iIdx++) { g_sCAN.pucBufferTx[iIdx] = iIdx + 0x1; } g_sCAN.MsgObjectRx.pucMsgData = g_sCAN.pucBufferRx; g_sCAN.ulBytesRemaining = CAN_FIFO_SIZE; CANReceiveFIFO(g_sCAN.pucBufferRx, CAN_FIFO_SIZE); while(1) {OSTimeSet(0); switch(g_sCAN.eState) { case CAN_IDLE: { // // Switch to sending state. // g_sCAN.eState = CAN_SENDING; // // Initialize the transmit count to zero. // g_sCAN.ulBytesTransmitted = 0; // // Schedule all of the CAN transmissions. // CANTransmitFIFO(g_sCAN.pucBufferTx, CAN_FIFO_SIZE); break; } case CAN_SENDING: { // // Wait for all bytes to go out. // if(g_sCAN.ulBytesTransmitted == CAN_FIFO_SIZE) { // // Switch to wait for RX state. // g_sCAN.eState = CAN_WAIT_RX; } break; } case CAN_WAIT_RX: { // // Wait for all new data to be received. // if(g_sCAN.ulBytesRemaining==0) { // // Switch to wait for Process data state. // g_sCAN.eState=CAN_PROCESS; // // Reset the buffer pointer. // g_sCAN.MsgObjectRx.pucMsgData=g_sCAN.pucBufferRx; // // Reset the number of bytes expected. // g_sCAN.ulBytesRemaining = CAN_FIFO_SIZE; } break; } case CAN_PROCESS: { // // Compare the received data to the data that was sent out. // for(iIdx = 0; (iIdx < CAN_FIFO_SIZE)&&(flag_error==0); iIdx++) { if(g_sCAN.pucBufferTx[iIdx] != g_sCAN.pucBufferRx[iIdx]) { // Detected an Error Condition. flag_feedback=0; //RIT128x96x4StringDraw_test("this is a god damned loopback",40,20,15,7); flag_error=1; } } if(flag_feedback) { //RIT128x96x4StringDraw_test("this is a good loopback",40,20,15,7); } else { //RIT128x96x4StringDraw_test("this is a god damned loopback",40,20,15,7); flag_feedback=1; flag_error=0; } OSMboxPost(VolMbox,(void *)g_sCAN.pucBufferRx); //OSTimeSet(0); OSTaskSuspend(OS_PRIO_SELF); // OSTimeDly(OS_TICKS_PER_SEC /200); // time_temp1= OSTimeGet(); // oled_Volume_column(g_sCAN.pucBufferRx,CAN_FIFO_SIZE);//call the OLED with funcation of volum colum //updating the mssage buffer for(iIdx = 0; iIdx < CAN_FIFO_SIZE; iIdx++) { //time_temp1= OSTimeGet(); g_sCAN.pucBufferTx[iIdx]=(char)rand(); } g_sCAN.eState = CAN_IDLE; break; } default: { break; } } // OSTimeDly(OS_TICKS_PER_SEC /100); /* 延时20ms */ } } /********************************************************************************************************* ** Function name: taskvolumndisplay ** Descriptions: OLED display task ** input parameters: *parg ** output parameters: none ** Returned value: none *********************************************************************************************************/ static void taskvolumndisplay (void *parg) { unsigned char err; unsigned char *dataptr; //unsigned char vlotemp[4]={0,0,0,0}; (void)parg; while(1) { dataptr = (unsigned char *)OSMboxPend(VolMbox,0,&err); //OSTimeSet(0); OSTimeDly(2); oled_Volume_column( dataptr,CAN_FIFO_SIZE); //time_temp1 = OSTimeGet(); OSTaskResume(TASK_CAN0_PRIO); // OSTimeDly(OS_TICKS_PER_SEC /100); /* 延时20ms */ } } /********************************************************************************************************* ** Function name: taskKey ** Descriptions: KEY 任务 ** input parameters: *parg ** output parameters: 无 ** Returned value: 无 *********************************************************************************************************/ static void taskKey (void *parg) { INT8U keytemp ; (void)parg; while (1) {
keytemp = keyRead(); /* 读按键信息 */
OSMboxPost(KeyMbox,(void *)keytemp); /* 发送按键信息到消息邮箱 */
OSTimeDly(OS_TICKS_PER_SEC / 5); /* 延时200毫秒 */ } }
/********************************************************************************************************* ** Function name: taskLcd ** Descriptions: LCD 任务 ** input parameters: *parg ** output parameters: 无 ** Returned value: 无 *********************************************************************************************************/ static void taskLcd (void *parg) { INT8U err; INT8U temp; (void)parg;
while (1) {
temp = (INT8U)OSMboxPend(KeyMbox,0,&err); SnakeGame(temp); OSTimeDly(OS_TICKS_PER_SEC / 5); // 延时200毫秒 } }
/********************************************************************************************************* ** Function name: taskLed ** Descriptions: LED 任务 ** input parameters: *parg ** output parameters: 无 ** Returned value: 无 *********************************************************************************************************/ static void taskLed (void *parg) {
(void)parg; while (1) { ledOn(); OSTimeDly(OS_TICKS_PER_SEC /1); /* 延时1000ms */ ledOff(); OSTimeDly(OS_TICKS_PER_SEC /1 ); /* 延时1000ms */ } }
//***************************************************************************** // // This function configures the transmit FIFO and copies data into the FIFO. // //***************************************************************************** int CANTransmitFIFO(unsigned char *pucData, unsigned long ulSize) { int iIdx;
int iCount ; // // This is the message object used to send button updates. This message // object will not be "set" right now as that would trigger a transmission. // g_sCAN.MsgObjectTx.ulMsgID = TRANSMIT_MESSAGE_ID; g_sCAN.MsgObjectTx.ulMsgIDMask = 0;
// // This enables interrupts for transmitted messages. // g_sCAN.MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;
// // Return the maximum possible number of bytes that can be sent in a single // FIFO. // if(ulSize > CAN_FIFO_SIZE) { return(CAN_FIFO_SIZE); }
// // Loop through all eight message objects that are part of the transmit // FIFO. // if(CAN_FIFO_SIZE%8 == 0) iCount = CAN_FIFO_SIZE/8 ; else iCount = CAN_FIFO_SIZE/8+1 ;
for(iIdx = 0; iIdx < iCount; iIdx++) { // // If there are more than eight bytes remaining then use a full message // to transfer these 8 bytes. // if(ulSize > 8) { // // Set the length of the message, which can only be eight bytes // in this case as it is all that can be sent with a single message // object. // g_sCAN.MsgObjectTx.ulMsgLen = 8; g_sCAN.MsgObjectTx.pucMsgData = &pucData[iIdx * 8];
// // Set the MSG_OBJ_FIFO to indicate that this is not the last // data in a chain of FIFO entries. // g_sCAN.MsgObjectTx.ulFlags |= MSG_OBJ_FIFO;
// // There are now eight less bytes to transmit. // ulSize -= 8;
// // Write out this message object. // CANMessageSet(CAN0_BASE, iIdx + 1, &g_sCAN.MsgObjectTx, MSG_OBJ_TYPE_TX); } // // If there are less than or exactly eight bytes remaining then use a // message object to transfer these 8 bytes and do not set the // MSG_OBJ_FIFO flag to indicate that this is the last of the entries // in this FIFO. // else { // // Set the length to the remaining bytes and transmit the data. // g_sCAN.MsgObjectTx.ulMsgLen = ulSize; g_sCAN.MsgObjectTx.pucMsgData = &pucData[iIdx * 8];
// // Write out this message object. // CANMessageSet(CAN0_BASE, iIdx + 1, &g_sCAN.MsgObjectTx, MSG_OBJ_TYPE_TX); } } return(0); }
//***************************************************************************** // // This function configures the receive FIFO and should only be called once. // //***************************************************************************** int CANReceiveFIFO(unsigned char *pucData, unsigned long ulSize) { int iIdx; int iCount ;
if(ulSize > CAN_FIFO_SIZE) { return(CAN_FIFO_SIZE); } // // Configure the receive message FIFO to accept the transmit message object. // g_sCAN.MsgObjectRx.ulMsgID = RECEIVE_MESSAGE_ID; g_sCAN.MsgObjectRx.ulMsgIDMask = 0;
// // This enables interrupts for received messages. // g_sCAN.MsgObjectRx.ulFlags = MSG_OBJ_RX_INT_ENABLE; // // Remember the beginning of the FIFO location. // g_sCAN.MsgObjectRx.pucMsgData = pucData; // // Transfer bytes in multiples of eight bytes. // if(CAN_FIFO_SIZE%8 == 0) iCount = CAN_FIFO_SIZE/8 ; else iCount = CAN_FIFO_SIZE/8+1 ;//向下取整规则
for(iIdx=0; iIdx < iCount; iIdx++) { // if(iIdx == 1) // g_sCAN.MsgObjectRx.ulMsgID = 0x89; // If there are more than eight remaining to be sent then just queue up // eight bytes and go on to the next message object(s) for the // remaining bytes. // if(ulSize > 8) { // // The length is always eight as the full buffer is divisible by 8. // g_sCAN.MsgObjectRx.ulMsgLen = 8;
// // There are now eight less bytes to receive. // ulSize -=8; // // Set the MSG_OBJ_FIFO to indicate that this is not the last // data in a chain of FIFO entries. // g_sCAN.MsgObjectRx.ulFlags |= MSG_OBJ_FIFO; // // Make sure that all message objects up to the last indicate that // they are part of a FIFO. //. CANMessageSet(CAN0_BASE, iIdx + iCount + 1, &g_sCAN.MsgObjectRx , MSG_OBJ_TYPE_RX); } else { // // Get the remaining bytes. // g_sCAN.MsgObjectRx.ulMsgLen = ulSize; // // Clear the MSG_OBJ_FIFO to indicate that this is the last data in // a chain of FIFO entries. // g_sCAN.MsgObjectRx.ulFlags &= ~MSG_OBJ_FIFO; // // This is the last message object in a FIFO so don't set the FIFO // to indicate that the FIFO ends with this message object. // CANMessageSet(CAN0_BASE, iIdx + iCount + 1, &g_sCAN.MsgObjectRx, MSG_OBJ_TYPE_RX); } } return(0); } //***************************************************************************** // // The oled_Volume_column interface. // //*****************************************************************************
void oled_Volume_column( unsigned char audio[],int data_num)
{ unsigned long ulRow,number,ulWidth;
unsigned char ucData[14]={0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; unsigned char ucData_1[14]={0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88}; ulWidth=16; for(number=0;number<data_num;number++) { temp_high[number]=((audio[number])%96); if(flag_temp_past[number]==0) { // RIT128x96x4Init(350000); //350000 past_high[number]=temp_high[number]; flag_temp_past[number]=1; for(ulRow=0;ulRow<temp_high[number];ulRow++) { RIT128x96x4ImageDraw(ucData,(number+1)*26-5,96-ulRow,ulWidth,Volum_pre_change ); } } else { { for(ulRow=0;ulRow<temp_high[number];ulRow++) { RIT128x96x4ImageDraw(ucData,(number+1)*26-5,96-ulRow,ulWidth,Volum_pre_change ); } for(ulRow=temp_high[number];ulRow<96;ulRow++) //ulRow<past_high[number]; { RIT128x96x4ImageDraw(ucData_1,(number+1)*26-5,96-ulRow,ulWidth,Volum_pre_change ); } } } past_high[number]=temp_high[number]; } }
void CANIntHandler(void) { unsigned long ulStatus; int iCount ; int iFlag = 0x00 ; // // Find the cause of the interrupt, if it is a status interrupt then just // acknowledge the interrupt by reading the status register. // ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // // The first eight message objects make up the Transmit message FIFO. // // if(CAN_FIFO_SIZE%8 == 0) iCount = CAN_FIFO_SIZE/8 ; else { iCount = CAN_FIFO_SIZE/8+1 ; iFlag = 0x0a ; } if(ulStatus <= iCount)//this judgement indicates that it's a transmitted interrupt { // // Increment the number of bytes transmitted. // if(ulStatus == iCount && iFlag == 0xa) { g_sCAN.ulBytesTransmitted += CAN_FIFO_SIZE%8 ; } else g_sCAN.ulBytesTransmitted += 8 ; } // // The second eight message objects make up the Receive message FIFO. // else if((ulStatus > iCount) && (ulStatus <= 2*iCount)) //this judgement indicates that it's a received interrupt { // // Read the data out and acknowledge that it was read. // CANMessageGet(CAN0_BASE, ulStatus, &g_sCAN.MsgObjectRx, 1); //s // Advance the read pointer. // g_sCAN.MsgObjectRx.pucMsgData += 8; // // Decrement the expected bytes remaining. // g_sCAN.ulBytesRemaining -= g_sCAN.MsgObjectRx.ulMsgLen; } else { // // This was a status interrupt so read the current status to // clear the interrupt and return. // CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); } // // Acknowledge the CAN controller interrupt has been handled. // CANIntClear(CAN0_BASE, ulStatus); }
//***************************************************************************** // // The UART interrupt handler. // //***************************************************************************** void UART0IntHandler(void) { unsigned long ulStatus; // // Get the interrrupt status. // ulStatus = UARTIntStatus(UART0_BASE, true); // // Clear the asserted interrupts. // UARTIntClear(UART0_BASE,ulStatus); // // Loop while there are characters in the receive FIFO. // while(UARTCharsAvail(UART0_BASE)) { // // Read the next character from the UART and write it back to the UART. UARTCharPut(UART0_BASE,UARTCharGet(UART0_BASE)); } }
//***************************************************************************** // // Send a string to the UART. // //***************************************************************************** void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount) { // // Loop while there are more characters to send. // while(ulCount--) { // // Write the next character to the UART. // UARTCharPut(UART0_BASE, *pucBuffer++); } }
总的来说就是建立了四个人任务,1个CAN,1个SPI,一个LED,和一个uart,将uart的优先级设置为此四个任务中最高的时候,一切正常,否则程序会在切换到UART之前进入那个 “不希望发生的中断造成的死循环!”
请求答疑!!!!
|