Dies ist lediglich eine Teillösung des Praktikums CAN-Bus der TU-Ilmenau.
Beteiligt an dem Praktikum sind folgende Personen:
#include "main.h" #include "io.h" #include "CANR_16X.H" #include "Reg164ci.h" //CAN-Suff #define C1CSR *(unsigned int *) 0xef00 #define C1PCIR *(unsigned int *) 0xef02 #define C1BTR *(unsigned int *) 0xef04 #define C1GMS *(unsigned int *) 0xef06 #define C1UGML *(unsigned int *) 0xef08 #define C1LGML *(unsigned int *) 0xef0a #define C1UMLM *(unsigned int *) 0xef0c #define C1LMLM *(unsigned int *) 0xef0e //used for sending #define C1MCR1 *(unsigned int *) 0xef10 #define C1UAR1 *(unsigned int *) 0xef12 #define C1LAR1 *(unsigned int *) 0xef14 #define C1MCFG1 *(unsigned char *) 0xef16 //used for receiving #define C1MCR2 *(unsigned int *) 0xef20 #define C1UAR2 *(unsigned int *) 0xef22 #define C1LAR2 *(unsigned int *) 0xef24 #define C1MCFG2 *(unsigned char *) 0xef26 #define C1BUF20 *(unsigned char *) 0xef27 #define C1BUF21 *(unsigned char *) 0xef28 #define C1BUF22 *(unsigned char *) 0xef29 #define C1BUF23 *(unsigned char *) 0xef2a #define C1BUF24 *(unsigned char *) 0xef2b #define C1BUF25 *(unsigned char *) 0xef2c #define C1BUF26 *(unsigned char *) 0xef2d #define C1BUF27 *(unsigned char *) 0xef2e #define XP0IC *(unsigned int *) 0xf186 #define XP0INT *(unsigned char *) 0x40 //T2 #define T2CON *(unsigned int *) 0xff40 #define T2IC *(unsigned int *) 0xff60 #define T2INT *(unsigned char *) 0x22 #define T2R 1<<6 //RTC #define RTCH *(unsigned int *) 0xf0d6 #define RTCL *(unsigned int *) 0xf0d4 #define T14 *(unsigned int *) 0xf0d2 #define T14REL *(unsigned int *) 0xf0d0 //external adresses #define A1_1 0x10 #define A1_2 0x20 #define A2_1 0x30 #define A2_2 0x40 #define A3_1 0x50 #define A3_2 0x60 #define A4_1 0x70 #define A4_2 0x80 #define DIL_1 0x90 #define DIL_2 0xa0 #define DIL_3 0xb0 #define DIL_4 0xc0 #define SW3_10 0xd0 #define S1_8 0xe0 #define S9_16 0xf0 #define HEX_DSP A4_1 //7-Segment Display first digit for date #define TIME_DSP A4_1 //7-Segment Display first digit for time #define SINTV 1 //sending intervall [1/s] #define BTIME 100000 //key bouncing time [~CLK's] //7-Segment bin to hex unsigned char bintohex[]={ 0x3f, //0 0x06, //1 0x5b, //2 0x4f, //3 0x66, //4 0x6d, //5 0x7d, //6 0x07, //7 0x7f, //8 0x67, //9 0x77, //A 0x7c, //B 0x39, //C 0x5e, //D 0x79, //E 0x71 //F }; //remember last input unsigned char last_input; unsigned char cache_1=0; //7-Segment Display Cache, 8bit size //send 1 byte via can void can_send_byte(unsigned char data) { unsigned char retval; //read CAN mask (outgoing) retval=read_bus(S1_8); //dddd.xxxx -> 0000.xxxx retval=(retval & 0xf); C1LAR1=(retval & 0x07) << 13 | (retval & 0x01); //-- //0 0 0 1 0 1 0 0 //INTPND RXIE TXIE MSGVAL NEWDAT CPUUPD TXRQ RMTPND //0101.1001.1001.0101 C1MCR1=0x5995; //1 1 //NEWDAT CPUUPD //1111.1010.1111.1111 C1MCR1=0xfaff; //write msg 1 byte //xxxx.xxxx.0000.0000+0000.0000.0001.1000 C1MCFG1=data<<8 | 0x18; //CPUUPD=0 //1111.0111.1111.1111 C1MCR1=0xf7ff; C1MCR1=C1MCR1 | 0x2000; //TXRQ von 01 auf 11 setzen, rücksetzen durch Controler, //TXRQ=0 //1110.1111.1111.1111 C1MCR1=0xefff; } //write to bus void write_bus(unsigned char adress, unsigned char data) { DP1L=0xff; //P1 is output P1L=data; P1H=adress; P1H=0x00; } //read from bus unsigned char read_bus(unsigned char adress) { unsigned char retval; DP1L=0x00; //P1 is input P1H=adress; retval=P1L; P1H=0x00; return retval; } //display 1 byte in hex void write_dsp_hex(unsigned char addr_offset, unsigned char value) { write_bus(addr_offset, bintohex[(value & 0x0f)]); write_bus(addr_offset+0x10, bintohex[(value & 0xf0)>>4]); } //simple wait void wait(int loops) { int ac_loops; for (ac_loops=0;ac_loops<=loops;ac_loops++) ; } //managing inputs void input_eval(void) { unsigned char retval; //read CAN mask (incoming) retval=read_bus(S1_8); //xxxx.dddd -> 0000.xxxx retval=(retval & 0xf0)>>4; C1LAR2=(retval & 0x07)<<13 | (retval & 0x01); //-- //switches retval=read_bus(S9_16); if (retval & 0x01) { //timer on T2=19530/SINTV; //clear timer T2CON=T2CON | T2R; } else { //timer off T2CON=T2CON & !T2R; } if (retval & 0x02) { //display cache_1 write_dsp_hex(HEX_DSP,cache_1); } //buttons retval=read_bus(SW3_10); if (last_input!=retval) { last_input=retval; if (retval & 0x01){ cache_1++; wait(BTIME); //avoid key-bouncing } else if (retval & 0x10) { cache_1--; wait(BTIME); //avoid key-bouncing } else if (retval & 0x20) { //can request can_send_byte(cache_1); } } } //initialisation void init(void) { unsigned char i; DP1H=0x11; //P1 is output //setup CAN C1CSR=C1CSR | 0x0041; //CCE+INIT+IE C1BTR=0x34C9; //100kBaud C1CSR=C1CSR & 0xEFBE; //reset CCE+INIT+IE C1MCR2=0x5599; //receive initialisieren C1LAR2=0; //accept from everybody C1UAR2=0; C1MCFG2=0x0060; //6 bytes XP0IC=1<<6; //enable CAN interrupt //clear all digits for (i=A1_1;i<=A4_2;i+=16) write_bus(i,0x00); //RTC setup T14REL=0xff83; //1s //timer T2 setup //T2IR T2IE ILVL GLVL T2IC=1<<6; //enable interrupt //T2UDE=0 -we use internel clk //T2UD=1 -count-down //T2R=1 -start immediately //T2M=0 -timer mode //T2I=7 -19.53kHz CLK //19,530 * 1/19.53kHz -> 1/s T2=19530/SINTV; //8 7 6 543 210 //T2UDE T2UD T2R T2M T2I T2CON=1<<7 | T2R | 7; } void main() { init(); while(1) input_eval(); } #pragma noframe static interrupt( T2INT ) using ( RBANK ) void t2_underflow (void) { //generate out_packet can_send_byte(cache1); T2=19530/SINTV; //rearm the timer } static interrupt( XP0INT ) using ( RBANK ) void can_request (void) { int rtc; if !(C1CSR & 0x10) return; C1CSR=C1CSR & 0xef; //clear recieved flag //got time: hh.mm.ss (6 bytes) //setup RTC //rtc=hh*3600+mm*60+ss /* rtc storage rtc=(C1BUF25*10+C1BUF24)*3600+(C1BUF23*10+C1BUF22)*60+(C1BUF21*10+C1BUF20); RTCH=(rtc & 0xff00)>>8; RTCL=(rtc & 0x00ff); */ if (read_bus(S9_16) & 0x02) return; //display time write_dsp_hex(TIME_DSP, (C1BUF20<10?C1BUF20:10) + (C1BUF21<10?C1BUF21:10)<<4); write_dsp_hex(TIME_DSP+0x20, (C1BUF20<10?C1BUF22:10) + (C1BUF21<10?C1BUF23:10)<<4); write_dsp_hex(TIME_DSP+0x40, (C1BUF20<10?C1BUF24:10) + (C1BUF21<10?C1BUF25:10)<<4); }