硬件:S32K144开发板
软件:S32DS 2.2
1,S32K144硬件连接说明
看门狗定时器时间到没有喂狗就会触发系统复位,反之定时时间内喂狗会正常工作,可以避免程序跑飞等软硬件问题。 IO口分配情况如下,S32K144开发板具有3个按键和4个LED灯,具体与芯片的引脚连接情况如下所示。
* IO口分配情况
* KEY1 PTC12
* KEY2 PTC13
* KEY3 PTB2
2,S32K144的CAN配置
S32DS的外设配置通过图形配置工具Component Inspector来实现。双击Components下方的pin_mux按钮(1)打开图形配置工具Component Inspector(2)。可以双击图形配置工具Component Inspector空白处让它最大化方便我们进行配置。
按照下图对应配置三路CAN总线的对应引脚,CAN0(1)、CAN1(2)、CAN2(3)。完成配置引脚后退出。
双击Components(1)按钮打开图形配置工具Component Iibrary(2)进行外设添加。双击can_pal(3)按钮添加三个CAN外设,对应上方配置的三路CAN总线。配置完成如(4)所示。
3,S32K144的CAN常用函数说明
1,CAN初始化函数CAN_Init。
/*功能**********************************************************************
*
* 函数名称 : CAN_Init
* 描述 : 配置 CAN 模块
*
* 工具:CAN_Init_Activity
*结束**************************************************************************/
status_t CAN_Init(const can_instance_t * const instance,
const can_user_config_t *config)
2,配置接收缓冲函数CAN_ConfigRxBuff。
/*功能**********************************************************************
*
* 函数名称 : CAN_ConfigRxBuff
* 描述 : 配置用于接收的缓冲区。
*
* 工具:CAN_ConfigRxBuff_Activity
*结束**************************************************************************/
status_t CAN_ConfigRxBuff(const can_instance_t * const instance,
uint32_t buffIdx,
const can_buff_config_t *config,
uint32_t acceptedId)
3,配置发送缓冲函数CAN_ConfigTxBuff。
/*功能**********************************************************************
*
* 函数名称 : CAN_ConfigTxBuff
* 描述 :配置用于传输的缓冲区。
*
* 工具:CAN_ConfigTxBuff_Activity
*结束**************************************************************************/
status_t CAN_ConfigTxBuff(const can_instance_t * const instance,
uint32_t buffIdx,
const can_buff_config_t *config)
4,缓冲区配置 ID 过滤器函数CAN_SetRxFilter。
/*功能**********************************************************************
*
* 函数名称 : CAN_SetRxFilter
* 描述 : 为特定接收缓冲区配置 ID 过滤器。
*
* 工具:CAN_SetRxFilter_Activity
*结束**************************************************************************/
status_t CAN_SetRxFilter(const can_instance_t * const instance,
can_msg_id_type_t idType,
uint32_t buffIdx,
uint32_t mask)
5,安装 IRQ 处理程序的回调函数CAN_InstallEventCallback。
/*功能**********************************************************************
*
* 函数名称 : CAN_InstallEventCallback
* 描述 : 安装 IRQ 处理程序的回调函数。
*
* 工具:CAN_InstallEventCallback_Activity
*结束**************************************************************************/
status_t CAN_InstallEventCallback(const can_instance_t * const instance,
can_callback_t callback,
void *callbackParam)
6,CAN接收函数CAN_Receive。
/*功能**********************************************************************
*
* 函数名称 : CAN_Receive
* 描述 : 使用指定的消息缓冲区接收 CAN 帧。
*
* 工具:CAN_Receive_Activity
*结束**************************************************************************/
status_t CAN_Receive(const can_instance_t * const 实例,
uint32_t buffIdx,
can_message_t *消息)
7,CAN发送函数CAN_Send。
/*功能**********************************************************************
*
* 函数名称 : CAN_Send
* 描述 : 使用指定的缓冲区发送 CAN 帧。
*
* 实施 : CAN_Send_Activity
*结束**************************************************************************/
status_t CAN_Send(const can_instance_t * const instance,
uint32_t buffIdx,
const can_message_t *message)
4,S32K144的CAN实战
实现三个按键控制三路CAN发送,按下KEY1后CAN0发送,按下KEY2后CAN1发送,按下KEY3后CAN2发送。发送的信息接收后从串口发出便于观察。这里只写出CAN0的代码示例,其余两个类似。
1,编写can_init()函数进行CAN初始化。
void CAN0_Init(void)
{
CAN_Init(&can_pal0_instance, &can_pal0_Config0);
can_buff_config_t Rx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t Tx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
CAN_ConfigRxBuff(&can_pal0_instance, RX_MAILBOX_CAN0, &Rx_buffCfg, Rx_Filter); //注册接收配置和MSGID过滤器(如过滤器配置为0x1,则只接受msgid 0x1发来的报文)
CAN_ConfigTxBuff(&can_pal0_instance, TX_MAILBOX_CAN0, &Tx_buffCfg); //配置发送
/*设置MSGID的掩码,掩码粗略可以理解为对11bit MSGID地址的过滤
如果某bit位需要过滤设置为1,不过滤设置为0,例如掩码设置为0x7ff则过滤全部标准id,如果设置为0x7fe,这只能接受0x01的报文(不存在0x0的地址)*/
CAN_SetRxFilter(&can_pal0_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN0,0); //设置MSGID掩码,
CAN_InstallEventCallback(&can_pal0_instance,&CAN0_Callback_Func,(void*)0); //注册回调函数
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //*****重点****此函数不只有接收作用 还有续订回调函数的作用.
}
2,编写回调函数
void CAN0_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState; //此处防止警报
(void)instance;
(void)buffIdx;
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //接收报文并重新注册回调函数
switch(event) //回调事件
{
case CAN_EVENT_RX_COMPLETE: //接收完成 事件
IRQ_CAN0_RX =1;
break;
case CAN_EVENT_TX_COMPLETE: //发送完成事件
break;
default:
break;
}
}
3,编写发送函数
/*按键处理*/
pinstate = KEY_Proc (0);
if(pinstate ==BTN1_PRES )
{
can_message_t Tx_msg = {
.cs = 0U,
.id = 0x01,
.data[0] = 0x0,
.data[1] = 0x1,
.data[2] = 0x2,
.data[3] = 0x3,
.data[4] = 0x4,
.data[5] = 0x5,
.data[6] = 0x6,
.data[7] = 0x7,
.length = 8
};
CAN_Send(&can_pal0_instance, TX_MAILBOX_CAN0, &Tx_msg);
u1_printf("CAN0发送报文\r\n");
}
4,编写接收函数
if (IRQ_CAN0_RX ==1)
{
int i;
u1_printf("CAN0 RECV ID:0x%x \r\n",recvMsg_CAN0.id);
for(i=0; i<recvMsg_CAN0.length;i++)
{
u1_printf("Data %d : %x\r\n",i,recvMsg_CAN0.data[i]);
if(i==recvMsg_CAN0.length-1) u1_printf("***************\r\n");
}
IRQ_CAN0_RX=0;
}
5,烧录验证