Hi guys
sorry my message box was empyty. I am working on Freescale 16-bit microcontroller MC9S12XHz512.I am tryinyg to implement CAN on it. But only its reception part is working.I want to transmit data on CAN.
Does anyone know what are the register setting for that or is there any sample code available n where?If anyone has any idea Plz reply me as soon as possible.
SARY
Solved! Go to Solution.
hi
CANTx flag and register are fine .nway I have solved my problem .Now I can transmit data whenever I want.Thanks for ur reply.NowI can mark it as solved.
hi Kef
thanks for the reply.But no that bit is zero.here is some part of code.
CAN0CTL0_INITRQ = 1;
while((CAN0CTL1&1)==0);
CAN0CTL1 = 0xC0; //Enable MSCAN with bus clk, wake up enable
CAN0BTR0 = 0x04; //SJW=1 and Tq freq=4MHz
CAN0BTR1 = 0x1C; //1bit time =(PS*(1+13+2))/fclk =(5*16)/20M=4us =250 kbps (1bit=16Tq)
CAN0IDAC = 0x00; //Two 32 bit accept filters
//Bank 1
CAN0IDAR0 = 0;
CAN0IDAR1 = 0x08;//Match IDE bit=1 to support only EXT ID
CAN0IDAR2 = 0;
CAN0IDAR3 = 0; //Match RTR bit=0 to support only DATA FRAME
//Bank 2
CAN0IDAR4 = 0;
CAN0IDAR5 = 0x08;//Match IDE bit=1
CAN0IDAR6 = 0;
CAN0IDAR7 = 0; //Match RTR bit=0
//if MR_bit=1, don't check corres. AR_bit and accept that bit always
//if MR_bit=0, check corres. AR_bit and accept that bit only if it matches
//Bank 1
CAN0IDMR0 = 0xFF;
CAN0IDMR1 = 0xF7;//Match IDE bit for accepting Extended ID only (no std frame)
CAN0IDMR2 = 0xFF;
CAN0IDMR3 = 0xFE;//Match RTR bit for accepting DATA frames only (no remote frame)
//Bank 2
CAN0IDMR4 = 0xFF;
CAN0IDMR5 = 0xF7;
CAN0IDMR6 = 0xFF;
CAN0IDMR7 = 0xFE;
CAN0CTL0 = 0x00; /* Exit initialization mode request */
while (CAN0CTL1_INITAK)
; /* Wait for normal mode */
while(!(CAN0CTL0_SYNCH))
; /* Wait for CAN synchronization */
CAN0RFLG_RXF = 1; /* Clear receiver flags */
CAN0RIER_RXFIE = 1;
I dont know but may be transmit interrupt has to be defined at some address .I dont know where to define that.Right now i have defined it like
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 5 knopp()
{
unsigned char u8TxBuffer = {0},u8Length=8;
unsigned long u32ID=0x18FEF100;
unsigned char u8TxData[8]={ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18};
unsigned char u8Index;
// if (!CAN0TFLG) /* Retrun if Transmit Buffer is full */
// return ERR_BUFFER_FULL;
CAN0TBSEL = CAN0TFLG; /* Select lowest empty buffer */
u8TxBuffer = CAN0TBSEL; /* Backup selected buffer */
*((unsigned long *) ((unsigned long)(&CAN0TXIDR0)))= u32ID; /* Load Id to IDR Registers */
/* Load data to Data Segment Registers */
for (u8Index=0;u8Index<u8Length;u8Index++) {
*(&CAN0TXDSR0 + u8Index) = u8TxData[u8Index];
}
CAN0TXDLR = 8; /* Set Data Length Code */
CAN0TXTBPR = 1; /* Set Priority */
CAN0TFLG = u8TxBuffer; /* Start transmission */
while ( (CAN0TFLG & u8TxBuffer) != u8TxBuffer);
/* Wait for Transmission completion */
}
for testing purpose and i am forcefully setting CAN0TFLG flag in main loop.should it work.
waitig for reply
SARY
I dont know but may be transmit interrupt has to be defined at some address .I dont know where to define that.Right now i have defined it like
You could set CAN0 TX interrupt vector like this:
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt VectorNumber_Vcan0tx knopp(void)
{
...
}
#pragma CODE_SEG DEFAULT
What's inside your knopp routine should force CAN module to send message.
I have tried dat but it does not got to the interrupt function.What I m doing now is I hav defined a function like
int interrupt_5_knopp()
n wen I want to tx data on CAN I just call these function.Though its working but is it the right method?n also if I want to test some request type of PGN to which an Engine ECU should respond .How can I test that wd no ECUs in my Lab.I mean wat data should a cAT analzing tool must send.
I just want to check dat both tx n rx part of CAN should work fine n simultaneously.
SARY
Hi Kef
I am facing one problem with the code .I am sending PGN no. as unsigned long and putting it in the register like
u32ID=0x18FEF100;
*((unsigned long *) ((unsigned long)(&CAN0TXIDR0)))= u32ID;
Is it right method or I hav to make some conversions.
because PGN No. I m recieving on CAT(I+ME) software tool is different it is 0x031F7880.
what may be the problem ,in the coding part or CAN software tool.
do reply if you have any idea.
SARY
Who is PGN and what is dat, n, hav etc? I don't understand. Well, maybe it's because English is not my native language.
Did you enable CAN TX interrupt? If not, then no wonder your ISR doesn't get called.
You wrote that calling int interrupt_5_knopp() works. Then you should mark this thread as solved or change somehow the subject line. Is right to call knopp directly or to convert it to ISR, it's up to you and your program requirements. CAN TX ISR is neede only when it's necessary to stream few CAN messages. You may wait in your main thread, you may also put messages to FIFO queue and let CAN TX interrupt to send data from FIFO.
I don't know either what's in your u32ID variable. Is it CAN ID or CAN ID converted to MSCAN CANIDRx registers ID bits layout. If you won't to know how to convert CAN ID to MSCAN CANIDRx bits, then you should open your S12XHZ datasheet and study
Figure 14-25. Receive/Transmit Message Buffer — Standard Identifier Mapping
and
Figure 14-24. Receive/Transmit Message Buffer — Extended Identifier Mapping
It's a pity figure 14-24 is not as clear as figure 14-25. But if you compare contents of IDR0-IDR3 registers in both figures, then you should understand how to calculate IDRx bits from CAN ID when trasmitting and how to calculate CAN ID from IDRx bits on receive.
Regards
hi
PGN mean parameter group number or id of a CAN message.I have enabled all CAN Tx interrupt .But its not working.
I cant mark it as slolved ,because still I am not able to receive correct PGN(CAN Identifier) which I am transmitting.I want to transmit Trip Reset command and I am sending it in a unsigned long format .
i.e.
*((unsigned long*) ((unsigned long)(&CAN0TXIDR0)))= 0x18DE0000;
But what I have received on my CAT tool(CAN analzing tool ) is different.I cant test that on Engine ECU right now.So I just want to know wats the problem.
Is the CAT tool is showing wrong data or coding part has some problem.
I hope now you understand my problem.
SARY
First you say you can't transmit. Then you say you can trasmit, but can't trigger TX interrupt. Can = solved, isn't it? :smileyhappy:
Like I wrote already, you should check CANxxIDRx ID bits layout. Those figures explain where every CAN message ID bit goes in CANxxIDRx registers and in CAN acceptance registers. Of course when you want to send message with some ID, you can't simply
*((unsigned long*) &CAN0TXIDR0)= ID;
It should be something like this (not tested):
CAN0TXIDR0 = (char)(ID >> 21);
CAN0TXIDR1 = (char) (
((ID >> (18-5)) & 0xE0)
| ((ID >> 15) & 7)
| 0x18
);
CAN0TXIDR2 = (char)(ID >> 7);
CAN0TXIDR3 = (char)(ID << 1);
hi
CANTx flag and register are fine .nway I have solved my problem .Now I can transmit data whenever I want.Thanks for ur reply.NowI can mark it as solved.