您尚未登录。

楼主 #1 2020-01-07 21:40:07

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

感谢韬哥发来的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元零售价。看起来性价比还可以。
        多余的便不作介绍,开发板直接上图。
FluxBB bbcode SWM181CBT6_Board
        板子上面资源不多,主要是:CH340G+芯片+20P大JTAG口。简单的例程调试基本上没有问题。支持一下国产MCU,思考使用什么姿势打开这款芯片的外设资源,后面再更贴。

最近编辑记录 LinjieGuo (2020-01-07 21:42:58)

离线

楼主 #2 2020-01-07 22:10:20

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

看了看资料,我们可以这样子如何快速上手芯片的开发:
1、从官网获取开发资料:点击进入官网
(1)芯片手册
(2)Keil芯片DFP包
(3)官方例程
(4)开发板原理图
(5)如何下载程序

最近编辑记录 LinjieGuo (2020-01-07 22:11:10)

离线

楼主 #3 2020-01-07 22:35:40

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

尝试使用ISP下载程序,但是官网下载的ISP程序无法成功握手连接上MCU,跟华心微特的朋友联系,ISP目前来说还未完善,所以暂时不支持,需要使用J-Link进行程序下载。

离线

楼主 #6 2020-01-09 13:01:52

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

------------------------------------------------------------------------------------------------
        尝试使用嵌入式点灯大法来打开这一款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灭。
        嵌入式点灯大法施展成功。


TEST1_20200109-2016.png

最近编辑记录 LinjieGuo (2020-01-09 14:58:19)

离线

楼主 #8 2020-01-09 15:38:48

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

尝试了解官方的工程架构,打开Keil,Target配置如下:
FluxBB bbcode 测试
我们使用的SWM181CBT6,拥有16KB SRAM,240KB Flash,所以我们可以修改一下。物尽其用。
查看数据手册上面的存储器映射表:
FluxBB bbcode 测试
填写Keil的配置(用于自动生成链接脚本)。
IROM 0X0000 0000,  0X0003 C000 ; IRAM  0X 2000 0000,0x0000 4000
上图:
FluxBB bbcode 测试
这样就能用上240KB的Flash,16KB SRAM了。

最近编辑记录 LinjieGuo (2020-01-09 15:41:27)

离线

楼主 #10 2020-01-11 10:33:59

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

观察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)

离线

楼主 #11 2020-01-11 10:41:25

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

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)

离线

楼主 #12 2020-01-11 15:15:24

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

尝试使用串口通讯进行通讯,我在原理图上面怎么找都找不到串口引脚。
翻查数据手册,发现并没有特定的串口引脚,芯片内部有一个神奇的数字信号引脚分配器——>PORTCON。
对于部分数字输入输出功能,可以配置到任意 I/O 引脚,以方便板级布局。包括如下功能:
 UARTn_TX           UARTn_RX
 I2Cn_SDA           I2Cn_CLK
 PWMx_OUT         PWM_BREAK
 COUNTERn_IN     CAPTURE_IN
 CAN_RX              CAN_TX
怎么用呢?我们看看下面这个图应该就明白了。
FluxBB bbcode 测试
意思是可用把上面列出来的数字类型引脚分配到任意的带FUNCTION功能的引脚上面。
那我们看看那些引脚是带有FUNCTION的呢?上图:
FluxBB bbcode 测试
看起来,除了电源引脚、晶振引脚、复位引脚,其余的引脚都支持配置为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)

离线

楼主 #14 2020-01-11 15:40:38

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

刚刚想用keil直接下载程序,便按官方教程,修改Jflash中的相关文件,但是keil还是无法下载,还是要使用官方的Jlink下载软件。
写好串口的程序,下载进去。
芯片没有任何反应。下载之前的点灯程序,按下按键,依然没有任何反应。
芯片似乎挂掉了,可能是由以下原因导致,
①按照官方的教程中修改Jlink的Device.xml文件(重装Jlink,没有解决问题,排除!)
②CH340G IO无法直连MCU IO导致芯片不正常,
③使用了下载软件的校验功能,虽然没有成功过,可能影响了内部的数据
④使用keil下载,虽然下载失败,可能影响了内部的数据
反正现在情况就是显示下载成功,但是没有出现想要的实验现象,具体原因未知。
FluxBB bbcode 测试
使用下载软件的校验功能,校验结果说不一致,到底是什么原因呢?
FluxBB bbcode 测试

最近编辑记录 LinjieGuo (2020-01-11 15:59:00)

离线

楼主 #16 2020-01-11 16:15:06

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

感谢@xiaohui的回复,下载https://whycan.cn/files/members/1390/Synwit_JFLASH-190304.rar的内容,解压后,复制到./Keil/ARM/Flash中,然后直接使用Keil下载程序,下载之前的点灯程序,成功点灯。目录如下:
FluxBB bbcode 测试

最近编辑记录 LinjieGuo (2020-01-11 16:16:45)

离线

楼主 #18 2020-01-11 18:35:04

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

LinjieGuo 说:

PA0(RX)-->TX
PA1(TX)-->RX

程序下载进去之后,串口调试助手上面没有任何数据,将2根线反过来,可用看到数据,说明上面这个接法是错的,应该修正为:
PA0(RX)-->RX
PA1(TX)-->TX
(此接法对应开发板上面的丝印,并非是芯片引脚的标识)

最近编辑记录 LinjieGuo (2020-01-11 18:51:24)

离线

楼主 #19 2020-01-11 18:51:03

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

既然串口能够发送数据,现在尝试使用串口来接收数据。串口接收数据使用中断方式,那么就要搞懂这款芯片的中断是怎么管理的。
我们一般写程序需要用到的是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的中断源可用来源于下表的任意一项。
FluxBB bbcode 测试
        ②IRQ16~31的中断源可用来源于下表的任意1项或者2项(注意:可用配置2项)
FluxBB bbcode 测试
        怎么配置一个IRQ指向的是什么源呢?
        还是看图,中断源的选择应该是由一个多路选择开关来决定的。
        对于IRQ0~15,由IRQx_SRC 寄存器的bit[6:0]选择一个中断源:
FluxBB bbcode 测试
        对于IQR16~31,可由IRQx_SRC 寄存器的bit[4:0]选择中断源1,bit[9:5]选择中断源2,可用配置2个中断源:
FluxBB bbcode 测试
       
(3)CPU处理中断事件
        CPU接收到中断信号(异常信号),自动跳转到对应的异常向量处执行代码(异常向量实际上就是一条跳转指令)

最近编辑记录 LinjieGuo (2020-01-11 20:04:39)

离线

楼主 #20 2020-01-13 10:57:04

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

知道了中断的原理,那么,怎么开中断,怎么安装中断向量呢?
(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)按照上面这种流程去初始化串口,代码如下:
FluxBB bbcode 测试
(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)

离线

楼主 #21 2020-01-13 12:52:41

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

串口的大概就是这样子了,一个单片机控制系统开发应该需要有一个时间基准,我们现在看看定时器怎么使用。
通过手册可以看出,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)

离线

楼主 #23 2020-01-13 15:59:25

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

基本框架已经定好了,忽然觉得24MHz是否有点慢了,修改工作频率,只需要修改这行代码即可。

#define SYS_CLK   	SYS_CLK_48MHz

然后官方的库函数会帮我们进行时钟初始化。
切记,千万不要修改下面三个宏,这三个宏,应该是定死的参数,官方库函数用的,如果变动,可能很多地方需要修改。

/*以下三个参数应该是不需要修改的,作为掩码一样使用,勿动*/
#define __HSI		(24000000UL)		//高速内部时钟
#define __LSI		(   32000UL)		//低速内部时钟
#define __HSE		(24000000UL)		//高速外部时钟

离线

楼主 #26 2020-01-13 20:17:22

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

======================================================
经过了上面的折腾,我们完成了这么多事情:
(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,使用串口打开设备,给板子上电。可以看到如下图:
FluxBB bbcode 测试
(2)输入help,回车:
FluxBB bbcode 测试
(3)使用LED
(可以使用TAB补全指令,使用上方向键回到上一条指令)
①输入LedGPA5 con:配置LED IO
②输入LedGPA5 on:点亮板子上面的LED
③输入LedGPA5 off:熄灭板子上面的LED
④输入LedGPA5 cat:查看LED的情况
上图:
FluxBB bbcode 测试

最近编辑记录 LinjieGuo (2020-01-13 23:07:12)

离线

楼主 #29 2020-02-23 00:57:52

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: 从零开发SWM181之----构建裸机控制台框架 [收到来自华芯微特--韬哥的SWM181CBT6开发板]

还没回去上班……

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn