Rechnernetze der Prozessdatenverarbeitung - CAN Bus

Dies ist lediglich eine Teillösung des Praktikums CAN-Bus der TU-Ilmenau.

Beteiligt an dem Praktikum sind folgende Personen:

main.c

#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);
 
}
 
wiki/study/prakt/rndpv.txt · Last modified: 2005/06/02 21:22 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki