找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

请问M467控制器不同CANFD的FIFO的RAM区域地址分配!

[复制链接]
跳转到指定楼层
楼主
匿名  发表于 2024-6-16 20:36:07 回帖奖励 |正序浏览 |阅读模式
请问M467控制器不同CANFD的FIFO的RAM区域地址分配!
问题1:如果我要定义4个通道的RAM区域,按照8条的报文数量,请问后面的几个通道应该如何分配?请指点一下,下面这样定义对吗?
CANFD_BUF_T __attribute__((section(".ARM.__at_0x40020200+0x240*0"))) CANFD0_TxBuff[8]; // size=8*(8+64)=0x240Bytes

CANFD_BUF_T __attribute__((section(".ARM.__at_0x40020200+0x240*1"))) CANFD1_TxBuff[8]; // size=8*(8+64)=0x240Bytes
CANFD_BUF_T __attribute__((section(".ARM.__at_0x40020200+0x240*2"))) CANFD2_TxBuff[8]; // size=8*(8+64)=0x240Bytes
CANFD_BUF_T __attribute__((section(".ARM.__at_0x40020200+0x240*3"))) CANFD3_TxBuff[8]; // size=8*(8+64)=0x240Bytes



问题2:如果我定义的是16条报文,是应该这样理解吗?size=16*(8+64)=0x480Bytes
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 顶 踩
回复

使用道具

12#
匿名  发表于 2024-6-20 20:20:01
感谢指点~
回复

使用道具

11#
Angus 发表于 2024-6-20 17:45:24 | 只看该作者
CANFD 用自己的 RAM 区存放收发数据,这个RAM 不在地址 0x20000000 开始的、通用 RAM 区。有6144个字节,只能按字读写,是1536个字。

CANFD0 的专用 RAM 区,首地址是 0x40020200,  往后 1536个字。
CANFD1 的专用 RAM 区,首地址是 0x40024200(加了0x4000),  往后 1536个字。
CNAFD2 的专用 RAM 区,首地址是 0x40028200,  往后 1536个字。
CNAFD3 的专用 RAM 区,首地址是 0x4002C200,  往后 1536个字。

如果你配置 CNAFD0 工作正常了,可以按相同结构配置 CANFD1。CANFD0的配置里,出现专用RAM 地址的地方,只要加 0x4000,就成了 CANFD1的相应配置。

让四个CANFD 同时工作的代码示例: EC_M460_uCOSii_4CANFD_TxRx_V1.00.zip (4.02 MB, 下载次数: 14)
回复 支持 反对

使用道具 举报

10#
匿名  发表于 2024-6-20 16:43:55
贴上源码,不知道哪里的问题。先这样吧。。。如果不行的话,就不搞了。。。
回复 支持 反对

使用道具

9#
匿名  发表于 2024-6-20 16:43:25
void CANFD0_TxTest(CANFD_T *psCanfd, uint8_t cnt)
{
    switch (cnt)
    {
        case 0:
            while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
            {
                if (--u32TimeOutCnt0 == 0) break;
            }
            psCanfd->TXBAR = 1 << 0 ;
            break;

        case 1:
            while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
            {
                if (--u32TimeOutCnt0 == 0) break;
            }
            psCanfd->TXBAR = 1 << 1 ;
            break;

        default:
            break ;
    }
}

void CANFD1_TxTest(CANFD_T *psCanfd, uint8_t cnt)
{
    switch (cnt)
    {
        case 0:
            while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
            {
                if (--u32TimeOutCnt1 == 0) break;
            }
            psCanfd->TXBAR = 1 << 0 ;
            break;

        case 1:
            while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
            {
                if (--u32TimeOutCnt1 == 0) break;
            }
            psCanfd->TXBAR = 1 << 1 ;
            break;

        default:
            break ;
    }
}

void CANFD2_TxTest(CANFD_T *psCanfd, uint8_t cnt)
{
    switch (cnt)
    {
        case 0:
            while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
            {
                if (--u32TimeOutCnt2 == 0) break;
            }
            psCanfd->TXBAR = 1 << 0 ;
            break;

        case 1:
            while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
            {
                if (--u32TimeOutCnt2 == 0) break;
            }
            psCanfd->TXBAR = 1 << 1 ;
            break;

        default:
            break ;
    }
}

void CANFD3_TxTest(CANFD_T *psCanfd, uint8_t cnt)
{
    switch (cnt)
    {
        case 0:
            while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
            {
                if (--u32TimeOutCnt3 == 0) break;
            }
            psCanfd->TXBAR = 1 << 0 ;
            break;

        case 1:
            while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
            {
                if (--u32TimeOutCnt3 == 0) break;
            }
            psCanfd->TXBAR = 1 << 1 ;
            break;

        default:
            break ;
    }
}

void CANFD0_Init(void)
{
    CANFD_FD_T sCANFD_Config0;
    SYS_ResetModule(CANFD0_RST);
    CANFD_GetDefaultConfig(&sCANFD_Config0, CANFD_OP_CAN_FD_MODE);
    sCANFD_Config0.sBtConfig.sNormBitRate.u32BitRate = 500000;
    sCANFD_Config0.sBtConfig.sDataBitRate.u32BitRate = 2000000;
    CANFD_Open(CANFD0, &sCANFD_Config0);
}

void CANFD1_Init(void)
{
    CANFD_FD_T sCANFD_Config1;
    SYS_ResetModule(CANFD1_RST);
    CANFD_GetDefaultConfig(&sCANFD_Config1, CANFD_OP_CAN_FD_MODE);
    sCANFD_Config1.sBtConfig.sNormBitRate.u32BitRate = 500000;
    sCANFD_Config1.sBtConfig.sDataBitRate.u32BitRate = 2000000;
    CANFD_Open(CANFD1, &sCANFD_Config1);
}

void CANFD2_Init(void)
{
    CANFD_FD_T sCANFD_Config2;
    SYS_ResetModule(CANFD2_RST);
    CANFD_GetDefaultConfig(&sCANFD_Config2, CANFD_OP_CAN_FD_MODE);
    sCANFD_Config2.sBtConfig.sNormBitRate.u32BitRate = 500000;
    sCANFD_Config2.sBtConfig.sDataBitRate.u32BitRate = 2000000;
    CANFD_Open(CANFD2, &sCANFD_Config2);
}

void CANFD3_Init(void)
{
    CANFD_FD_T sCANFD_Config3;
    SYS_ResetModule(CANFD3_RST);
    CANFD_GetDefaultConfig(&sCANFD_Config3, CANFD_OP_CAN_FD_MODE);
    sCANFD_Config3.sBtConfig.sNormBitRate.u32BitRate = 500000;
    sCANFD_Config3.sBtConfig.sDataBitRate.u32BitRate = 2000000;
    CANFD_Open(CANFD3, &sCANFD_Config3);
}


int32_t main(void)
{

    SYS_UnlockReg();                         // Unlock protected registers
    SYS_Init();                              // Init System, peripheral clock and multi-function I/O

    UART_Open(UART0, 115200);                           // Init UART to 115200-8n1 for print message

    SYS_ResetModule(CANFD0_RST);
    CANFD0->CCCR = CANFD_CCCR_CCE_Msk | CANFD_CCCR_INIT_Msk | CANFD_CCCR_BRSE_Msk | CANFD_CCCR_FDOE_Msk;

    SYS_ResetModule(CANFD1_RST);
    CANFD1->CCCR = CANFD_CCCR_CCE_Msk | CANFD_CCCR_INIT_Msk | CANFD_CCCR_BRSE_Msk | CANFD_CCCR_FDOE_Msk;

    SYS_ResetModule(CANFD2_RST);
    CANFD2->CCCR = CANFD_CCCR_CCE_Msk | CANFD_CCCR_INIT_Msk | CANFD_CCCR_BRSE_Msk | CANFD_CCCR_FDOE_Msk;

    SYS_ResetModule(CANFD3_RST);
    CANFD3->CCCR = CANFD_CCCR_CCE_Msk | CANFD_CCCR_INIT_Msk | CANFD_CCCR_BRSE_Msk | CANFD_CCCR_FDOE_Msk;

    CANFD0_Init();
    CANFD1_Init();
    CANFD2_Init();
    CANFD3_Init();

    CANFD0_TX_fifo_Init();
    CANFD1_TX_fifo_Init();
    CANFD2_TX_fifo_Init();
    CANFD3_TX_fifo_Init();
       

    CANFD0_Tx_Init(CANFD0, 2, 7, 0);
    CANFD0->CCCR = CANFD_CCCR_BRSE_Msk | CANFD_CCCR_FDOE_Msk ;    // Write is OK after 2 CLKs
       
    CANFD1_Tx_Init(CANFD1, 2, 7, 0);
    CANFD1->CCCR = CANFD_CCCR_BRSE_Msk | CANFD_CCCR_FDOE_Msk ;    // Write is OK after 2 CLKs

    CANFD2_Tx_Init(CANFD2, 2, 7, 0);
    CANFD2->CCCR = CANFD_CCCR_BRSE_Msk | CANFD_CCCR_FDOE_Msk ;    // Write is OK after 2 CLKs

    CANFD3_Tx_Init(CANFD3, 2, 7, 0);
    CANFD3->CCCR = CANFD_CCCR_BRSE_Msk | CANFD_CCCR_FDOE_Msk ;    // Write is OK after 2 CLKs

    SYS_LockReg();

    TIM1_Init();

    u32TimeOutCnt0 = CANFD_TIMEOUT;
    u32TimeOutCnt1 = CANFD_TIMEOUT;
    u32TimeOutCnt2 = CANFD_TIMEOUT;
    u32TimeOutCnt3 = CANFD_TIMEOUT;


    while (1)
    {
        CANFD0_TxTest(CANFD0, u8Item);
        CANFD1_TxTest(CANFD1,u8Item);
        CANFD2_TxTest(CANFD2,u8Item);
        CANFD3_TxTest(CANFD3,u8Item);
    }

}
回复 支持 反对

使用道具

8#
匿名  发表于 2024-6-20 16:43:06
void CANFD0_TX_fifo_Init(void)
{
    CANFD0_Txfifo[0].u32Id       = 0x001 << 18 ;                    // SID = 0x111
    CANFD0_Txfifo[0].u32Config   = 0x00300000 + 0x000F0000 ;        // DLC=8 mean 8 Bytes

    CANFD0_Txfifo[1].u32Id       = 0x002 << 18 ;                    // SID = 0x113
    CANFD0_Txfifo[1].u32Config   = 0x00300000 + 0x000F0000 ;        // DLC=9 =12 Bytes

    CANFD0_Txfifo[0].au32Data[0] = 0x11111111;
    CANFD0_Txfifo[1].au32Data[0] = 0x22222222;
}

void CANFD1_TX_fifo_Init(void)
{
    CANFD1_Txfifo[0].u32Id       = 0x011 << 18 ;                    // SID = 0x111
    CANFD1_Txfifo[0].u32Config   = 0x00300000 + 0x000F0000 ;        // DLC=8 mean 8 Bytes

    CANFD1_Txfifo[1].u32Id       = 0x012 << 18 ;                    // SID = 0x113
    CANFD1_Txfifo[1].u32Config   = 0x00300000 + 0x000F0000 ;        // DLC=9 =12 Bytes

    CANFD1_Txfifo[0].au32Data[0] = 0x11111111;
    CANFD1_Txfifo[1].au32Data[0] = 0x22222222;
}

void CANFD2_TX_fifo_Init(void)
{
    CANFD2_Txfifo[0].u32Id       = 0x021 << 18 ;                    // SID = 0x111
    CANFD2_Txfifo[0].u32Config   = 0x00300000 + 0x000F0000 ;        // DLC=8 mean 8 Bytes

    CANFD2_Txfifo[1].u32Id       = 0x022 << 18 ;                    // SID = 0x113
    CANFD2_Txfifo[1].u32Config   = 0x00300000 + 0x000F0000 ;        // DLC=9 =12 Bytes

    CANFD2_Txfifo[0].au32Data[0] = 0x11111111;
    CANFD2_Txfifo[1].au32Data[0] = 0x22222222;
}

void CANFD3_TX_fifo_Init(void)
{
    CANFD3_Txfifo[0].u32Id       = 0x031 << 18 ;                    // SID = 0x111
    CANFD3_Txfifo[0].u32Config   = 0x00300000 + 0x000F0000 ;        // DLC=8 mean 8 Bytes

    CANFD3_Txfifo[1].u32Id       = 0x032 << 18 ;                    // SID = 0x113
    CANFD3_Txfifo[1].u32Config   = 0x00300000 + 0x000F0000 ;        // DLC=9 =12 Bytes

    CANFD3_Txfifo[0].au32Data[0] = 0x11111111;
    CANFD3_Txfifo[1].au32Data[0] = 0x22222222;
}

void CANFD0_Tx_Init(CANFD_T *psCanfd, int16_t TxBuff_Quantity, int16_t DLC_Max, uint16_t TxBuff_StartAddr)
{
    psCanfd->TXBC = (TxBuff_Quantity << CANFD_TXBC_NDTB_Pos)
                    + TxBuff_StartAddr ;

    psCanfd->TXESC = DLC_Max <<  CANFD_TXESC_TBDS_Pos;
}
void CANFD1_Tx_Init(CANFD_T *psCanfd, int16_t TxBuff_Quantity, int16_t DLC_Max, uint16_t TxBuff_StartAddr)
{
    psCanfd->TXBC = (TxBuff_Quantity << CANFD_TXBC_NDTB_Pos)
                    + TxBuff_StartAddr ;

    psCanfd->TXESC = DLC_Max <<  CANFD_TXESC_TBDS_Pos;
}
void CANFD2_Tx_Init(CANFD_T *psCanfd, int16_t TxBuff_Quantity, int16_t DLC_Max, uint16_t TxBuff_StartAddr)
{
    psCanfd->TXBC = (TxBuff_Quantity << CANFD_TXBC_NDTB_Pos)
                    + TxBuff_StartAddr ;

    psCanfd->TXESC = DLC_Max <<  CANFD_TXESC_TBDS_Pos;
}
void CANFD3_Tx_Init(CANFD_T *psCanfd, int16_t TxBuff_Quantity, int16_t DLC_Max, uint16_t TxBuff_StartAddr)
{
    psCanfd->TXBC = (TxBuff_Quantity << CANFD_TXBC_NDTB_Pos)
                    + TxBuff_StartAddr ;

    psCanfd->TXESC = DLC_Max <<  CANFD_TXESC_TBDS_Pos;
}
回复 支持 反对

使用道具

7#
匿名  发表于 2024-6-20 16:42:46
void SYS_Init(void)
{

    /* Set PF multi-function pins for XT1_OUT(PF.2) and XT1_IN(PF.3) */
    SET_XT1_OUT_PF2();
    SET_XT1_IN_PF3();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable HIRC and HXT clock */
    CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk | CLK_PWRCTL_HXTEN_Msk);

    /* Wait for HIRC and HXT clock ready */
    CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk | CLK_STATUS_HXTSTB_Msk);

    /* Set PCLK0 and PCLK1 to HCLK/2 */
    CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV1 | CLK_PCLKDIV_APB1DIV_DIV1);

    /* Set core clock to 200MHz */
    CLK_SetCoreClock(200000000);

    /* Enable all GPIO clock */
    CLK->AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |
                    CLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;
    CLK->AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;

    CLK_EnableSysTick(CLK_CLKSEL0_STCLKSEL_HCLK_DIV2, 0);


    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));
    CLK_EnableModuleClock(UART0_MODULE);

    /* Set IP clock */
    CLK_SetModuleClock(CANFD0_MODULE, CLK_CLKSEL0_CANFD0SEL_HCLK, CLK_CLKDIV5_CANFD0(1));
    CLK_SetModuleClock(CANFD1_MODULE, CLK_CLKSEL0_CANFD1SEL_HCLK, CLK_CLKDIV5_CANFD1(1));
    CLK_SetModuleClock(CANFD2_MODULE, CLK_CLKSEL0_CANFD2SEL_HCLK, CLK_CLKDIV5_CANFD2(1));
    CLK_SetModuleClock(CANFD3_MODULE, CLK_CLKSEL0_CANFD3SEL_HCLK, CLK_CLKDIV5_CANFD3(1));
    /* Enable IP clock */
    CLK_EnableModuleClock(CANFD0_MODULE);
    CLK_EnableModuleClock(CANFD1_MODULE);
    CLK_EnableModuleClock(CANFD2_MODULE);
    CLK_EnableModuleClock(CANFD3_MODULE);

    CLK_SetModuleClock(TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_PCLK0, MODULE_NoMsk);
    CLK_EnableModuleClock(TMR1_MODULE);

    /*--------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                    */
    /*--------------------------------------------------------------------------------------------*/

    SET_UART0_RXD_PB12();       // Set multi-function pins for UART0 RXD and TXD
    SET_UART0_TXD_PB13();


    //CAN
    SET_CAN0_TXD_PD11();
    SET_CAN0_RXD_PD10();

    SET_CAN1_TXD_PC13();
    SET_CAN1_RXD_PD12();

    SET_CAN2_TXD_PB9();
    SET_CAN2_RXD_PB8();

    SET_CAN3_TXD_PF11();
    SET_CAN3_RXD_PF10();

}
回复 支持 反对

使用道具

6#
匿名  发表于 2024-6-20 16:42:17
CANFD_BUF_T __attribute__((section(".ARM.__at_0x40020200"))) CANFD0_Txfifo[2];
CANFD_BUF_T __attribute__((section(".ARM.__at_0x40024200"))) CANFD1_Txfifo[2];
CANFD_BUF_T __attribute__((section(".ARM.__at_0x40028200"))) CANFD2_Txfifo[2];
CANFD_BUF_T __attribute__((section(".ARM.__at_0x4002C200"))) CANFD3_Txfifo[2];

uint8_t u8Item = 0;

uint32_t u32TimeOutCnt0 = 0;
uint32_t u32TimeOutCnt1 = 0;
uint32_t u32TimeOutCnt2 = 0;
uint32_t u32TimeOutCnt3 = 0;


void TIM1_Init(void)
{
    TIMER_Open(TIMER1, TIMER_PERIODIC_MODE, 100000);//1khz中断一次
    TIMER_EnableInt(TIMER1);
    NVIC_EnableIRQ(TMR1_IRQn);
    TIMER_Start(TIMER1);
}

void TMR1_IRQHandler(void)
{
    if (++u8Item > 1) u8Item = 0;

    TIMER_ClearIntFlag(TIMER1);
}
回复 支持 反对

使用道具

5#
匿名  发表于 2024-6-20 15:55:37
Angus 发表于 2024-6-20 14:49
CANFD0123的内RAM区,首址分别是 :
CANFD0:0x40020200,
CANFD1:0x40024200,

只改 HXE 地址的第4位就可以了;
请问一下,这句话怎么理解?
回复 支持 反对

使用道具

地板
Angus 发表于 2024-6-20 14:49:00 | 只看该作者
游客 121.29.98.x 发表于 2024-6-18 17:30
“不明白四个通道的RAM区域是什么意思?“
我的意思是,如果四个CANFD通道,CAN0,1,2,3 ,同时需要分配RAM ...

CANFD0123的内RAM区,首址分别是 :
CANFD0:0x40020200,
CANFD1:0x40024200,
CANFD2:0x40028200,
CANFD3:0x4002C200,

如果定义了CANFD0的数组工作正常,再定义其它三个CANFD数组时,只改 HXE 地址的第4位就可以了。
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU