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 */
/********************************************************************* * Function: void CANInitialize(BYTE SJW, * BYTE BRP, * BYTE PHSEG1, * BYTE PHSEG2, * BYTE PROPSEG, * enum CAN_CONFIG_FLAGS flags) * * PreCondition: MCU must be in Configuration mode or else these * values will be ignored. * * Input: SJW - SJW value as defined in 18CXX8 datasheet * (Must be between 1 thru 4) * BRP - BRP value as defined in 18CXX8 datasheet * (Must be between 1 thru 64) * PHSEG1 - PHSEG1 value as defined in 18CXX8 * datasheet * (Must be between 1 thru 8) * PHSEG2 - PHSEG2 value as defined in 18CXX8 * datasheet * (Must be between 1 thru 8) * PROPSEG - PROPSEG value as defined in 18CXX8 * datasheet * (Must be between 1 thru 8) * flags - Value of type enum CAN_CONFIG_FLAGS * * Output: CAN bit rate is set. All masks registers are set * '0' to allow all messages. * Filter registers are set according to flag value. * If (config & CAN_CONFIG_VALID_XTD_MSG) * Set all filters to XTD_MSG * Else if (config & CONFIG_VALID_STD_MSG) * Set all filters to STD_MSG * Else * Set half of the filters to STD while rests to * XTD_MSG. * * Side Effects: All pending transmissions are aborted. * ********************************************************************/ void CANInitialize(BYTE SJW, BYTE BRP, BYTE PHSEG1, BYTE PHSEG2, BYTE PROPSEG, enum CAN_CONFIG_FLAGS config) { BYTE FilterConfig1; BYTE FilterConfig2; // In order to setup necessary config parameters of CAN module, // it must be in CONFIG mode. CANSetOperationMode(CAN_OP_MODE_CONFIG); // Now set the baud rate. CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, config); RXB0CON = config & CAN_CONFIG_MSG_BITS; if ( (config & CAN_CONFIG_DBL_BUFFER_BIT) == CAN_CONFIG_DBL_BUFFER_ON ) RXB0CON_RX0DBEN = 1; RXB1CON = RXB0CON; // Set default filter and mask registers for all receive buffers. CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG); CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG); switch( (config & CAN_CONFIG_MSG_BITS) | ~CAN_CONFIG_MSG_BITS ) { case CAN_CONFIG_VALID_XTD_MSG: FilterConfig1 = CAN_CONFIG_XTD_MSG; FilterConfig2 = CAN_CONFIG_XTD_MSG; break; case CAN_CONFIG_VALID_STD_MSG: FilterConfig1 = CAN_CONFIG_STD_MSG; FilterConfig2 = CAN_CONFIG_STD_MSG; break; default: FilterConfig1 = CAN_CONFIG_STD_MSG; FilterConfig2 = CAN_CONFIG_XTD_MSG; break; } // By default, there will be no mask on any receive filters, // hence filter value of '0' will be ignored. CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1); CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1); CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2); CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2); CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2); CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2); // Restore to Normal mode. CANSetOperationMode(CAN_OP_MODE_NORMAL); }
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) { } }