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程序就到这了,谢谢大家观看~
|