打印
[N32G430]

N32G430 评测

[复制链接]
158|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 一路向北lm 于 2024-4-24 18:54 编辑

拿到了N32G430开发板已经有一段时间了,由于最近一段时间经历离职/换工作,一直没有开箱评测,最近几天有空,给大家做一个分享汇报。

1.芯片功能:
       N32G430系列采用32-bit Arm® Cortex®-M4F内核,最高工作主频128MHz,支持浮点运算和DSP指令,集成高达 64KB嵌入式加密Flash,16KB SRAM,集成丰富的高性能模拟器件,内置1个12bit 4.7Msps ADC,3个高速比较 器,集成多路U(S)ART、I²C、SPI、CAN等数字通信接口。

2.资料下载:
国民技术官网:https://www.nationstech.com/zlxz369/

3.gpio-led 测试
void LED_Initialize(GPIO_Module* GPIOx, uint16_t pin)
{
        GPIO_InitType GPIO_InitStructure;
        if(GPIOx == GPIOA)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
        }
        else if(GPIOx == GPIOB)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
        }
        else if(GPIOx == GPIOC)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOC);
        }
        else
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD);
        }
        
        if(pin < GPIO_PIN_ALL)
        {
                GPIO_Structure_Initialize(&GPIO_InitStructure);
                GPIO_InitStructure.Pin          = pin;
                GPIO_InitStructure.GPIO_Mode    = GPIO_MODE_OUT_PP;
                GPIO_InitStructure.GPIO_Current = GPIO_DS_4MA;
                GPIO_Peripheral_Initialize(GPIOx, &GPIO_InitStructure);
        }
}

void LED_Toggle(GPIO_Module* GPIOx, uint16_t pin)
{
    GPIO_Pin_Toggle(GPIOx, pin);;
}

{
    GPIO_Pins_Set(GPIOx, pin);
}

void LED_Off(GPIO_Module* GPIOx,uint16_t pin)
{
    GPIO_Pins_Reset(GPIOx, pin);
}


// mian test
int main(void)
{
        LED_Initialize(LED1_GPIO_PORT, LED1_GPIO_PIN | LED2_GPIO_PIN | LED3_GPIO_PIN);
        LED_Off(LED1_GPIO_PORT, LED1_GPIO_PIN | LED2_GPIO_PIN | LED3_GPIO_PIN);     
        while(1)
        {
                LED_Toggle(LED1_GPIO_PORT, LED1_GPIO_PIN);   
                LED_Toggle(LED2_GPIO_PORT, LED2_GPIO_PIN);
                LED_Toggle(LED3_GPIO_PORT, LED3_GPIO_PIN);
                SysTick_Delay_Ms(1000);
        }
}
4.gpio-key 测试
void Key_Input_Initialize(GPIO_Module* GPIOx, uint16_t pin)
{
        GPIO_InitType GPIO_InitStructure;
        if(GPIOx == GPIOA)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
        }
        else if(GPIOx == GPIOB)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
        }
        else if(GPIOx == GPIOC)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOC);
        }
        else
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD);
        }
        
        if(pin < GPIO_PIN_ALL)
        {
                GPIO_Structure_Initialize(&GPIO_InitStructure);
                GPIO_InitStructure.Pin       = pin;
                GPIO_InitStructure.GPIO_Mode = GPIO_MODE_INPUT;
                GPIO_InitStructure.GPIO_Pull = GPIO_PULL_UP;
                /* Initialize GPIO */
                GPIO_Peripheral_Initialize(GPIOx, &GPIO_InitStructure);
        }
}

void Key_Input_Initialize(GPIO_Module* GPIOx, uint16_t pin)
{
        /* Define a structure of type GPIO_InitType */
        GPIO_InitType GPIO_InitStructure;
        
        /* Enable KEY related GPIO peripheral clock */
        if(GPIOx == GPIOA)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
        }
        else if(GPIOx == GPIOB)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
        }
        else if(GPIOx == GPIOC)
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOC);
        }
        else
        {
                RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD);
        }
        
        if(pin < GPIO_PIN_ALL)
        {
                GPIO_Structure_Initialize(&GPIO_InitStructure);
                GPIO_InitStructure.Pin       = pin;
                GPIO_InitStructure.GPIO_Mode = GPIO_MODE_INPUT;
                GPIO_InitStructure.GPIO_Pull = GPIO_PULL_UP;
                GPIO_Peripheral_Initialize(GPIOx, &GPIO_InitStructure);
        }
}

// main test
int main(void)
{
        LED_Initialize(LED1_GPIO_PORT, LED1_GPIO_PIN | LED2_GPIO_PIN);
        Key_Input_Initialize(KEY3_PORT, KEY3_PIN);
        while(1)
        {
                if(GPIO_Input_Pin_Data_Get(KEY3_PORT, KEY3_PIN) == PIN_RESET)
                {
                        LED_On(LED1_GPIO_PORT, LED1_GPIO_PIN);
                        LED_Off(LED2_GPIO_PORT, LED2_GPIO_PIN);
                        LED_Off(LED3_GPIO_PORT, LED3_GPIO_PIN);
                }  
}
5.timer-gpio-toggle 测试
uint32_t BSTIMClockFrequency = 0;

void GPIO_Config(void)
{
    GPIO_InitType GPIO_InitStructure;
    GPIO_Structure_Initialize(&GPIO_InitStructure);
    GPIO_InitStructure.Pin = GPIO_PIN_6;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_OUT_PP;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
    GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
}


int main(void)
{
    GPIO_Config();
    BSTIMClockFrequency = Common_BSTIM_RCC_Initialize(TIM6, RCC_HCLK_DIV4);
    Common_TIM_NVIC_Initialize(TIM6_IRQn, ENABLE);
    Common_TIM_Base_Initialize(TIM6, 65535, 0);
    TIM_Base_Reload_Mode_Set(TIM6, TIM_PSC_RELOAD_MODE_IMMEDIATE);
    TIM_Interrupt_Enable(TIM6, TIM_INT_UPDATE);
    TIM_On(TIM6);
}


void TIM6_IRQHandler(void)
{
    if (TIM_Interrupt_Status_Get(TIM6, TIM_INT_UPDATE) != RESET)
    {
        TIM_Interrupt_Status_Clear(TIM6, TIM_INT_UPDATE);
        GPIO_Pin_Toggle(GPIOB, GPIO_PIN_6);
    }
}
6.uart-printf 测试
void GPIO_Configuration(void)
{
    GPIO_InitType GPIO_InitStructure;
    GPIO_Structure_Initialize(&GPIO_InitStructure);   

    GPIO_InitStructure.Pin            = USARTx_TxPin;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = USARTx_Tx_GPIO_AF;
    GPIO_Peripheral_Initialize(USARTx_GPIO, &GPIO_InitStructure);   

    GPIO_InitStructure.Pin            = USARTx_RxPin;
    GPIO_InitStructure.GPIO_Alternate = USARTx_Rx_GPIO_AF;
    GPIO_Peripheral_Initialize(USARTx_GPIO, &GPIO_InitStructure);
}

void RCC_Configuration(void)
{
    GPIO_AHBClkCmd(USARTx_GPIO_CLK);
    USART_APBxClkCmd(USARTx_CLK);
}

void  UART_Configuration(void)
{
   USART_InitType USART_InitStructure;
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;

    /* Configure USARTx */
    USART_Initializes(USARTx, &USART_InitStructure);
    /* Enable the USARTx */
    USART_Enable(USARTx);
}

int main(void)
{
    RCC_ClocksType RCC_ClocksStatus;
    RCC_Configuration();
    GPIO_Configuration();
    UART_Configuration(void);
    RCC_Clocks_Frequencies_Value_Get(&RCC_ClocksStatus);
    printf("\n\rUSART Printf Example: retarget the C library printf function to the USART\n\r");

    while (1)
    {
    }
}

int fputc(int ch, FILE* f)
{
    USART_Data_Send(USARTx, (uint8_t)ch);
    while (USART_Flag_Status_Get(USARTx, USART_FLAG_TXDE) == RESET);
    return (ch);
}

#ifdef USE_FULL_ASSERT
void assert_failed(const uint8_t* expr, const uint8_t* file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* Infinite loop */
    while (1)
    {
    }
}

#endif
7.can-loop测试,N32G430集成了can外设,也就意味着它具备胜任工业网络canopen协议的可能,can迈出大门第一步,回环自测
void CAN_CONFIG(void)
{
    RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_CAN);
    CAN_NVIC_Configuration();
    CAN_GPIO_Configuration();
   
    CAN_Reset(CAN);
    CAN_Structure_Initializes(&CAN_InitStructure);
    CAN_InitStructure.TTCM          = DISABLE;
    CAN_InitStructure.ABOM          = DISABLE;
    CAN_InitStructure.AWKUM         = DISABLE;
    CAN_InitStructure.NART          = DISABLE;
    CAN_InitStructure.RFLM          = DISABLE;
    CAN_InitStructure.TXFP          = ENABLE;
    CAN_InitStructure.OperatingMode = CAN_LOOPBACK_MODE;
    CAN_InitStructure.RSJW          = CAN_RSJW_1TQ;
    CAN_InitStructure.TBS1          = CAN_TBS1_8TQ;
    CAN_InitStructure.TBS2          = CAN_TBS2_7TQ;   
    CAN_InitStructure.BaudRatePrescaler = 4;
    CAN_Initializes(CAN, &CAN_InitStructure);
    CAN_FilterInitStructure.Filter_Num            = 0;
    CAN_FilterInitStructure.Filter_Mode           = CAN_FILTER_IDLISTMODE;
    CAN_FilterInitStructure.Filter_Scale          = CAN_FILTER_32BITSCALE;
    CAN_FilterInitStructure.Filter_HighId         = 0x8000;
    CAN_FilterInitStructure.Filter_LowId          = 0x0000;
    CAN_FilterInitStructure.FilterMask_HighId     = 0x4000;
    CAN_FilterInitStructure.FilterMask_LowId      = 0x0000;
    CAN_FilterInitStructure.Filter_FIFOAssignment = CAN_FIFO0;
    CAN_FilterInitStructure.Filter_Act            = ENABLE;
    CAN_Filter_Initializes(&CAN_FilterInitStructure);
    CAN_Config_Interrupt_Enable(CAN, CAN_INT_FMP0);
}


void CAN_NVIC_Configuration(void)
{
    NVIC_InitType NVIC_InitStructure;
    NVIC_Initializes(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel                   = CAN_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0x1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Initializes(&NVIC_InitStructure);
}



void CAN_GPIO_Configuration(void)
{
    GPIO_InitType GPIO_InitStructure;
    GPIO_Structure_Initialize(&GPIO_InitStructure);
   
        RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
        RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);

    GPIO_InitStructure.Pin            = GPIO_PIN_8;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF6_CAN;
    GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.Pin             = GPIO_PIN_9;
    GPIO_InitStructure.GPIO_Alternate  = GPIO_AF6_CAN;
    GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
}



uint8_t Check_CanRecData(CanRxMessage* RxMessage, uint32_t StdId, uint32_t ExtId, uint8_t IDE, uint8_t RTR, uint8_t DLC,
                         uint8_t Data0, uint8_t Data1, uint8_t Data2, uint8_t Data3,
                         uint8_t Data4, uint8_t Data5, uint8_t Data6, uint8_t Data7, uint8_t FMI)
{
    if(IDE == CAN_EXTENDED_ID)
    {
        if(RxMessage->ExtId   != ExtId)         
        {
            return Fail;
        }
    }
    else if(IDE == CAN_STANDARD_ID)
    {
        if(RxMessage->StdId   != StdId)  
        {
            return Fail;
        }
    }
    if( (RxMessage->IDE     != IDE)   ||         /* CAN_ID_STD / CAN_ID_EXT */
        (RxMessage->RTR     != RTR)   ||         /* CAN_RTR_DATA / CAN_RTR_REMOTE */
        (RxMessage->DLC     != DLC)              /* 0 to 8 */
    )
    {
        return Fail;
    }
    if(RTR == CAN_RTRQ_DATA)
    {
        if(DLC >= 1)
        {
            if(RxMessage->Data[0] != Data0)
            {
                return Fail;
            }
        }
        if(DLC >= 2)
        {
            if(RxMessage->Data[1] != Data1)
            {
                return Fail;
            }
        }
        if(DLC >= 3)
        {
            if(RxMessage->Data[2] != Data2)
            {
                return Fail;
            }
        }
        if(DLC >= 4)
        {
            if(RxMessage->Data[3] != Data3)
            {
                return Fail;
            }
        }
        if(DLC >= 5)
        {
            if(RxMessage->Data[4] != Data4)
            {
                return Fail;
            }
        }
        if(DLC >= 6)
        {
            if(RxMessage->Data[5] != Data5)
            {
                return Fail;
            }
        }
        if(DLC >= 7)
        {
            if(RxMessage->Data[6] != Data6)
            {
                return Fail;
            }
        }
        if(DLC == 8)
        {
            if(RxMessage->Data[7] != Data7)
            {
                return Fail;
            }
        }
        if(DLC > 8)
        {
            return Fail;
        }
    }
    else if(RTR == CAN_RTRQ_REMOTE)
    {
        
    }
    if(RxMessage->FMI != FMI)           
    {
        return Fail;
    }

    return Pass;
}

uint16_t Rx_Flag = DISABLE;
int main(void)
{
    uint32_t wait_slak;
    NVIC_Priority_Group_Set(NVIC_PER2_SUB2_PRIORITYGROUP);

    CAN_CONFIG();
   
    CAN_TxMessage.StdId   = 0x0400;        
    CAN_TxMessage.ExtId   = 0x00;        
    CAN_TxMessage.IDE     = CAN_STANDARD_ID;           /* CAN_ID_STD / CAN_ID_EXT */
    CAN_TxMessage.RTR     = CAN_RTRQ_DATA;           /* CAN_RTR_DATA / CAN_RTR_REMOTE */
    CAN_TxMessage.DLC     = 8;           /* 0 to 8 */
    CAN_TxMessage.Data[0] = 0x00;
    CAN_TxMessage.Data[1] = 0x01;
    CAN_TxMessage.Data[2] = 0x02;
    CAN_TxMessage.Data[3] = 0x03;
    CAN_TxMessage.Data[4] = 0x04;
    CAN_TxMessage.Data[5] = 0x05;
    CAN_TxMessage.Data[6] = 0x06;
    CAN_TxMessage.Data[7] = 0x07;
    while(1)
    {
        CAN_Transmit_Message_initializes(CAN,&CAN_TxMessage);
        while(Rx_Flag == DISABLE)
        {
            Rx_Flag = Check_CanRecData(&CAN_RxMessage, 0x0400, 0x00, CAN_STANDARD_ID, CAN_RTRQ_DATA, 8,
                         0x00,0x01, 0x02, 0x03,
                         0x04,0x05, 0x06, 0x07, 0);
        }
        
        wait_slak = 0xFFFF;
        while(wait_slak>0)
        {
            wait_slak--;
        }
        Rx_Flag = DISABLE;
    }
}

8.内置boot-loader测试,测试内部的boot,是我这次测试的重点,在汇川工作的时候,遇到过国民其它系列芯片内置boot的bug问题,本次再来体验一下,看国民官方是否修复。

8.1 N32G430内置boot功能强大,具体支持功能如下:

8.2
N32G430 系列芯片的固件程序 BOOT,支持通过 USART 接口下载用户程序和数据。 相关命令格式如下:


上下层指令数据结构

1、上层指令结构:
<CMD_H + CMD_L + LEN + Par> + (DAT)。
CMD_H 代表一级命令字段, CMD_L 代表二级命令字段; LEN 代表发送数据长度; Par代表 4 个字节命令参数; DAT 代表上层指令往下层发送的具体数据;
2、下层应答结构:
< CMD_H + CMD_L + LEN > + (DAT) + <CR1+CR2>。
CMD_H 代表一级命令字段, CMD_L 代表二级命令字段,下层的命令字段和对应上层的命令字段相同; LEN 代表发送数据长度; DAT 代表下层向上层应答的具体数据; CR1+CR2代表向上层返回的指令执行结果,若上层发送命令一级、二级命令字段不属于任何命令, BOOT 回复 CR1=0xBB, CR2 = 0xCC。



串口支持的命令数据结构:
1、 上位机下发上层指令:
STA1 + STA2 + {上层指令结构} + XOR。
STA1 和 STA2 是串口发送命令的起始字节, STA1=0xAA, STA2=0x55。用于芯片识别上位机发送串口数据流。
XOR 代表之前命令字节的异或运算值(STA1 + STA2 + {上层指令结构})。
2、 上位机接收下层应答:
STA1 + STA2 + {下层应答结构} + XOR。
STA1 和 STA2 是串口发送命令的起始字节, STA1=0xAA, STA2=0x55。用于上位机识别芯片发送串口数据流
XOR 代表之前命令字节的异或运算值(STA1 + STA2 + {下层应答结构})。

8.3 命令列表


8.4 命令说明和实例修改串口波特率

Par[0~3],串口波特率协商设置值可以设定最大,设定范围为 2.4Kbps ~ 4Mbps,默认波特率为 9600bps

状态字节(CR1CR2)根据命令执行情况分为:
1. 返回成功:状态标志位(0xA00x00)
2. 返回失败:状态标志位(0xB00x00)

4.png (215.39 KB )

4.png

使用特权

评论回复
沙发
呐咯密密| | 2024-4-24 13:52 | 只看该作者
n32g430的性价比真的高

使用特权

评论回复
板凳
一路向北lm|  楼主 | 2024-4-24 18:29 | 只看该作者
呐咯密密 发表于 2024-4-24 13:52
n32g430的性价比真的高

是的,拿来做canopen设备一点问题没有的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

257

主题

3643

帖子

73

粉丝