本测评测试 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 之后,一切正常。
|