感谢韬哥发来的SWM181CBT6开发板,板子是最小系统,我们仅仅是用于熟悉这个芯片,即使上面资源不多,也丝毫不影响我们对这个芯片外设进行开发。
对SWM181CBT6-LQFP48进行简单的性能介绍。
(1)内置16KB SRAM 120KB Flash
(2)32 位 ARM® Cortex™-M0 内核,可运行在48MHz
(3)SPI x 2 UART x4 I2C*2 CAN*1
8 通道 16 位 PWM 产生器
12 位 8 通道高精度 SAR ADC
16 位 6 通道高精度 SIGMA-DELTA ADC
24MHz、48MHz 精度可达 1%的片内时钟源
芯片淘宝官方店报价:4.6元零售价。看起来性价比还可以。
多余的便不作介绍,开发板直接上图。
板子上面资源不多,主要是:CH340G+芯片+20P大JTAG口。简单的例程调试基本上没有问题。支持一下国产MCU,思考使用什么姿势打开这款芯片的外设资源,后面再更贴。
最近编辑记录 LinjieGuo (2020-01-07 21:42:58)
离线
有支持12bit DAC的型号吗?想支持一下国产
离线
华芯微特特定发来贺电,恭喜LinjieGuo喜提开发板一块。
离线
------------------------------------------------------------------------------------------------
尝试使用嵌入式点灯大法来打开这一款MCU,看看点的灯亮不亮,速度快不快。
找到官方例程,.\GPIO\KeyLED,使用J-link上位机通用工具Synwit_Jlink_Download_Check_V1.5.exe将程序下载进MCU。
工程文件里面有个readme.txt:功能说明:按下接在PA4上的按键,则接在PA5上的LED亮;放开按键则LED灭!
程序下载非常成功,但是没有丝毫反应,灯似乎不亮。
按下S2,不亮;松开,不亮。
------------------------------------------------------------------------------------------------
仔细管擦,板子上面似乎有一些跳线位,打开原理图,一看,原来如此,MCU并没有和LED/KEY相连。
(1)使用一根杜邦线将GPA5和LED相连,
(2)使用一根杜邦线将GPA4和KEY相连。
重启单板,按下按键S2,LED亮;松开,LED灭。
嵌入式点灯大法施展成功。
最近编辑记录 LinjieGuo (2020-01-09 14:58:19)
离线
有支持12bit DAC的型号吗?想支持一下国产
有的呀,有SWM181系列,和190系列都是12bit的呢。如果想要了解,可查看官网或者联系官方人员哦,谢谢!
离线
尝试了解官方的工程架构,打开Keil,Target配置如下:
我们使用的SWM181CBT6,拥有16KB SRAM,240KB Flash,所以我们可以修改一下。物尽其用。
查看数据手册上面的存储器映射表:
填写Keil的配置(用于自动生成链接脚本)。
IROM 0X0000 0000, 0X0003 C000 ; IRAM 0X 2000 0000,0x0000 4000
上图:
这样就能用上240KB的Flash,16KB SRAM了。
最近编辑记录 LinjieGuo (2020-01-09 15:41:27)
离线
默默地在一个地方守候着,时刻关注着,加油哦!
离线
观察startup_xxx.s文件(启动文件),里面做了什么事情呢?
---------------------------------------------------------------------------------------------
(1)开辟栈,并使用标号__initial_sp获得栈顶。
Stack_Size EQU 0x800;
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
---------------------------------------------------------------------------------------------
(2)开辟堆,并使用__heap_limit获取堆的界限。
Heap_Size EQU 0x000;
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
此处明显堆的大小为0,这样的话,按道理来说是无法使用C库里面的malloc()函数分配内存的。
---------------------------------------------------------------------------------------------
(3)异常向量指定:RESET段。
AREA RESET, DATA, READONLY
__Vectors DCD Stack_Mem + Stack_Size ; Top of Stack 栈顶,等于__initial_sp
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0
DCD 0
DCD 0
DCD 0
DCD 0
DCD 0
DCD SRAM_SWITCH
DCD SVC_Handler ; SVCall Handler
DCD 0
DCD 0
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD IRQ0_Handler
DCD IRQ1_Handler
DCD IRQ2_Handler
DCD IRQ3_Handler
DCD IRQ4_Handler
DCD IRQ5_Handler
DCD IRQ6_Handler
DCD IRQ7_Handler
DCD IRQ8_Handler
DCD IRQ9_Handler
DCD IRQ10_Handler
DCD IRQ11_Handler
DCD IRQ12_Handler
DCD IRQ13_Handler
DCD IRQ14_Handler
DCD IRQ15_Handler
DCD IRQ16_Handler
DCD IRQ17_Handler
DCD IRQ18_Handler
DCD IRQ19_Handler
DCD IRQ20_Handler
DCD IRQ21_Handler
DCD IRQ22_Handler
DCD IRQ23_Handler
DCD IRQ24_Handler
DCD IRQ25_Handler
DCD IRQ26_Handler
DCD IRQ27_Handler
DCD IRQ28_Handler
DCD IRQ29_Handler
DCD IRQ30_Handler
DCD IRQ31_Handler
__Vectors_End
---------------------------------------------------------------------------------------------
为什么这样设定?
查看sct脚本:工程目录下的输入目录里面存在一个自动生成的KeyLED.sct链接脚本。
脚本的数据来源于,Target设置,作用:指定各段存放的位置。
LR_IROM1 0x00000000 0x00006000 { ; load region size_region
ER_IROM1 0x00000000 0x00006000 { ; 芯片Flash映射在0地址
*.o (RESET, +First) ;指定RESET段链接到头部
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00002000 { ; RW data
.ANY (+RW +ZI) ;变量,堆栈等链接到此处。
}
}
因为芯片内存过小,而且这个芯片不适合扩展内存等操作,在内存管理方面便不多做介绍。
最近编辑记录 LinjieGuo (2020-01-11 10:35:30)
离线
CPU上电后,芯片内部自动读取存放在Flash 0地址上面的栈顶地址进而设置堆栈指针。
CPU 内部电压稳定后,发生reset异常,自动跳转到异常的处理函数中。
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
LDR R0, =__main
BX R0
ENDP
可用看到,这里只有一种操作,那就是跳转到__main()函数里面执行了。
__main()和Main() (以前的ARM9使用ADS编写程序用到)是存在差异的,有兴趣自行百度进行科普。
------------------------------------------------------------------------------------------------------
在main()里面,首先便调用以下函数,设置芯片工作频率。
void SystemInit(void)
{
uint32_t i;
SYS->CLKEN |= (1 << SYS_CLKEN_OSC_Pos);
switch(SYS_CLK)
{
case SYS_CLK_24MHz: //0 内部高频24MHz RC振荡器
if(SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) //当前时钟是高频RC,修改高频RC时钟频率时需要先切到一个稳定时钟源
{
switchToRC32KHz();
}
switchToRC24MHz();
break;
case SYS_CLK_6MHz: //1 内部高频 6MHz RC振荡器
if(SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) //当前时钟是高频RC,修改高频RC时钟频率时需要先切到一个稳定时钟源
{
switchToRC32KHz();
}
switchToRC6MHz();
break;
case SYS_CLK_48MHz: //2 内部高频48MHz RC振荡器
if(SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) //当前时钟是高频RC,修改高频RC时钟频率时需要先切到一个稳定时钟源
{
switchToRC32KHz();
}
switchToRC48MHz();
break;
case SYS_CLK_12MHz: //3 内部高频12MHz RC振荡器
if(SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) //当前时钟是高频RC,修改高频RC时钟频率时需要先切到一个稳定时钟源
{
switchToRC32KHz();
}
switchToRC12MHz();
break;
case SYS_CLK_32KHz: //4 内部低频32KHz RC振荡器
if((SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) == 0)
{
switchToRC24MHz();
}
switchToRC32KHz();
break;
case SYS_CLK_XTAL: //5 外部XTAL晶体振荡器(2-30MHz)
if((SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) == 0)
{
switchToRC24MHz();
}
switchToXTAL();
break;
}
for(i = 0;i <10000;i++); //等待时钟稳定。。。
SystemCoreClockUpdate();
}
以上代码中,存在一条神奇的语句,可能要耗费CPU一点时间。
for(i = 0;i <10000;i++); //等待时钟稳定。。。
MCU IO引脚上电后会存在默认高电平/低电平等情况,如果板子设计时没有考虑到这个原因导致的影响,可用在这行语句之前指定引脚状态,减少影响。
--------------------------------------------------------------------------------------------------
展开宏:#define SYS_CLK SYS_CLK_24MHz
可用看到,官方例程里面,MCU默认工作于24MHz。
理论上,可用修改该宏定义为SYS_CLK_48MHz,将MCU工作频率设置为48MHz。但是不知道是否稳定,目前没有尝试。
#define SYS_CLK_24MHz 0 //0 内部高频24MHz RC振荡器
#define SYS_CLK_6MHz 1 //1 内部高频 6MHz RC振荡器
#define SYS_CLK_48MHz 2 //2 内部高频48MHz RC振荡器
#define SYS_CLK_12MHz 3 //3 内部高频12MHz RC振荡器
#define SYS_CLK_32KHz 4 //4 内部低频32KHz RC振荡器
#define SYS_CLK_XTAL 5 //5 外部XTAL晶体振荡器(2-30MHz)
最近编辑记录 LinjieGuo (2020-01-11 10:52:41)
离线
尝试使用串口通讯进行通讯,我在原理图上面怎么找都找不到串口引脚。
翻查数据手册,发现并没有特定的串口引脚,芯片内部有一个神奇的数字信号引脚分配器——>PORTCON。
对于部分数字输入输出功能,可以配置到任意 I/O 引脚,以方便板级布局。包括如下功能:
UARTn_TX UARTn_RX
I2Cn_SDA I2Cn_CLK
PWMx_OUT PWM_BREAK
COUNTERn_IN CAPTURE_IN
CAN_RX CAN_TX
怎么用呢?我们看看下面这个图应该就明白了。
意思是可用把上面列出来的数字类型引脚分配到任意的带FUNCTION功能的引脚上面。
那我们看看那些引脚是带有FUNCTION的呢?上图:
看起来,除了电源引脚、晶振引脚、复位引脚,其余的引脚都支持配置为FUNCTION功能。
怎么配置呢?我们尽量不要关注寄存器层,直接使用官方的例程上面的库接口:
PORT_Init(PORTA, PIN0, FUNMUX_UART0_RXD, 1); //GPIOA.0配置为UART0输入引脚
PORT_Init(PORTA, PIN1, FUNMUX_UART0_TXD, 0); //GPIOA.1配置为UART0输出引脚
来到这里,终于明白为什么开发板上面CH340G的两根串口线不直连MCU了。
初始化串口,使用官方的代码,略微修改波特率为115200。
void SerialInit(void)
{
UART_InitStructure UART_initStruct;
PORT_Init(PORTA, PIN0, FUNMUX_UART0_RXD, 1); //GPIOA.0配置为UART0输入引脚
PORT_Init(PORTA, PIN1, FUNMUX_UART0_TXD, 0); //GPIOA.1配置为UART0输出引脚
UART_initStruct.Baudrate = 115200;
UART_initStruct.DataBits = UART_DATA_8BIT;
UART_initStruct.Parity = UART_PARITY_NONE;
UART_initStruct.StopBits = UART_STOP_1BIT;
UART_initStruct.RXThreshold = 3;
UART_initStruct.RXThresholdIEn = 0;
UART_initStruct.TXThreshold = 3;
UART_initStruct.TXThresholdIEn = 0;
UART_initStruct.TimeoutTime = 10;
UART_initStruct.TimeoutIEn = 0;
UART_Init(UART0, &UART_initStruct);
UART_Open(UART0);
}
重定位编译器C库的标准输出:
int fputc(int ch, FILE *f)
{
UART_WriteByte(UART0, ch);
while(UART_IsTXBusy(UART0));
return ch;
}
这样就能够愉快的使用printf(...)函数进行格式化打印数据了。
-----------------------------------------------------------------------------------------
直接把MCU串口引脚连接到CH340G的串口引脚上,不知道会不会烧掉
PA0(RX)-->TX
PA1(TX)-->RX
最近编辑记录 LinjieGuo (2020-01-11 15:19:31)
离线
发现并没有特定的串口引脚,芯片内部有一个神奇的数字信号引脚分配器——>PORTCON。
对于部分数字输入输出功能,可以配置到任意 I/O 引脚,以方便板级布局。
这个不错, 貌似ESP32也是这样。
离线
刚刚想用keil直接下载程序,便按官方教程,修改Jflash中的相关文件,但是keil还是无法下载,还是要使用官方的Jlink下载软件。
写好串口的程序,下载进去。
芯片没有任何反应。下载之前的点灯程序,按下按键,依然没有任何反应。
芯片似乎挂掉了,可能是由以下原因导致,
①按照官方的教程中修改Jlink的Device.xml文件(重装Jlink,没有解决问题,排除!)
②CH340G IO无法直连MCU IO导致芯片不正常,
③使用了下载软件的校验功能,虽然没有成功过,可能影响了内部的数据
④使用keil下载,虽然下载失败,可能影响了内部的数据
反正现在情况就是显示下载成功,但是没有出现想要的实验现象,具体原因未知。
使用下载软件的校验功能,校验结果说不一致,到底是什么原因呢?
最近编辑记录 LinjieGuo (2020-01-11 15:59:00)
离线
刚刚想用keil直接下载程序,便按官方教程,修改Jflash中的相关文件,但是keil还是无法下载,还是要使用官方的Jlink下载软件。
写好串口的程序,下载进去。
芯片没有任何反应。下载之前的点灯程序,按下按键,依然没有任何反应。
芯片似乎挂掉了,可能是由以下原因导致,
①按照官方的教程中修改Jlink的Device.xml文件(重装Jlink,没有解决问题,排除!)
②CH340G IO无法直连MCU IO导致芯片不正常,
③使用了下载软件的校验功能,虽然没有成功过,可能影响了内部的数据
④使用keil下载,虽然下载失败,可能影响了内部的数据
反正现在情况就是显示下载成功,但是没有出现想要的实验现象,具体原因未知。
https://whycan.cn/files/members/1845/DownloadPt_1.png
使用下载软件的校验功能,校验结果说不一致,到底是什么原因呢?
https://whycan.cn/files/members/1845/DownloadPt_2.png
需要https://whycan.cn/files/members/1390/Synwit_JFLASH-190304.rar把解压后里面所有的flm文件放到keil对应存放flm的地方,重新打开keil并且配置下载器的选项选择对应的芯片。flm是下载算法
最近编辑记录 xiaohui (2020-01-11 16:05:13)
离线
离线
感谢@xiaohui的回复,下载https://whycan.cn/files/members/1390/Synwit_JFLASH-190304.rar的内容,解压后,复制到./Keil/ARM/Flash中,然后直接使用Keil下载程序,下载之前的点灯程序,成功点灯。目录如下:
https://whycan.cn/files/members/1845/Dir_FLM.png
建议下次提问新开帖子哦。方便也遇到这个问题的人快速看到你的提问和别人也可以快速看到你遇到问题伸出援手!
离线
PA0(RX)-->TX
PA1(TX)-->RX
程序下载进去之后,串口调试助手上面没有任何数据,将2根线反过来,可用看到数据,说明上面这个接法是错的,应该修正为:
PA0(RX)-->RX
PA1(TX)-->TX
(此接法对应开发板上面的丝印,并非是芯片引脚的标识)
最近编辑记录 LinjieGuo (2020-01-11 18:51:24)
离线
既然串口能够发送数据,现在尝试使用串口来接收数据。串口接收数据使用中断方式,那么就要搞懂这款芯片的中断是怎么管理的。
我们一般写程序需要用到的是IRQ异常,也就是中断请求。从启动文件上看,异常向量表里面有32个IRQ异常向量,命名规则为IRQx_Handler(x=0~31)。
一般中断的流程如下:
外设产生中断-->中断管理器-->CPU
(1)外设产生中断
这款芯片能产生中断的外设有那些呢?
手册上面有个表,上面列举了非常的中断号,不知道怎么用,但是大概能回答本问题。
GPIO、PWM_HALT、IIC0、IIC1、WDT、ADC0、BOD、TIMER_PULSE、DMA、
CACHE、Flash、CAN、CMP、ADC1、HALL、UART0~3、PWM_CH0~3等等...
(2)中断管理器
这款芯片的中断管理器怎么管理外设产生的中断信号呢?
这款芯片的IRQx_Handler(x=0~31)异常向量,默认是不指定中断源的,需要我们配置它的中断信号来源。
①IRQ0~15的中断源可用来源于下表的任意一项。
②IRQ16~31的中断源可用来源于下表的任意1项或者2项(注意:可用配置2项)
怎么配置一个IRQ指向的是什么源呢?
还是看图,中断源的选择应该是由一个多路选择开关来决定的。
对于IRQ0~15,由IRQx_SRC 寄存器的bit[6:0]选择一个中断源:
对于IQR16~31,可由IRQx_SRC 寄存器的bit[4:0]选择中断源1,bit[9:5]选择中断源2,可用配置2个中断源:
(3)CPU处理中断事件
CPU接收到中断信号(异常信号),自动跳转到对应的异常向量处执行代码(异常向量实际上就是一条跳转指令)
最近编辑记录 LinjieGuo (2020-01-11 20:04:39)
离线
知道了中断的原理,那么,怎么开中断,怎么安装中断向量呢?
(1)使能外设中断
不同的外设拥有不同的中断,具体情况看对应外设的寄存器。
(2)编写中断服务函数
IRQ中断一共有32个,分别是IRQ0~IRQ31。以IRQ0为例:
void IRQ0_Handler(void)
{
//此处添加代码(判断中断标志,并处理)
}
(3)连接中断服务函数
①配置IRQ的中断源
②设置其优先级
③使能该中断
这三步操作,官方已经实现了操作库,以串口为例:
IRQ_Connect(IRQ0_15_UART0, IRQ0_IRQ, 1);
这样就能将串口0的中断连接到IRQ0,并且将其优先级设置为1。(优先级可设置为0~3,其中0为最高优先级)
---------------------------------------------------------------------------------------------------------------------------
以串口0为例,我们使能其接收中断,然后在中断中将接收的数据写入缓冲区。
SWM181的串口外设寄存器跟其他的芯片有一点点不一样,但是我们按照常规的方式来操作,便能找到共同点:
(1)使能外设时钟
(2)使能IO口时钟
(3)配置引脚功能
(4)配置串口通讯格式:波特率、数据位、停止位、校验位等...
(5)使能发送功能/接收功能
(6)使能发送中断/接收中断
(7)使能串口外设
--------------------------------------------------------
(1)按照上面这种流程去初始化串口,代码如下:
(2)编写中断服务函数:
void __irqUart0_RX(void)
{
u32 dat;
/*--接收中断或接收超时中断--*/
if(UART_INTRXThresholdStat(UART0) || UART_INTTimeoutStat(UART0)) //串口接收FIFO中断或者接收超时中断
{
while(UART_IsRXFIFOEmpty(UART0) == 0) //FIFO非空则不断提取数据
{
if(UART_ReadByte(UART0, &dat) == 0) //提取一个数据
{
printf("%c \r\n",dat); //将提取到得数据打印出来
}
}
}
}
最近编辑记录 LinjieGuo (2020-01-13 12:02:56)
离线
串口的大概就是这样子了,一个单片机控制系统开发应该需要有一个时间基准,我们现在看看定时器怎么使用。
通过手册可以看出,SWM181内部的定时器情况应该如下:
①1个24位系统滴答定时器
②4个通用32位定时器
③一个32位计数器
-----------------------------------------------------------------
按老套路来走,定时器的使用流程,一般是这样:
(1)设置定时器内部计数器的时钟源
(2)设置计数器的计数方式:自加/自减
(3)设置计数器的装载缓冲器(初值):
(4)使能溢出(自加)/置零(自减)中断
(5)使能定时器运行
-----------------------------------------------------------------
看看官方例程代码是怎么初始化系统滴答定时器的:
官方的库函数配置方法就一行代码:
SysTick_Config(SystemCoreClock/4); //每0.25秒钟触发一次中断
对应的系统滴答定时器中断代码,只需要写成以下格式便可:
void SysTick_Handler(void)
{
//代码
}
-----------------------------------------------------------------
问:上面这行代码为什么这样配置就可以得到"每0.25s触发一次中断"的效果呢?
我们需要了解系统滴答定时器的输入时钟源是什么?系统滴答定时器位于M0架构内部,跟我们这款MCU的外设设计无关,想要知道具体情况,应该翻阅M0架构的相关文档。暂且不做讨论。
我们追踪代码可以得知:
#define __HSI (24000000UL) //高速内部时钟
uint32_t SystemCoreClock = __HSI;
SysTick_Config(SystemCoreClock/4); //每0.25秒钟触发一次中断
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
从代码可以看出,ticks就是定时器初值。
而且翻阅手册,得知:SysTick定时器是一个24位自减定时器。
我们只需要将(SystemCoreClock/4)再除以250,应该就可以将系统滴答定时器,配置为1ms触发一次中断。代码如下:
SysTick_Config(SystemCoreClock/4/250); //每1ms钟触发一次中断
中断服务程序里面放一个变量累加:
u32 gSysTick=0; //32位可以描述49天,若非项目要求,推荐使用32位,效率较高
void SysTick_Handler(void)
{
gSysTick++;
}
编写一个函数用于获取系统滴答值。
#define SysTick_t u64
SysTick_t GetSysTick(void)
{
SysTick_t temp=0;
/*关中断*/
SysTick->CTRL &= ~(1<<1);
temp = gSysTick;
/*开中断*/
SysTick->CTRL |= (1<<1);
return temp;
}
定义一下系统滴答的参数结构:
typedef struct{
SysTick_t Diff; //时间差
SysTick_t Old; //旧的滴答值
SysTick_t New; //新的滴答值
}TimeOut_t;
某些平台申请的变量,默认值非0,我们编写一个函数用于初始化这个结构。
/*--初始化软超时结构---------------------*/
void TimeOutArgsInit(TimeOut_t *tTimeOut)
{
tTimeOut->Diff = 0;
tTimeOut->New = 0;
tTimeOut->Old = 0;
}
这种结构,在使用单片机写裸机状态机程序时,非常好用。结构分明,具体后面再说。
-------------------------------------------------------------------------------------
最近编辑记录 LinjieGuo (2020-01-13 15:15:09)
离线
我的SWM项目已经完成,手里有个板子,哪位兄弟要的?运费到付
离线
基本框架已经定好了,忽然觉得24MHz是否有点慢了,修改工作频率,只需要修改这行代码即可。
#define SYS_CLK SYS_CLK_48MHz
然后官方的库函数会帮我们进行时钟初始化。
切记,千万不要修改下面三个宏,这三个宏,应该是定死的参数,官方库函数用的,如果变动,可能很多地方需要修改。
/*以下三个参数应该是不需要修改的,作为掩码一样使用,勿动*/
#define __HSI (24000000UL) //高速内部时钟
#define __LSI ( 32000UL) //低速内部时钟
#define __HSE (24000000UL) //高速外部时钟
离线
顶一下!
离线
每天来看看小哥哥啥进度哦!加油哦
离线
======================================================
经过了上面的折腾,我们完成了这么多事情:
(1)设置CPU工作时钟
(2)使用GPIO
(3)使用串口
(4)使用中断
(5)使用系统定时器
那么,我们就利用这些外设,编写一个类似命令行一样的工程框架,用于调试项目吧。
======================================================
放出工程:Framework_V1.0.7z
(因代码写得乱,移植可能有些困难,有其他平台需要移植的可以联系我,如果哪位朋友优化好结构,希望也可以分享出来)
如果是使用同样的芯片,可以不关注控制台的实现,直接使用lib工程:
Framework_V1.0_lib.7z
测试:
(1)连接串口线
GPA0配置为RX-->连接官方开发板子上面上面丝印RX
GPA1配置为TX-->连接官方开发板子上面上面丝印TX
(2)连接LED线
GPA5-->LED
(1)打开putty,使用串口打开设备,给板子上电。可以看到如下图:
(2)输入help,回车:
(3)使用LED
(可以使用TAB补全指令,使用上方向键回到上一条指令)
①输入LedGPA5 con:配置LED IO
②输入LedGPA5 on:点亮板子上面的LED
③输入LedGPA5 off:熄灭板子上面的LED
④输入LedGPA5 cat:查看LED的情况
上图:
最近编辑记录 LinjieGuo (2020-01-13 23:07:12)
离线
======================================================
经过了上面的折腾,我们完成了这么多事情:
(1)设置CPU工作时钟
(2)使用GPIO
(3)使用串口
(4)使用中断
(5)使用系统定时器
那么,我们就利用这些外设,编写一个类似命令行一样的工程框架,用于调试项目吧。
======================================================
放出工程:Framework_V1.0.7z
(因代码写得乱,移植可能有些困难,有其他平台需要移植的可以联系我,如果哪位朋友优化好结构,希望也可以分享出来)
如果是使用同样的芯片,可以不关注控制台的实现,直接使用lib工程:
Framework_V1.0_lib.7z
测试:
(1)连接串口线
GPA0配置为RX-->连接官方开发板子上面上面丝印RX
GPA1配置为TX-->连接官方开发板子上面上面丝印TX
(2)连接LED线
GPA5-->LED(1)打开putty,使用串口打开设备,给板子上电。可以看到如下图:
https://whycan.cn/files/members/1845/console_bootpt_1.png
(2)输入help,回车:
https://whycan.cn/files/members/1845/console_bootpt_2.png
(3)使用LED
(可以使用TAB补全指令,使用上方向键回到上一条指令)
①输入LedGPA5 con:配置LED IO
②输入LedGPA5 on:点亮板子上面的LED
③输入LedGPA5 off:熄灭板子上面的LED
④输入LedGPA5 cat:查看LED的情况
上图:
https://whycan.cn/files/members/1845/console_bootpt_3.png
持续根据项目哦
离线
======================================================
经过了上面的折腾,我们完成了这么多事情:
(1)设置CPU工作时钟
(2)使用GPIO
(3)使用串口
(4)使用中断
(5)使用系统定时器
那么,我们就利用这些外设,编写一个类似命令行一样的工程框架,用于调试项目吧。
======================================================
放出工程:Framework_V1.0.7z
(因代码写得乱,移植可能有些困难,有其他平台需要移植的可以联系我,如果哪位朋友优化好结构,希望也可以分享出来)
如果是使用同样的芯片,可以不关注控制台的实现,直接使用lib工程:
Framework_V1.0_lib.7z
测试:
(1)连接串口线
GPA0配置为RX-->连接官方开发板子上面上面丝印RX
GPA1配置为TX-->连接官方开发板子上面上面丝印TX
(2)连接LED线
GPA5-->LED(1)打开putty,使用串口打开设备,给板子上电。可以看到如下图:
https://whycan.cn/files/members/1845/console_bootpt_1.png
(2)输入help,回车:
https://whycan.cn/files/members/1845/console_bootpt_2.png
(3)使用LED
(可以使用TAB补全指令,使用上方向键回到上一条指令)
①输入LedGPA5 con:配置LED IO
②输入LedGPA5 on:点亮板子上面的LED
③输入LedGPA5 off:熄灭板子上面的LED
④输入LedGPA5 cat:查看LED的情况
上图:
https://whycan.cn/files/members/1845/console_bootpt_3.png
持续根据项目哦
离线
看介绍,还是有一些可玩性的,也准备申请一下来试试
离线
欢迎免费试用哦~~~
离线