Jump to content

    
Sign in to follow this  
Chip115

Stellaris LM3S9B96, CAN

Recommended Posts

Всем привет! Пытаюсь заставить работать CAN 0 , но пока все четно ((

Да и не совсем пока я разобрался с stellarisware. помогите осилить )

Как я понимаю, надо юзасть can.c и can.h из driverlib.

Вот такие ф-ции там есть

 

//*****************************************************************************
extern void CANBitTimingGet(unsigned long ulBase, tCANBitClkParms *pClkParms);
extern void CANBitTimingSet(unsigned long ulBase, tCANBitClkParms *pClkParms);
extern unsigned long CANBitRateSet(unsigned long ulBase,
							   unsigned long ulSourceClock,
							   unsigned long ulBitRate);
extern void CANDisable(unsigned long ulBase);
extern void CANEnable(unsigned long ulBase);
extern tBoolean CANErrCntrGet(unsigned long ulBase, unsigned long *pulRxCount,
						  unsigned long *pulTxCount);
extern void CANInit(unsigned long ulBase);
extern void CANIntClear(unsigned long ulBase, unsigned long ulIntClr);
extern void CANIntDisable(unsigned long ulBase, unsigned long ulIntFlags);
extern void CANIntEnable(unsigned long ulBase, unsigned long ulIntFlags);
extern void CANIntRegister(unsigned long ulBase, void (*pfnHandler)(void));
extern unsigned long CANIntStatus(unsigned long ulBase,
							  tCANIntStsReg eIntStsReg);
extern void CANIntUnregister(unsigned long ulBase);
extern void CANMessageClear(unsigned long ulBase, unsigned long ulObjID);
extern void CANMessageGet(unsigned long ulBase, unsigned long ulObjID,
					  tCANMsgObject *pMsgObject, tBoolean bClrPendingInt);
extern void CANMessageSet(unsigned long ulBase, unsigned long ulObjID,
					  tCANMsgObject *pMsgObject, tMsgObjType eMsgType);
extern tBoolean CANRetryGet(unsigned long ulBase);
extern void CANRetrySet(unsigned long ulBase, tBoolean bAutoRetry);
extern unsigned long CANStatusGet(unsigned long ulBase, tCANStsReg eStatusReg);

 

Хочу просто передать сообщение не важнно какое и не важно с каким идентификатором. Просто для начала хочу понять как эта штука работает. А саму передачу буду наблюдать по осциллографу.

Я так думаю, что вначале юзаются эти функции

 

extern void CANEnable(unsigned long ulBase);
extern void CANInit(unsigned long ulBase);

А как быть с передачей сообщения? как понимаю, надо юзать эту функцию CANMessageSet, но что то до меня туго доходит :(

Помогите разобраться. Может у кого есть пример для этого МК?

Edited by IgorKossak
[codebox]

Share this post


Link to post
Share on other sites

Вот тут на основании примера из IAR что то написал. Не работает (( Не могу понять что не так ((

Помогите разобраться ))

//*****************************************************************************
//
// gpio.c - API for GPIO ports
//
// Copyright © 2005-2012 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
// 
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
// 
// This is part of revision 8555 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************

//*****************************************************************************
//
//! \addtogroup gpio_api
//! @{
//
//*****************************************************************************

#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include <stdio.h>
#include "utils/uartstdio.h"
#include "inc/hw_can.h"
#include "driverlib/can.h"

#define CAN_IDLE 0
#define CAN_SENDING 1
#define CAN_WAIT_RX 2
#define CAN_PROCESS 3



//
// Size of the FIFOs allocated to the CAN controller.
//
#define CAN_FIFO_SIZE		   32

//
// Message object used by the transmit message FIFO.
//
#define TRANSMIT_MESSAGE_ID	 11

//
// Message object used by the receive message FIFO.
//
#define RECEIVE_MESSAGE_ID	  8

//
// The number of FIFO transfers that cause a toggle of the LED.
//
#define TOGGLE_RATE			 100

//
// The CAN bit rate.
//
#define CAN_BITRATE			 250000



#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif


//
// This structure holds all of the state information for the CAN transfers.
//
struct
{
//
// This holds the information for the data receive message object that is
// used to receive data for each CAN controller.
//
tCANMsgObject MsgObjectRx;

//
// This holds the information for the data send message object that is used
// to send data for each CAN controller.
//
tCANMsgObject MsgObjectTx;

//
// Receive buffer.
//
unsigned char pucBufferRx[CAN_FIFO_SIZE];

//
// Transmit buffer.
//
unsigned char pucBufferTx[CAN_FIFO_SIZE];

//
// Bytes remaining to be received.
//
unsigned long ulBytesRemaining;

//
// Bytes transmitted.
//
unsigned long ulBytesTransmitted;

//
// The current state of the CAN controller.
//
  /* enum
{
	CAN_IDLE,
	CAN_SENDING,
	CAN_WAIT_RX,
	CAN_PROCESS,
} */ char eState;
} g_sCAN;

//*****************************************************************************
//
// This function configures the transmit FIFO and copies data into the FIFO.
//
//*****************************************************************************
int
CANTransmitFIFO(unsigned char *pucData, unsigned long ulSize)
{
int iIdx;

//
// This is the message object used to send button updates.  This message
// object will not be "set" right now as that would trigger a transmission.
//
g_sCAN.MsgObjectTx.ulMsgID = TRANSMIT_MESSAGE_ID;
g_sCAN.MsgObjectTx.ulMsgIDMask = 0;

//
// This enables interrupts for transmitted messages.
//
g_sCAN.MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;

//
// Return the maximum possible number of bytes that can be sent in a single
// FIFO.
//
if(ulSize > CAN_FIFO_SIZE)
{
	return(CAN_FIFO_SIZE);
}

//
// Loop through all eight message objects that are part of the transmit
// FIFO.
//
for(iIdx = 0; iIdx < 8; iIdx++)
{
	//
	// If there are more than eight bytes remaining then use a full message
	// to transfer these 8 bytes.
	//
	if(ulSize > 8)
	{
		//
		// Set the length of the message, which can only be eight bytes
		// in this case as it is all that can be sent with a single message
		// object.
		//
		g_sCAN.MsgObjectTx.ulMsgLen = 8;
		g_sCAN.MsgObjectTx.pucMsgData = &pucData[iIdx * 8];

		//
		// Set the MSG_OBJ_FIFO to indicate that this is not the last
		// data in a chain of FIFO entries.
		//
		g_sCAN.MsgObjectTx.ulFlags |= MSG_OBJ_FIFO;

		//
		// There are now eight less bytes to transmit.
		//
		ulSize -= 8;

		//
		// Write out this message object.
		//
		CANMessageSet(CAN0_BASE, iIdx + 1, &g_sCAN.MsgObjectTx,
					  MSG_OBJ_TYPE_TX);
	}
	//
	// If there are less than or exactly eight bytes remaining then use a
	// message object to transfer these 8 bytes and do not set the
	// MSG_OBJ_FIFO flag to indicate that this is the last of the entries
	// in this FIFO.
	//
	else
	{
		//
		// Set the length to the remaining bytes and transmit the data.
		//
		g_sCAN.MsgObjectTx.ulMsgLen = ulSize;
		g_sCAN.MsgObjectTx.pucMsgData = &pucData[iIdx * 8];

		//
		// Write out this message object.
		//
		CANMessageSet(CAN0_BASE, iIdx + 1, &g_sCAN.MsgObjectTx,
					  MSG_OBJ_TYPE_TX);
	}
}
return(0);
}




//*****************************************************************************
//
// Send a string to the UART.
//
//*****************************************************************************

int putchar (int iCh)
{
 UARTCharPut (UART0_BASE, iCh);
 return (iCh);
}


void
UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
{
//
// Loop while there are more characters to send.
//
while(ulCount--)
{
	//
	// Write the next character to the UART.
	//
	UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
}
}

void main ()
{
 int iIdx; 
 unsigned long Clk;
  // установить часту на 80 МГц 
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |SYSCTL_OSC_MAIN);
Clk=SysCtlClockGet();

//
// Configure CAN 0 Pins.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinTypeCAN(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//
// Enable the CAN controller.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
//
// Reset the state of all the message object and the state of the CAN
// module to a known state.
//
CANInit(CAN0_BASE);


//
// Configure the bit rate for the CAN device, the clock rate to the CAN
// controller is fixed at 50MHz for this class of device and the bit rate is
// set to CAN_BITRATE.
//
CANBitRateSet(CAN0_BASE, 50000000, CAN_BITRATE);

//
// Take the CAN0 device out of INIT state.
//
CANEnable(CAN0_BASE);

//
// Set the initial state to idle.
//
g_sCAN.eState = CAN_IDLE;

//
// Initialize the CAN FIFO buffer.
//
for(iIdx = 0; iIdx < CAN_FIFO_SIZE; iIdx++)
{
	g_sCAN.pucBufferTx[iIdx] = iIdx + 0x1;
}


//
// Reset the buffer pointer.
//
g_sCAN.MsgObjectRx.pucMsgData = g_sCAN.pucBufferRx;

//
// Set the total number of bytes expected.
//
g_sCAN.ulBytesRemaining = CAN_FIFO_SIZE;







SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//GPIOPinConfigure(GPIO_PD2_U1RX);
//GPIOPinConfigure(GPIO_PD3_U1TX);

// Установить GPIO A0 и A1 как выводы UART 
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioInit(0);
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
						(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
						 UART_CONFIG_PAR_NONE));  





/*while (1)
{

for (int counter=0;counter<5000000; counter++){}
//UARTprintf ( "UARTprintf \n" );
printf ( "Hello\n" );

}
}*/

while(1)
{
	switch(g_sCAN.eState)
	{
		case CAN_IDLE:
		{
			//
			// Switch to sending state.
			//
			g_sCAN.eState = CAN_SENDING;

			//
			// Initialize the transmit count to zero.
			//
			g_sCAN.ulBytesTransmitted = 0;

			//
			// Schedule all of the CAN transmissions.
			//
			CANTransmitFIFO(g_sCAN.pucBufferTx, CAN_FIFO_SIZE);

			break;
		}
		case CAN_SENDING:
		{
			//
			// Wait for all bytes to go out.
			//
			if(g_sCAN.ulBytesTransmitted == CAN_FIFO_SIZE)
			{
				//
				// Switch to wait for RX state.
				//
				g_sCAN.eState = CAN_WAIT_RX;
			}

			break;
		}
		case CAN_WAIT_RX:
		{
			//
			// Wait for all new data to be received.
			//
			if(g_sCAN.ulBytesRemaining == 0)
			{
				//
				// Switch to wait for Process data state.
				//
				g_sCAN.eState = CAN_PROCESS;

				//
				// Reset the buffer pointer.
				//
				g_sCAN.MsgObjectRx.pucMsgData = g_sCAN.pucBufferRx;

				//
				// Reset the number of bytes expected.
				//
				g_sCAN.ulBytesRemaining = CAN_FIFO_SIZE;
			}
			break;
		}
		case CAN_PROCESS:
		{
			//
			// Compare the received data to the data that was sent out.
			//
			for(iIdx = 0; iIdx < CAN_FIFO_SIZE; iIdx++)
			{
				if(g_sCAN.pucBufferTx[iIdx] != g_sCAN.pucBufferRx[iIdx])
				{
					//
					// Detected an Error Condition.
					//
					UARTprintf ( "Error \n" );
					break;
				}
			}

			//
			// Change the CAN FIFO data.
			//
			for(iIdx = 0; iIdx < CAN_FIFO_SIZE; iIdx++)
			{
				//
				// Increment the data to change it.
				//
				g_sCAN.pucBufferTx[iIdx] += 0xB;
			}


			//
			// Return to the idle state.
			//
			g_sCAN.eState = CAN_IDLE;

			break;
		}
		default:
		{
			break;
		}
	}
}
}

Edited by IgorKossak
[codebox]

Share this post


Link to post
Share on other sites

Так. Вроде бы раскурил пример для платы EK-LM3S8962. Вырезал то, что надо.

Не понимаю, почему не работает? Что я упустил? И до удаления ненужных функций не работала ((

Как я понял, пример был заточен на получение данных по CAN, потом данные изменялись и отправлялись в ответ. И так снова.

Как вообще работает машина? Посылка должна уйти при вызове функции CANMessageSet ? Не надо там как то пинать еще? Я не стал подключать прерывания. Может это как то повлияло?

вот код в приложении

CAN.rar

Edited by Chip115

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this