реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Stellaris LM3S9B96, CAN, помогите разобраться с CAN
Chip115
сообщение Mar 20 2012, 07:59
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 28-12-07
Пользователь №: 33 709



Всем привет! Пытаюсь заставить работать CAN 0 , но пока все четно ((
Да и не совсем пока я разобрался с stellarisware. помогите осилить )
Как я понимаю, надо юзасть can.c и can.h из driverlib.
Вот такие ф-ции там есть

CODE
//*****************************************************************************
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, но что то до меня туго доходит sad.gif
Помогите разобраться. Может у кого есть пример для этого МК?

Сообщение отредактировал IgorKossak - Mar 20 2012, 14:40
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
Chip115
сообщение Mar 20 2012, 11:48
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 28-12-07
Пользователь №: 33 709



Вот тут на основании примера из IAR что то написал. Не работает (( Не могу понять что не так ((
Помогите разобраться ))
CODE
//*****************************************************************************
//
// 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;
}
}
}
}


Сообщение отредактировал IgorKossak - Mar 20 2012, 14:40
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
Chip115
сообщение Mar 21 2012, 09:21
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 28-12-07
Пользователь №: 33 709



Так. Вроде бы раскурил пример для платы EK-LM3S8962. Вырезал то, что надо.
Не понимаю, почему не работает? Что я упустил? И до удаления ненужных функций не работала ((
Как я понял, пример был заточен на получение данных по CAN, потом данные изменялись и отправлялись в ответ. И так снова.
Как вообще работает машина? Посылка должна уйти при вызове функции CANMessageSet ? Не надо там как то пинать еще? Я не стал подключать прерывания. Может это как то повлияло?
вот код в приложении


Сообщение отредактировал Chip115 - Mar 21 2012, 09:42
Прикрепленные файлы
Прикрепленный файл  CAN.rar ( 1.97 килобайт ) Кол-во скачиваний: 19
 
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 00:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01379 секунд с 7
ELECTRONIX ©2004-2016