打印
[N32G43x]

【N32G43XCL-STB_V1.0】+开箱及DEMO程序搭建

[复制链接]
932|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
N32G43XCL-STB_V1.0板子昨天就收到了,今天才有时间来开箱~
上图片:




中规中矩的一个48PIN的最小系统板,送线及加塑料螺丝,好评~
我之前没接触过国民的MCU,乘这个机会,也尝试一把,看看性能到底如何~
我们先看官方对N32G435XX系列MCU的介绍:

除了多了电容触控,其他外设也没什么突出的。
BSP风格类似ST标准库的风格,也容易上手~
板载LED,KEY和CMSIS DAP下载电路,更是一目了然~
下面开始搭建程序:
1、按照MDK PACK支持包。

2、拷贝必要文件,重新组合成一个DEMO工程:

因为采用M4的内核,所以支持位带操作及SYSTICK定时器:
我们新建我们3个核心文件:
sys.h
 
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).M4同M3类似,只是寄存器地址变了.
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414   
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14   
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     

#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010

//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入
delay.c的一些延时函数:
void delay_us(u32 nus)
{               
        u32 temp;                     
        SysTick->LOAD=nus*fac_us;                                 //时间加载                           
        SysTick->VAL=0x00;                                        //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数          
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
        SysTick->VAL =0X00;                                       //清空计数器
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对168M条件下,nms<=798ms
void delay_xms(u16 nms)
{                                     
        u32 temp;                  
        SysTick->LOAD=(u32)nms*fac_ms;                        //时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;                                   //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //开始倒数
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //关闭计数器
        SysTick->VAL =0X00;                                       //清空计数器                      
}
//延时nms
//nms:0~65535
void delay_ms(u16 nms)
{                  
        u8 repeat=nms/540;                                                //这里用540,是考虑到某些客户可能超频使用,
                                                                                        //比如超频到248M的时候,delay_xms最大只能延时541ms左右了
        u16 remain=nms%540;
        while(repeat)
        {
                delay_xms(540);
                repeat--;
        }
        if(remain)delay_xms(remain);
}
debug_usart.c里面设定为调试串口的配置:
//加入以下代码,支持printf函数,而不需要选择use MicroLIB          
#if 1
#pragma import(__use_no_semihosting)            
//标准库需要的支持函数                 
struct __FILE
{
        int handle;
};

FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
void _sys_exit(int x)
{
        x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{        

  USART_SendData(DBG_USARTx, (uint8_t)ch);
  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(DBG_USARTx, USART_FLAG_TXC) == RESET)
  {
  }
         
        return ch;
}
#endif


#if EN_DBG_USART_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误          
u8 DBG_USART_RX_BUF[DBG_USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,        接收完成标志
//bit14,        接收到0x0d
//bit13~0,        接收到的有效字节数目
u16 DBG_USART_RX_STA=0;       //接收状态标记       
#endif

void DBG_UART_Init(u32 bound)
{
    GPIO_InitType GPIO_InitStructure;
    USART_InitType USART_InitStructure;
  
#if EN_DBG_USART_RX
    NVIC_InitType NVIC_InitStructure;
#endif
  
    //GPIO初始化
    GPIO_InitStruct(&GPIO_InitStructure);
  
    DBG_PERIPH_GPIO_APBxClkCmd(DBG_PERIPH_GPIO_AF | DBG_PERIPH_GPIO, ENABLE);
    DBG_PERIPH_APBxClkCmd(DBG_PERIPH, ENABLE);

    GPIO_InitStructure.Pin        = DBG_TX_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
                GPIO_InitStructure.GPIO_Alternate = DBG_TX_GPIO_AF;
    GPIO_InitPeripheral(DBG_GPIO, &GPIO_InitStructure);

    GPIO_InitStructure.Pin       = DBG_RX_PIN;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = DBG_RX_GPIO_AF;
    GPIO_InitPeripheral(DBG_GPIO, &GPIO_InitStructure);
   
#if EN_DBG_USART_RX
    //中断优先级配置
    /* Configure the NVIC Preemption Priority Bits */
    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//在main函数里面统一配置
    /* Enable the USARTy Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel            = DBG_USART_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
#endif   
    //串口配置
    USART_InitStructure.BaudRate            = bound;
    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;

    // init uart
    USART_Init(DBG_USARTx, &USART_InitStructure);
#if EN_DBG_USART_RX    //发送中断默认不开启  
    /* Enable USARTy Receive and Transmit interrupts */
    USART_ConfigInt(DBG_USARTx, USART_INT_RXDNE, ENABLE);
    //USART_ConfigInt(DBG_USARTx, USART_INT_TXDE, ENABLE);
#endif     
    // enable uart
    USART_Enable(DBG_USARTx, ENABLE);
}


#if EN_DBG_USART_RX
void DBG_USART_IRQHandler(void)                        //串口1中断服务程序
{
        u8 Res;
#if SYSTEM_SUPPORT_OS                 //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
        OSIntEnter();   
#endif
        if(USART_GetIntStatus(DBG_USARTx, USART_INT_RXDNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
        {
                Res =USART_ReceiveData(DBG_USARTx);//(USART1->DR);        //读取接收到的数据
               
                if((DBG_USART_RX_STA&0x8000)==0)//接收未完成
                {
                        if(DBG_USART_RX_STA&0x4000)//接收到了0x0d
                        {
                                if(Res!=0x0a)DBG_USART_RX_STA=0;//接收错误,重新开始
                                else DBG_USART_RX_STA|=0x8000;        //接收完成了
                        }
                        else //还没收到0X0D
                        {       
                                if(Res==0x0d)DBG_USART_RX_STA|=0x4000;
                                else
                                {
                                        DBG_USART_RX_BUF[DBG_USART_RX_STA&0X3FFF]=Res ;
                                        DBG_USART_RX_STA++;
                                        if(DBG_USART_RX_STA>(DBG_USART_REC_LEN-1))DBG_USART_RX_STA=0;//接收数据错误,重新开始接收          
                                }                 
                        }
                }                    
  }
#if SYSTEM_SUPPORT_OS         //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
        OSIntExit();                                                                                           
#endif
}
#endif
除了3个核心文件外,还写了LED的配置:
#ifndef __LED_NEW_H_
#define __LED_NEW_H_

#include "sys.h"


//LED端口定义
#define LED1 PAout(8)          // D1
#define LED2 PBout(4)          // D2       
#define LED3 PBout(5)          // D3       

void LED_Init(void);

#endif

void LED_Init(void)
{

  GPIO_InitType GPIO_InitStructure;

  RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA|RCC_APB2_PERIPH_GPIOB, ENABLE);

  /* Configure the GPIO pin */
  GPIO_InitStruct(&GPIO_InitStructure);
  //PA8
  GPIO_InitStructure.Pin        = GPIO_PIN_8;
  GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
  GPIO_InitStructure.GPIO_Pull    = GPIO_No_Pull;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
  GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
  //PB4 PB5
  GPIO_InitStructure.Pin        = GPIO_PIN_4|GPIO_PIN_5;
  GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
  GPIO_InitStructure.GPIO_Pull    = GPIO_No_Pull;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
  GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
  
  //默认LED关闭状态
  LED1=0;
  LED2=0;
  LED3=0;
}


最终我们设定一个任务:将输入的字符,重新输出,并让一个LED闪烁~
int main(void)
{
  u8 t;
        u8 len;       
        u16 times=0;  
  /*SystemInit() function has been called by startup file startup_n32g43x.s*/
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(108);                //延时初始化
        DBG_UART_Init(115200);        //串口初始化波特率为115200
        LED_Init();                                  //初始化与LED连接的硬件接口  
        while(1)
        {
                if(DBG_USART_RX_STA&0x8000)
                {                                          
                        len=DBG_USART_RX_STA&0x3fff;//得到此次接收到的数据长度
                        printf("\r\n您发送的消息为:\r\n");
                        for(t=0;t<len;t++)
                        {
                                USART_SendData(DBG_USARTx, DBG_USART_RX_BUF[t]);         //向串口1发送数据
                                while (USART_GetFlagStatus(DBG_USARTx, USART_FLAG_TXC) == RESET);//等待发送结束
                        }
                        printf("\r\n\r\n");//插入换行
                        DBG_USART_RX_STA=0;
                }else
                {
                        times++;
                        if(times%5000==0)
                        {
                                printf("\r\nN32G435CL-DEMOBOARD 串口实验\r\n");
                                printf("JasonQiu@21ic\r\n\r\n\r\n");
                        }
                        if(times%200==0)printf("请输入数据,以回车键结束\r\n");  
                        if(times%30==0)LED1=!LED1;//闪烁LED,提示系统正在运行.
                        delay_ms(10);   
                }
        }
}
编译无误后,我们下载,查看串口,我们发送什么,它就会回发回来,且LED闪烁:
                                                                                                                                                        
好了,开箱及DEMO程序就到这了,谢谢大家观看~


使用特权

评论回复
沙发
kyzhd| | 2021-12-21 17:59 | 只看该作者
支持支持,学习来了。

使用特权

评论回复
板凳
xiaoqi976633690| | 2021-12-28 15:50 | 只看该作者
SDK哪来的啊,976633690@qq.com 能提供分吗

使用特权

评论回复
地板
qjp1988113|  楼主 | 2021-12-31 14:09 | 只看该作者
xiaoqi976633690 发表于 2021-12-28 15:50
SDK哪来的啊, 能提供分吗

微信群里有啊

使用特权

评论回复
5
weiwei4dk| | 2021-12-31 17:10 | 只看该作者
谢谢分享

使用特权

评论回复
6
hello、C| | 2022-1-7 14:52 | 只看该作者
谢谢分享,过几天我也来写个**

使用特权

评论回复
7
amina22| | 2022-6-1 14:40 | 只看该作者

使用特权

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

本版积分规则

111

主题

627

帖子

2

粉丝