|
回复 沙发 Study_Stellaris 的帖子
#include "config.h"
#include "serial_com.h"
#include "can_deal.h"
volatile unsigned long g_ulIntCount = 0;
//*****************************************************************************
//
// Counters that are used to count the number of messages on each of the
// three message objects that are used in this example.
//
//*****************************************************************************
volatile unsigned long g_ulMsg1Count = 0;
volatile unsigned long g_ulMsg2Count = 0;
volatile unsigned long g_ulMsg3Count = 0;
//*****************************************************************************
//
// A flag to indicate that CAN controller message object 3 has sent a message.
//
//*****************************************************************************
volatile unsigned long g_bMsgObj3Sent = 0;
//*****************************************************************************
//
// A flag to indicate that some transmission error occurred.
//
//*****************************************************************************
volatile unsigned long g_bErrFlag = 0;
//*****************************************************************************
//
// CAN message objects that will hold the separate CAN messages. These could
// also be allocated on the stack but be careful because these structures
// each take about 20 bytes.
//
//*****************************************************************************
tCANMsgObject g_sCANMsgObject1;
tCANMsgObject g_sCANMsgObject2;
tCANMsgObject g_sCANMsgObject3;
//*****************************************************************************
//
// Message buffers that hold the contents of the 4 different messages that
// are being transmitted. Each one is a different length.
//
//*****************************************************************************
unsigned char g_ucMsg1[4] = { 0, 0, 0, 0 };
unsigned char g_ucMsg2[5] = { 2, 2, 2, 2, 2 };
unsigned char g_ucMsg3[6] = { 3, 3, 3, 3, 3, 3 };
unsigned char g_ucMsg4[8] = { 4, 4, 4, 4, 5, 5, 5, 5 };
tCANBitClkParms CANBitClkSettings[] =
{
{7, 2, 1, 1}, /* CANBAUD_1M */
{14, 5, 2, 1}, /* CANBAUD_500K */
{14, 5, 2, 2}, /* CANBAUD_250K */
{ 7, 2, 1, 8}, //{14, 5, 2, 4}, {29,10,1,2}, /* CANBAUD_125K */
{14, 5, 2, 5}, /* CANBAUD_100k */
{14, 5, 2, 10}, /* CANBAUD_50k */
{13, 6, 2, 20}, /* CANBAUD_25k */
{13, 6, 2, 25}, /* CANBAUD_20k */
{13, 6, 2, 50}, /* CANBAUD_10k */
{13, 6, 2, 100}, /* CANBAUD_5k */
{13, 6, 2, 200}, /* CANBAUD_2k5 */
};
//*****************************************************************************
//
// 函数配置UART0 显示例程运行信息
// 波特率:115200;数据位:8位;校验位:无;停止位:1位
//
//*****************************************************************************
void
InitConsole(void)
{
//
// Enable GPIO port A which is used for UART0 pins
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Configure the pin muxing for UART0 functions on port A0 and A1.
// This step is not necessary if your part does not support pin muxing.
//
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
//
// Select the alternate (UART) function for these pins.
//
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//
// Initialize the UART for console I/O.
//
UARTStdioInit(0);
}
//*****************************************************************************
//
// This function prints some information about the CAN message to the
// serial port for information purposes only.(ulMsgObj即报文对象的编号)
//
//*****************************************************************************
void
PrintCANMessageInfo(tCANMsgObject *pCANMsg, unsigned long ulMsgObj)
{
unsigned int uIdx;
UARTprintf("Sending msg: obj=%d ID=0x%04X msg=0x", ulMsgObj,
pCANMsg->ulMsgID);
for(uIdx = 0; uIdx < pCANMsg->ulMsgLen; uIdx++)
{
UARTprintf("%02X ", pCANMsg->pucMsgData[uIdx]);
}
UARTprintf("\n");
}
//*****************************************************************************
//
// 软件延时函数
//
//*****************************************************************************
void
SimpleDelay(void)
{
//
// Delay cycles for 1 second
//
SysCtlDelay(16000000 / 3);
}
//*****************************************************************************
//
// This function is the interrupt handler for the CAN peripheral. It checks
// for the cause of the interrupt, and maintains a count of all messages that
// have been transmitted.
//
//*****************************************************************************
void
CANIntHandler(void)
{
unsigned long ulStatus;
unsigned long ulNewData,ulTxReQuest,ulMsgVal;
unsigned long temp;
//
// Read the CAN interrupt status to find the cause of the interrupt
//
ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
//
// If the cause is a controller status interrupt, then get the status
//
if(ulStatus == CAN_INT_INTID_STATUS)
{
//
// Read the controller status. This will return a field of status
// error bits that can indicate various errors. Error processing
// is not done in this example for simplicity. Refer to the
// API documentation for details about the error status bits.
// The act of reading this status will clear the interrupt. If the
// CAN peripheral is not connected to a CAN bus with other CAN devices
// present, then errors will occur and will be indicated in the
// controller status.
//
ulStatus = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
temp = HWREG(CAN0_BASE + CAN_O_ERR);
ulTxReQuest = CANStatusGet(CAN0_BASE, CAN_STS_TXREQUEST);
ulNewData = CANStatusGet(CAN0_BASE ,CAN_STS_NEWDAT);
ulMsgVal = CANStatusGet(CAN0_BASE ,CAN_STS_MSGVAL);
//
// Set a flag to indicate some errors may have occurred.
//
g_bErrFlag = 1;
}
//
// Check if the cause is message object 1, which is used for sending
// message 1.
//
else if(ulStatus == 1)
{
//
// Getting to this point means that the TX interrupt occurred on
// message object 1, and the message TX is complete. Clear the
// message object interrupt.
//
CANIntClear(CAN0_BASE, 1);
//
// Increment a counter to keep track of how many messages have been
// sent. In a real application this could be used to set flags to
// indicate when a message is sent.
//
g_ulMsg1Count++;
//
// Since the message was sent, clear any error flags.
//
g_bErrFlag = 0;
}
//
// Check if the cause is message object 2, which is used for sending
// message 2.
//
else if(ulStatus == 2)
{
//
// Getting to this point means that the TX interrupt occurred on
// message object 2, and the message TX is complete. Clear the
// message object interrupt.
//
CANIntClear(CAN0_BASE, 2);
//
// Increment a counter to keep track of how many messages have been
// sent. In a real application this could be used to set flags to
// indicate when a message is sent.
//
g_ulMsg2Count++;
//
// Since the message was sent, clear any error flags.
//
g_bErrFlag = 0;
}
//
// Check if the cause is message object 3, which is used for sending
// messages 3 and 4.
//
else if(ulStatus == 3)
{
//
// Getting to this point means that the TX interrupt occurred on
// message object 3, and a message TX is complete. Clear the
// message object interrupt.
//
CANIntClear(CAN0_BASE, 3);
//
// Increment a counter to keep track of how many messages have been
// sent. In a real application this could be used to set flags to
// indicate when a message is sent.
//
g_ulMsg3Count++;
//
// 报文对象3的报文发送完毕标志设置,
// 这个标志能使主程序知道何时能用报文对象3发送另外一个报文
//
g_bMsgObj3Sent = 1;
//
// Since the message was sent, clear any error flags.
//
g_bErrFlag = 0;
}
//
// Otherwise, something unexpected caused the interrupt. This should
// never happen.
//
else
{
//
// Spurious interrupt handling can go here.
//
}
}
//*****************************************************************************
//
// Configure the CAN and enter a loop to transmit periodic CAN messages.
//
//*****************************************************************************
int
main(void)
{
//
// Set the clocking to run directly from the external crystal/oscillator.
// TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
// crystal on your board.
//
jtagWait(); // 防止JTAG失效,重要!
clockInit(); // 时钟初始化:晶振,6MHz
board_initialize(); // 初始化
//
// Set up the serial console to use for displaying messages. This is
// just for this example program and is not needed for CAN operation.
//
InitConsole();
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // 使能GPIOD系统外设
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0); // 使能CAN控制器系统外设
GPIOPinConfigure(GPIO_PA6_CAN0RX);
GPIOPinConfigure(GPIO_PB5_CAN0TX);
GPIOPinTypeCAN(GPIO_PORTA_BASE, GPIO_PIN_6 );
GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_5 );
CANInit(CAN0_BASE); // 初始化CAN节点
CANBitTimingSet(CAN0_BASE,
(tCANBitClkParms *)&CANBitClkSettings[CANBAUD_125K]); // 对 CAN控制器位时序进行配置
CANEnable(CAN0_BASE); // 使能CAN控制器
CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_STATUS | CAN_INT_ERROR ); // 使能CAN控制器中断源
IntEnable(INT_CAN0); // 使能CAN控制器中断(to CPU)
IntMasterEnable(); // 使能中断总开关
// 初始化报文对象1,使其能发送CAN报文1
// 这个报文对象没有被多个报文共用,因此只需初始化1次
// 且能用相同的标识符重复多次发送报文
//
g_sCANMsgObject1.ulMsgID = 0x0001;
g_sCANMsgObject1.ulMsgIDMask = 0;
g_sCANMsgObject1.ulFlags = MSG_OBJ_TX_INT_ENABLE;
g_sCANMsgObject1.ulMsgLen = sizeof(g_ucMsg1);
g_sCANMsgObject1.pucMsgData = g_ucMsg1;
//
// 初始化报文对象2,使其能发送CAN报文2
// 这个报文对象没有被多个报文共用,因此只需初始化1次
// 且能用相同的标识符重复多次发送报文
//
g_sCANMsgObject2.ulMsgID = 0x2001;
g_sCANMsgObject2.ulMsgIDMask = 0;
g_sCANMsgObject2.ulFlags = MSG_OBJ_TX_INT_ENABLE;
g_sCANMsgObject2.ulMsgLen = sizeof(g_ucMsg2);
g_sCANMsgObject2.pucMsgData = g_ucMsg2;
//
// 进入循环发送报文,四个报文发送的时间间隔是1秒
// 这四个报文的内容每当在下一次循环前更改一次
//
for(;;)
{
PrintCANMessageInfo(&g_sCANMsgObject1, 1); //显示报文对象1的信息
CANMessageSet(CAN0_BASE, 1, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);
PrintCANMessageInfo(&g_sCANMsgObject2, 2);
CANMessageSet(CAN0_BASE, 2, &g_sCANMsgObject2, MSG_OBJ_TYPE_TX);
//
// 调用报文对象3发送报文3,这时它每次用前都需初始化1次,
// 因为报文对象3由2个不同的报文所共享
//
g_sCANMsgObject3.ulMsgID = 0x3001;
g_sCANMsgObject3.ulMsgIDMask = 0;
g_sCANMsgObject3.ulFlags = MSG_OBJ_TX_INT_ENABLE;
g_sCANMsgObject3.ulMsgLen = sizeof(g_ucMsg3);
g_sCANMsgObject3.pucMsgData = g_ucMsg3;
//
// 清除报文发送完毕标志,
// 这个标志用来指示报文对象3报文发送完毕,
// 它将在报文发送完毕后置位
g_bMsgObj3Sent = 0;
//
// Now send message 3 using CAN controller message object 3. This is
// the first message sent using this message object. The
// CANMessageSet() function will cause the message to be sent right
// away.
//
PrintCANMessageInfo(&g_sCANMsgObject3, 3);
CANMessageSet(CAN0_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);
//
// 等待报文3发送完毕,也即等待报文对象3的中断,因为这是需要再次用它来发送另外一个报文
//
while(!g_bMsgObj3Sent)
{
}
//
// 再次用报文对象3发送报文4,这时有需要初始化一次
//
g_sCANMsgObject3.ulMsgID = 0x3002;
g_sCANMsgObject3.ulMsgIDMask = 0;
g_sCANMsgObject3.ulFlags = MSG_OBJ_TX_INT_ENABLE;
g_sCANMsgObject3.ulMsgLen = sizeof(g_ucMsg4);
g_sCANMsgObject3.pucMsgData = g_ucMsg4;
//
// Now send message 4 using CAN controller message object 3. This is
// the second message sent using this message object. The
// CANMessageSet() function will cause the message to be sent right
// away.
//
PrintCANMessageInfo(&g_sCANMsgObject3, 3);
CANMessageSet(CAN0_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);
//
// Wait 1 second before continuing
//
SimpleDelay();
//
// Check the error flag to see if errors occurred
//
if(g_bErrFlag)
{
UARTprintf(" error - cable connected?\n");
}
else
{
//
// If no errors then print the count of message sent
//
UARTprintf(" total count = %u\n",
g_ulMsg1Count + g_ulMsg2Count + g_ulMsg3Count);
}
//
// 更改上次发给报文的数据
//
(*(unsigned long *)g_ucMsg1)++;
(*(unsigned long *)g_ucMsg2)++;
(*(unsigned long *)g_ucMsg3)++;
(*(unsigned long *)&g_ucMsg4[0])++;
(*(unsigned long *)&g_ucMsg4[4])--;
}
//
// Return no errors
//
// return(0); //若删去它则程序不能正常运行
}
这是例程,运行后结果还是应答错误。 |
|