WhyCan Forum(哇酷开发者社区)

我们能随心所欲"有问题百度(谷歌)一下", 这得感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn

您尚未登录。

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

从零开发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
累计积分: 226

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
累计积分: 226

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

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

离线

#4 2020-01-08 08:49:56

gui401
会员
注册时间: 2019-10-25
累计积分: 42

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

有支持12bit DAC的型号吗?想支持一下国产

离线

#5 2020-01-08 09:36:34

华芯微特
会员
注册时间: 2019-12-24
累计积分: 165

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

华芯微特特定发来贺电,恭喜LinjieGuo喜提开发板一块。

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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)

离线

#7 2020-01-09 14:56:14

华芯微特
会员
注册时间: 2019-12-24
累计积分: 165

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

gui401 说:

有支持12bit DAC的型号吗?想支持一下国产

有的呀,有SWM181系列,和190系列都是12bit的呢。如果想要了解,可查看官网或者联系官方人员哦,谢谢!

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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)

离线

#9 2020-01-10 09:01:21

华芯微特
会员
注册时间: 2019-12-24
累计积分: 165

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

默默地在一个地方守候着,时刻关注着,加油哦!

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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
累计积分: 226

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
累计积分: 226

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)

离线

#13 2020-01-11 15:17:38

红白机
会员
注册时间: 2020-01-02
累计积分: 133

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

发现并没有特定的串口引脚,芯片内部有一个神奇的数字信号引脚分配器——>PORTCON。
对于部分数字输入输出功能,可以配置到任意 I/O 引脚,以方便板级布局。

这个不错, 貌似ESP32也是这样。

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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)

离线

#15 2020-01-11 16:04:06

xiaohui
会员
注册时间: 2019-01-15
累计积分: 119

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

LinjieGuo 说:

刚刚想用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)

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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)

离线

#17 2020-01-11 16:17:48

xiaohui
会员
注册时间: 2019-01-15
累计积分: 119

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

LinjieGuo 说:

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

建议下次提问新开帖子哦。方便也遇到这个问题的人快速看到你的提问和别人也可以快速看到你遇到问题伸出援手!

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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
累计积分: 226

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
累计积分: 226

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
累计积分: 226

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)

离线

#22 2020-01-13 15:20:21

演技担当黄晓明
会员
注册时间: 2017-10-17
累计积分: 117

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

我的SWM项目已经完成,手里有个板子,哪位兄弟要的?运费到付

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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

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

#define SYS_CLK   	SYS_CLK_48MHz

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

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

离线

#24 2020-01-13 16:40:37

szchen2006
会员
注册时间: 2019-10-09
累计积分: 158

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

顶一下!

离线

#25 2020-01-13 18:22:05

华芯微特
会员
注册时间: 2019-12-24
累计积分: 165

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

每天来看看小哥哥啥进度哦!加油哦

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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)

离线

#27 2020-02-21 11:51:50

华芯微特
会员
注册时间: 2019-12-24
累计积分: 165

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

LinjieGuo 说:

======================================================
经过了上面的折腾,我们完成了这么多事情:
(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

持续根据项目哦

离线

#28 2020-02-21 15:08:45

华芯微特
会员
注册时间: 2019-12-24
累计积分: 165

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

LinjieGuo 说:

======================================================
经过了上面的折腾,我们完成了这么多事情:
(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

持续根据项目哦

离线

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

LinjieGuo
Moderator
注册时间: 2019-07-24
累计积分: 226

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

还没回去上班……

离线

#30 2020-04-22 09:19:30

v_8787
会员
注册时间: 2019-01-31
累计积分: 39

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

看介绍,还是有一些可玩性的,也准备申请一下来试试

离线

#31 2020-04-24 15:49:27

华芯微特
会员
注册时间: 2019-12-24
累计积分: 165

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

欢迎免费试用哦~~~

离线

页脚

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