本测评测试 AT32F423 的 CAN 外设模块。硬件配置上,使用 fifo 标识符过滤功能。
软件编写上,使用软件 fifo 管理接收数据。
步骤:
1、配置
2、代码编写
main()
int main(void)
{
/* add user code begin 1 */
uint32_t start_tick;
/* add user code end 1 */
/* add a necessary delay to ensure that Vdd is higher than the operating
voltage of battery powered domain (2.57V) when the battery powered
domain is powered on for the first time and being operated. */
wk_wait_for_power_stable();
/* system clock config. */
wk_system_clock_config();
/* config periph clock. */
wk_periph_clock_config();
/* nvic config. */
wk_nvic_config();
/* init usart1 function. */
wk_usart1_init();
/* init can1 function. */
wk_can1_init();
/* init gpio function. */
wk_gpio_config();
/* add user code begin 2 */
sys_init();
fifo_init(&can_rx_fifo, can_rx_msg_buf,
sizeof(can_rx_msg_buf)/sizeof(can_rx_msg_buf[0]));
can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);
// printf("The demo is started!\n");
start_tick = sys_get_tick();
/* add user code end 2 */
while(1)
{
/* add user code begin 3 */
if (!FIFO_IS_EMPTY(&can_rx_fifo)) {
can_tx_message_type tx_msg;
can_rx_message_type *rx_msg = fifo_read(&can_rx_fifo, can_rx_message_type);
fifo_decrement(&can_rx_fifo);
// tx_msg.standard_id = rx_msg->standard_id;
// tx_msg.extended_id = rx_msg->extended_id;
// tx_msg.id_type = rx_msg->id_type;
// tx_msg.frame_type = rx_msg->frame_type;
memcpy(&tx_msg, rx_msg, sizeof(can_tx_message_type));
can_message_transmit(CAN1, &tx_msg);
}
if (sys_get_tick() - start_tick >= 1000) {
start_tick = sys_get_tick();
gpio_bits_toggle(LED2_GPIO_PORT, LED2_PIN);
can_message_transmit(CAN1, &can_tx_msg);
}
/* add user code end 3 */
}
}
CAN1_RX0_IRQHandler()
void CAN1_RX0_IRQHandler(void)
{
/* add user code begin CAN1_RX0_IRQ 0 */
if (can_flag_get(CAN1, CAN_RF0MN_FLAG) == SET) {
can_flag_clear(CAN1, CAN_RF0MN_FLAG);
if (!FIFO_IS_FULL(&can_rx_fifo)) {
can_rx_message_type *msg = fifo_tail_member(&can_rx_fifo,
can_rx_message_type);
can_message_receive(CAN1, CAN_RX_FIFO0, msg);
fifo_increment(&can_rx_fifo);
} else {
can_receive_fifo_release(CAN1, CAN_RX_FIFO0);
}
}
/* add user code end CAN1_RX0_IRQ 0 */
/* add user code begin CAN1_RX0_IRQ 1 */
/* add user code end CAN1_RX0_IRQ 1 */
}
fifo.h - fifo 功能全部使用宏定义函数实现
#ifndef _FIFO_H
#define _FIFO_H
#include <stdint.h>
#include <string.h>
typedef struct {
uint16_t head;
uint16_t tail;
uint16_t size;
void *data;
} fifo_t;
#define FIFO_IS_FULL(fifo) ((fifo)->tail - (fifo)->head == (fifo)->size)
#define FIFO_IS_EMPTY(fifo) ((fifo)->head == (fifo)->tail)
#define fifo_increment(fifo) ((fifo)->tail++)
#define fifo_decrement(fifo) ((fifo)->head++)
#define fifo_init(fifo, pdata, dsize) do { \
(fifo)->head = (fifo)->tail = 0; \
(fifo)->data = (pdata); \
(fifo)->size = (dsize); \
} while (0)
#define fifo_head_member(fifo, TYPE) \
(&((TYPE *)(fifo)->data)[(fifo)->head % (fifo)->size])
#define fifo_tail_member(fifo, TYPE) \
(&((TYPE *)(fifo)->data)[(fifo)->tail % (fifo)->size])
#define fifo_read(fifo, TYPE) fifo_head_member((fifo), TYPE)
#define fifo_write(fifo, data, TYPE) \
memcpy(fifo_tail_member((fifo), TYPE), (data), sizeof(TYPE));
#endif
3、测试
芯片每隔 1s 发送1帧 ID = 0x123 的固定报文,上位机每隔 500ms 发送1帧 ID = 1FF 的报文,芯片收到上位机的报文后原样转发出来
4、测试中遇到的问题
当配置 PA11 & PA12 为 CAN 接口时,CAN 通信不了,没有报文收发。切换到 PD0 & PD1 之后,一切正常。
|