void CANbus_setup() { char SJW, BRP, Phase_Seg1, Phase_Seg2, Prop_Seg, txt[4]; unsigned short init_flag; long mask; /* CAN BUS Timing Parameters */ SJW = 1; BRP = 1; Phase_Seg1 = 6; Phase_Seg2 = 7; Prop_Seg = 6; init_flag = _CAN_CONFIG_SAMPLE_THRICE & _CAN_CONFIG_PHSEG2_PRG_ON & _CAN_CONFIG_STD_MSG & _CAN_CONFIG_DBL_BUFFER_ON & _CAN_CONFIG_VALID_STD_MSG & _CAN_CONFIG_LINE_FILTER_OFF; /* Initialise CAN module */ CANInitialize(SJW, BRP, Phase_Seg1, Phase_Seg2, Prop_Seg, init_flag); /* Set CAN CONFIG mode */ CANSetOperationMode(_CAN_MODE_CONFIG, 0xFF); mask = -1; /* Set all MASK1 bits to 1's */ CANSetMask(_CAN_MASK_B1, mask, _CAN_CONFIG_STD_MSG); /* Set all MASK2 bits to 1's */ CANSetMask(_CAN_MASK_B2, mask, _CAN_CONFIG_STD_MSG); /* Filter 0x50 (temp node) and 0x202 (rear node) only */ CANSetFilter(_CAN_FILTER_B1_F1,0x202,_CAN_CONFIG_STD_MSG); CANSetFilter(_CAN_FILTER_B1_F2,0x50,_CAN_CONFIG_STD_MSG); /* Now set CAN module to NORMAL mode, as setup done. */ CANSetOperationMode(_CAN_MODE_NORMAL, 0xFF); }/* The CANbus is now set up and ready for use */
void CANTask(void *pvParameters) { printf("Start CAN Initialization\n\r"); CANInitialize(); printf("CAN Initialized\n\r"); CANVelMeasurementTest(); portTickType lastExecutionTime = xTaskGetTickCount(); for (;;) { //Use 10 ms! Works bad with 20ms for some mysterious reason DelayUntilTime(&lastExecutionTime, CANTaskT); CANGetNewVelocityMeasurements(); //CANGetNewCurrentMeasurements(); } }
void configurazione(void) { CANInitialize(4, 6, 5, 1, 3, CAN_CONFIG_LINE_FILTER_OFF & CAN_CONFIG_SAMPLE_ONCE & CAN_CONFIG_ALL_VALID_MSG & CAN_CONFIG_DBL_BUFFER_ON); LATA = 0x00; TRISA = 0xff; //ALL IN LATB = 0x00; TRISB = 0xff; //RB1 e RB2 INPUT LATC = 0x00; TRISC = 0xff; LATD = 0x00; TRISD = 0x00; //OUTPUT LCD LATE = 0x00; TRISE = 0xFF; PIR3bits.RXB1IF = 0; //azzera flag interrupt can bus buffer1 PIR3bits.RXB0IF = 0; //azzera flag interrupt can bus buffer0 IPR3bits.RXB1IP = 1; //interrupt alta priorità per can IPR3bits.RXB0IP = 1; //interrupt alta priorità per can PIE3bits.RXB1IE = 1; //abilita interrupt ricezione can bus buffer1 PIE3bits.RXB0IE = 1; //abilita interrupt ricezione can bus buffer0 }
void main(void) { WDTCON = 0x00; //TRISA = 0xC0; TRISB = 0xFF; TRISC = 0xFF; UartTxCnt = 0; UartRxCnt = 0; CanRxBuff = 0; UartTxBuff = 0; // Initialize TIMER0 INTCON2bits.TMR0IP = 0; //Timer0 INT-LOW OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_128); // 24Mhz/4/128 := 46875 -> 65536 - 46875 = 18661 WriteTimer0(49911); // 1Sec interval at 8Mhz /* EEAddres.Bytes[0] = Read_b_eep(0); EEAddres.Bytes[1] = Read_b_eep(1); EEAddres.Bytes[2] = Read_b_eep(2); EEAddres.Bytes[3] = Read_b_eep(3); EEAddres.SE_ID = 0x20123456; */ // Initialize CAN module with no message filtering // 8MHz Fosc 250Kb/s // 8MHz -> 2MHz @ 250Khz = 8Tq (1+2+3+2) CANInitialize(1 ,0x02 ,2 ,3 ,2 , CAN_CONFIG_VALID_XTD_MSG); //256kb at 8Mhz crystal /*CANSetOperationMode(CAN_OP_MODE_CONFIG); CANSetFilter(CAN_FILTER_B1_F1, Can_bootF.SE_ID, CAN_CONFIG_XTD_MSG); CANSetFilter(CAN_FILTER_B1_F2, Can_nodeF.SE_ID, CAN_CONFIG_XTD_MSG); CANSetMask(CAN_MASK_B1, Can_Mask1.SE_ID, CAN_CONFIG_XTD_MSG); CANSetFilter(CAN_FILTER_B2_F1, Can_addrLO.SE_ID, CAN_CONFIG_XTD_MSG); CANSetMask(CAN_MASK_B2, Can_Mask2.SE_ID, CAN_CONFIG_XTD_MSG); */ CANSetOperationMode(CAN_OP_MODE_NORMAL); //ADC configuration //reference is connected to A0 //voltage output connected to A1 LATA = 0x00; PORTA=0; TRISA=0xFF; //A port as input ADCON1 = 0b00111101;//VSS,VDD ref. AN0 analog only //ADCON2 = 0b00001001;//ADCON2 setup: Left justified, Tacq=2Tad, Tad=2*Tosc (or Fosc/2) ADCON2 = 0b10101011; ADCON0bits.ADON = 0x01;//Enable A/D module INTCONbits.GIE = 1; //enable global interrupts Tcombo int2byte; UartRx_Msg.Data[4] = 1;//CanRx_Msg.Data[0]; UartRx_Msg.Data[5] = 2;//CanRx_Msg.Data[0]; UartRx_Msg.Data[6] = 3;//CanRx_Msg.Data[7]; UartRx_Msg.Data[7] = 4;//CanRx_Msg.Data[7]; while(1) { ClrWdt(); /********************************/ //cobtinuasly reading of current*/ /********************************/ //ADC chanel A0 - voltage ADCON0bits.CHS0 = 0;//clear ADCON0 to select channel 0 (AN0) ADCON0bits.CHS1 = 0;//clear ADCON0 to select channel 0 (AN0) ADCON0bits.CHS2 = 0;//clear ADCON0 to select channel 0 (AN0) ADCON0bits.CHS3 = 0;//clear ADCON0 to select channel 0 (AN0) Delay100TCYx (2); ADCON0bits.GO = 1; while (ADCON0bits.GO); //wait for conversion current_ad_value=ADRES; ClrWdt(); Delay100TCYx (2); //ADC chanel A1 - rederence ADCON0bits.CHS0 = 1; //select channel 1 (AN1) Delay100TCYx (2); ADCON0bits.GO = 1; while (ADCON0bits.GO); //wait for conversion reference_ad_value= ADRES; //delta ADC = reference votlatge - real voltage //we filter it thru buffer count++; if(count>=100) count=0; delta_ad[count] = reference_ad_value-current_ad_value; if (UTicTac >= 1) { UTicTac = 0; //current conversion //I=1.6V*200/1024*0.625 * delta_ad ==0.52083333333333333333333333333333 *delta_ad //reference votlatge - real voltage current=0; for(char i=0;i<100;i++){ current+=delta_ad[i]; } //current *= 0.0052083; //above formula /100 current *= 0.00463541637; //above formula with correction factor of 0.89 int2byte.Int = (int)current; UartRx_Msg.Data[0] = int2byte.Char[1]; UartRx_Msg.Data[1] = int2byte.Char[0]; //capcity capacity += (current/3600); int2byte.Int=(int)capacity; UartRx_Msg.Data[2] = int2byte.Char[1]; UartRx_Msg.Data[3] = int2byte.Char[0]; // CAN adresses UartRx_Msg.Address.SE_ID = 0x010000F2; CANSendMessage(UartRx_Msg.Address.SE_ID, &UartRx_Msg.Data[0], 8, CAN_TX_PRIORITY_0 & CAN_TX_XTD_FRAME & CAN_TX_NO_RTR_FRAME); ClrWdt(); } if (CANIsRxReady()) // Check for CAN message { CANReceiveMessage(&CanRx_Msg.Address.SE_ID, &CanRx_Msg.Data[0], &CanRx_Msg.Length.Len, &RecFlags); // if ( RecFlags & CAN_RX_OVERFLOW ) // { // // Rx overflow occurred; handle it // } if ( RecFlags & CAN_RX_INVALID_MSG ) { // Invalid message received; handle it } else { /* if ( RecFlags & CAN_RX_RTR_FRAME ) { // RTR frame received //UartRx_Msg.Data[6]++; CanRxBuff++; if (CanRxBuff >= BuffNO) CanRxBuff = 0; } else { // Regular frame received. //UartRx_Msg.Data[7]++; CanRxBuff++; if (CanRxBuff >= BuffNO) CanRxBuff = 0; }*/ if(CanRx_Msg.Address.SE_ID==0x020000F2) capacity=(char)CanRx_Msg.Data[0]; /*UartRx_Msg.Data[4] = CanRx_Msg.Data[0]; UartRx_Msg.Data[5] = CanRx_Msg.Data[1]; UartRx_Msg.Data[6] = CanRx_Msg.Data[6]; UartRx_Msg.Data[7] = CanRx_Msg.Data[7];*/ } // if ( RecFlags & CAN_RX_XTD_FRAME ) // { // // Extended Identifier received; handle it // } // else // { // // Standard Identifier received. // } // // Extract receiver filter match, if it is to be used // RxFilterMatch = RecFlags & CAN_RX_FILTER_BITS; } // Process received message /* if ((BusyUSART() == 0) && (UartSync == 1)) { if (UartTxCnt > 0) // Preveri èe posiljamo CAN telegram na UART { WriteUSART(CanRx_Msg[UartTxBuff].Array[UartTxCnt]); // Pošlji znak UartTxCnt++; // poveèaj stevec za naslednji znak if ((UartTxCnt) >= (J1939_MSG_LENGTH + J1939_DATA_LENGTH)) // Preveri èe je zadni znak { UartTxCnt = 0; // Postavi na prvi znak UartTxBuff++; // Premakni na novi Buffer if (UartTxBuff >= BuffNO) // Preveri da nismo cez mejo UartTxBuff =0; } } else { if (CanRxBuff != UartTxBuff) { WriteUSART(CanRx_Msg[UartTxBuff].Array[UartTxCnt]); // Pošlji ga na UART UartTxCnt++; // Poveèaj števec na naslednji znak } } } if (UartRxCnt >= (J1939_MSG_LENGTH + J1939_DATA_LENGTH)) // Ali imamo vse znake. { if (CANIsTxReady()) // Preveri ali ja CAN prost { // void CANSendMessage(unsigned long id, BYTE *Data, BYTE DataLen enum CAN_TX_MSG_FLAGS MsgFlags); CANSendMessage(UartRx_Msg.Address.SE_ID, &UartRx_Msg.Data[0], 8, CAN_TX_PRIORITY_0 & CAN_TX_XTD_FRAME & CAN_TX_NO_RTR_FRAME); UartRxCnt = 0; // Pripravi za sprejem novega telegrama iz UART-a LATAbits.LATA5 = !LATAbits.LATA5; } } if DataRdyUSART() // Preveri ali v UART èaka nov znak { UTicTac = 0; tp_char = ReadUSART(); // Preber znak v polje if (UartSync) { UartRx_Msg.Array[UartRxCnt] = tp_char; UartRxCnt++; // in poveèaj stevec prebranih znakov iz UART-a } else { if (tp_char == '#') UartSync = 1; } } if (UTicTac > 5) // Èe je števec èez mejo, telegram ni veljeven { UartRxCnt = 0; // Postavi na prvi znak v telegramu UTicTac = 0; }*/ } // Do this forever }
/////*PROGRAMME PRINCIPAL*///// void main (void) { // Initialisations. ADCON1 = 0x0F; ADCON0 = 0; WDTCON = 0; // Configurations. TRISA = 0b11101111; TRISB = 0b11111111; TRISC = 0b00111111; ADCON1 = 0b00001011; // Configuration ADC de AN0 à AN3 // Timer de rafraichissement des BP et de chronométrage des sonars OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_2); // 38Hz INTCON2bits.TMR0IP = 0; // priorité basse, car les pulses sonars prennent du temps // Il faut laisser 50ms (20Hz) entre deux débordements (limite des sonars). // Mais on alterne les salves donc 38Hz est parfait. // Du coup on ne vérifie pas les boutons plus souvent, mais pas grave. // Les sharps actualisent leur valeur toutes les 40ms, mais on va les // échantillonner plus vite (38Hz), tant mieux si on choppe les nouvelles // valeurs rapidement. // Interruptions sur les pins "Echo output" des sonars (AN0 et AN1). // OpenRBxINT faits à la main (sauf pullup, par défaut). /*OpenADC(ADC_FOSC_4 // Tosc < 5.7 MHz. & ADC_LEFT_JUST // On pourra ignorer l'octet de poid faible (2 bits non nuls). & ADC_20_TAD, // 15µs * 5 MHz / 4 [cf ci-dessus] = 18.75 Tosc ADC_CH0 // Changé par le timer de toute façon. & ADC_INT_ON & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0b00001011); // Pins analogiques pour AN0 à AN3. // Interruption ADC. IPR1bits.ADIP = 0; // Priorité basse. PIE1bits.ADIE = 1; // Activée. PIR1bits.ADIF = 0; //*/ // Configuration du CAN. CANInitialize(1, 5, 7, 6, 2, CAN_CONFIG_VALID_STD_MSG); // Configuration des masques et filtres. CANSetOperationMode(CAN_OP_MODE_CONFIG); // Set Buffer 1 Mask value. CANSetMask(CAN_MASK_B1, 0b00100000000, CAN_CONFIG_STD_MSG); CANSetMask(CAN_MASK_B2, 0xFFFFFF, CAN_CONFIG_STD_MSG); // Set Buffer 1 filter values. CANSetFilter(CAN_FILTER_B1_F1, 0b00100000000, CAN_CONFIG_STD_MSG); CANSetFilter(CAN_FILTER_B1_F2, 0b00100000000, CAN_CONFIG_STD_MSG); // Set CAN module into Normal mode. CANSetOperationMode(CAN_OP_MODE_NORMAL); // Interruption Buffer 0. IPR3bits.RXB0IP = 0; // Priorité basse. PIE3bits.RXB0IE = 1; // Activée. PIR3bits.RXB0IF = 0; // Signal de démarrage. led = 0; for(i = 0; i < 20; i++) { led = led ^ 1; DelayMS(50); } // Autorisation des interruptions. RCONbits.IPEN = 1; INTCONbits.GIEH = 1; INTCONbits.GIEL = 1; while(1) { } }