一、项目介绍:
基于RT1021设计了一套最小系统板,芯片型号是MIMXRT1021DAF5B。
板卡介绍:
最小系统使用TYPEC接口供电,带一块1.3寸显示屏,分辨率为:240*240。多余的引脚使用锡手指引出,接口使用了PCIE-52;这里因为引脚定义是由心情随便定的,所以不能与市面同类接口对插。保险起见,我还是给电源系统增加了过压过流保护电路。
板上还有一块64M FLASH芯片,我这里使用的型号是GD25Q64EWIGR,RT1021单片机手册介绍可以将程序放 在这块片外FLASH里跑。本调试,只用了内部flash,片外flash功能还没有验证。
二、设计思路
硬件方面:首先确定好需要的外设,最起码需要一块屏幕,手边的1.3寸显示屏可以安排上。其次是最小系统的基本配置:电源,复位电路,晶振,启动配置电路,调试接口,对外接口......
代码调试:调试平台首选官方IDE,然后根据例程调通屏幕,验证外设.....
三、资料收集
硬件资料借鉴官网的RT1021 144P芯片开发板的图纸,做了些裁剪。总的来说RT1021的外围电路还算简单,照着官网图纸做是没有问题的。软件设计资料借鉴了官方IDE里的demo程序。以及网上开源的串口屏幕库文件。
四、设计过程
设计过程可以分为硬件设计,和代码调试两部分:
硬件部分:
RT1021的电源部分还是需要注意一下的,有一路内部电源要先于其他电源轨上电。电源硬件框图如下:
从typec口取电。然后经过防反接二极管D3后分成两路,一路给到TPS78233,TPS78233是一颗LDO,固定输出3.3V,负责给单片机提供一路长供电的电源,并保证SNVS_3.3V_IN网络优先上电;另一路经过过压过流保护芯片MP5016输出给后级电路。SY8113是一颗DC-DC降压芯片,输出设置为3.3V,给单片机和外设供电。USB上电时系统先给SNVS_3.3V_IN上电,PMIC_ON_REQ输出信号打开MP5016,VDD_3.3V上电成功。需要注意DCDC_PSWITCH设置延时10MS后。RT1021自带ON/OFF硬件电路,接上一路按键就可以实现开关机功能。
电源保护电路:
因为最小系统采用typec供电,为了避免因误插劣质充电器烧坏电路板的情况发生,我们需要给电路板输入口做过压过流保护电路。为提高电源系统可靠性,在VDD_3.3V电源网络上也增加了过压保护电路。
1.MP5016是一颗小封装带使能控制端的,过压过流保护芯片。过压保护点由MODE脚所借电阻决定,过流保护点由ILIMIT所接的电阻决定。
2.为确保单片机不被烧坏,这里我使用TL432芯片做了过压保护电路,当电压超过3.6V时Q1切断后级电路。
MCU外围电路:
MCU外围电路分为:复位,启动配置,晶振,片外FLASH,显示屏,扩展接口。
复位电路我这里使用SGM809B复位芯片,需要确保复位引脚在上电时序内均为低电平;
启动配置相关IO口需要注意MOD0需要拉低,MOD1需要拉高。其余BOOT相关引脚在上电时候要保持拉低状态,上电后就可以拿来用来;
如果使用片外FLASH则需要将GPIO_SD_B1_05悬空;
显示屏尺寸是1.3寸,分辨率是240*240,屏幕的pcb封装部分为了兼容老王家的屏做了调整。
代码调试:
代码调试使用的工具是官方软件MCUxpresso IDE,里面有很多RT1021的例程序。参考了其中的ADC和SPI 通讯部分;
值得一提的是config软件相当好用,配置的时候只需要搜索相关外设,然后选择参数即可。如果配置参数页面有出错的地方,软件会自动标红提示,非常方便。
其中ADC的相关配置如下图
上图中红框标出的地方一定要选,我在调试时漏选了,浪费了很长时间。
SPI的配置就比较简单了 ,这里我屏幕用的是SPI4接口,配置好IO口,SPI时钟源以及相关参数即可:
关键代码
代码调用了ADC接口,采集数据后,显示在屏幕上,结构简单直接贴代码:
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MIMXRT1021.h"
#include "fsl_debug_console.h"
#include "st7789tft.h"
#include "picture.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define DEMO_TEMP_MONITOR TEMPMON
#define DEMO_TEMP_LOW_HIGH_IRQn TEMP_LOW_HIGH_IRQn
#define DEMO_TEMP_PANIC_IRQn TEMP_PANIC_IRQn
#define DEMO_TEMP_LOW_HIGH_IRQHandler TEMP_LOW_HIGH_IRQHandler
#define DEMO_TEMP_PANIC_IRQHandler TEMP_PANIC_IRQHandler
#define DEMO_HIGH_ALARM_TEMP 42U
#define DEMO_LOW_ALARM_TEMP 40U
#define DEMO_CLOCK_SOURCE kCLOCK_AhbClk
#define DEMO_CLOCK_DIV kCLOCK_AhbDiv
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/* TODO: insert other include files here. */
#define EXAMPLE_LED_GPIO BOARD_INITPINS_st7798_bl_GPIO
#define EXAMPLE_LED_GPIO_PIN BOARD_INITPINS_st7798_bl_GPIO_PIN
#define cs_set GPIO_PinWrite(BOARD_INITPINS_st7798_cs_GPIO, BOARD_INITPINS_st7798_cs_GPIO_PIN, 1U);
#define cs_reset GPIO_PinWrite(BOARD_INITPINS_st7798_cs_GPIO, BOARD_INITPINS_st7798_cs_GPIO_PIN, 0U);
/* TODO: insert other definitions and declarations here. */
volatile bool g_pinSet = false;//状态机
lpspi_transfer_t masterXfer; //spi收发变量
/*
* @brief Application entry point.
*/
int main(void) {
float adc_value; //ADC转换结果
uint16_t adc0value;
adc_channel_config_t adcChannelConfigStruct; //ADC 通道配置结构体
uint16_t t;
/* Init board hardware. */
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
/* Init FSL debug console. */
BOARD_InitDebugConsole();
#endif
// EnableIRQ(DEMO_TEMP_LOW_HIGH_IRQn);
PRINTF("Hello World\n");
st7789_init();//屏幕初始化
delay(300);
LCD_Fill(0,0,240,240,0xffff); //清屏
LCD_ShowPicture(185,5,50,50,gImage_baocun);
/* Force the counter to be placed into memory. */
volatile static int i = 0 ;
/* Enter an infinite loop, just incrementing a counter. */
while(1) {
i++ ;
/* 'Dummy' NOP to allow source level single stepping of
tight while() loop */
__asm volatile ("nop");
/*ADC转换通道设置*/
adcChannelConfigStruct.channelNumber =0;//设置ADC转换通道对应的外部输入通道.,目前通道4
adcChannelConfigStruct.enableInterruptOnConversionCompleted = false; //使能转换完成后不产生中断,
ADC_SetChannelConfig(ADC1, 0, &adcChannelConfigStruct);//初始化ADC
while(ADC_GetChannelStatusFlags(ADC1,0)==0)
{
t++;
if(t>1000)
break;
}//等待转换结束
adc0value = ADC_GetChannelConversionValue(ADC1, 0);
adc_value=adc0value*3.3/4096;
if (g_pinSet)
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
LCD_ShowString(8,8,"init_is_ok!",0x0000,0xffff,24,0);
LCD_ShowFloatNum1(8,40,adc_value,3,0x0000,0xffff,32);
delay(4000);
g_pinSet = false;
}
else
{
g_pinSet = true;
}
}
return 0 ;
}
五、实现结果
读取63号引脚AD值,打印到屏幕上
六、遇到的问题
问题1:Jlink连接不上芯片。
解决思路:一般调试器连接不上单片机,可以从电源,复位电路,晶振电路,启动配置电路 这些方面排查。测试发现芯片自带DC-DC电源轨没有输出,检查原理图后发现有一个使能脚没有上拉。调整后jlink识别到单片机;
问题2: 使用NXP官方软件调试时,发现示例代码下载进去启动不了;
解决思路:判断是软件那里配置有问题。新建空的工程,写一个简单的点亮led的程序,发现程序可以执行。然后根据空工程的配置更新示例工程的配置。更新后可以执行代码。
七、芯片的优势和局限
优势:
芯片的优势很明显,外设丰富,主频可以跑到500MHz;
自带ON/OFF硬件电路,短按开机,长按5秒关机;
局限:
芯片内核是M7核,一般的调试工具还用不了;
100Pin的芯片用不了SDRAM,有些遗憾;