电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
Keil开发SWM320芯片的入门教程
分 享
扫描二维码分享
Keil开发SWM320芯片的入门教程
SWM320
Keil开发
教程
xukejing
关注
发布时间: 2019-07-04
丨
阅读: 3644
本人非常荣幸成为芯吧客社区首批评测松果派One的用户,也感谢松果派社区给我带来这个好玩的小板子。松果派One的主控芯片是国产ARM Cortex-M4,型号为SWM320,来自华芯威特(synwit)。 在不久前,我们已经对松果派One做了初步的评测,但是只测试了MicroPython的开发。详情见本人上一篇大作**《松果派ONE,基于国产ARM Cortex-M4》**。 对于初级爱好者,MicroPython是个非常容易上手的编程环境。然而,大多数老司机还是喜欢用c语言开发的,他们使用使用keil作为IDE,真的好高大上啊。各位正在用MicroPython的小伙伴们是否也想学学keil开发呢?今天,机会来了,我们要做一个小小的教程,展示一下SWM320芯片的Kei开发。 Keil从5.0版本之后通过安装对应单片机的pack提供对芯片的支持,安装Synwit.SWM32_DFP.1.0.0.pack后在Keil 5中新建工程可以直接选择Synwit SWM系列芯片,且软件会根据所选型号自动正确设置Flash/RAM大小、程序烧写算法、SVD仿真文件等内容。安装方法很简单,点击工具栏“Pack Installer”按钮 ,在弹出窗口中通过菜单“File->Import..”选中Synwit.SWM32_DFP.1.0.0.pack,点击“打开”按钮就安装了。 这是篇入门教程,既然涉及到硬件相关(点灯),那么硬件电路是有必要介绍一番,虽然点灯的硬件是再简单不过了。我们把一个LED与电阻串联后接在A0引脚与GND之间。当程序初始化A0引脚为输出并设置为高电平以后,A0引脚与GND之间会产生一个3.3V电压。注意图中LED的方向,LED是有极性的,正向导通时候才能发光。另外,为了保护LED(也对SWM320好),我们加了一个100欧的限流电阻。 ![点灯原理图](https://cf02.ickimg.com/bbsimages/201907/310ea1ab224c8521ea41608b8283aa5e.jpg "点灯原理图") 这个限流电阻的估算方式是这样的:当一个LED与电阻串联的电路两端加载3.3V电压以后;假设电阻分压1.5V(我们这次用的这个LED的正向压降约等于1.8V,则电阻分压为3.3-1.8=1.5V);一般来说,LED的电流设置在5~20毫安都是可以的,15毫安时候就可以把LED点得比较亮了;因为LED与电阻是串联关系,电阻上的电流也是15毫安(即0.015安);假设前面这些条件成立,可推算电阻的阻值为100欧(1.5/0.015=100欧)。 下面,让我们打开Keil,开始今天的教程吧。我给这个教程取名为“定时HelloWorld”,即:**定时器触发的GPIO翻转和串口输出**。 SWM320的函数封装与STM32是相似的,如果您已经玩过STM32,今天这个教程学起来应该是势如破竹的,不会遇到任何挫折。 首先,新建SWM320工程,新建一个main文件,如下图所示: ![](https://cf02.ickimg.com/bbsimages/201907/385addc7869c99289e6c8d664e62740c.jpg) 与过去的STM32程序一样,SWM320也需要引用自己的头文件,文件名叫SWM320.h,然后你就可以使用SystemInit或GPIO_Init这样的函数了。 其中,GPIO_Init函数控制引脚方向、上拉电阻和下拉电阻。GPIO_Init函数第一个输入变量指定GPIO端口,有效值包括GPIOA,GPIOB,GPIOC,GPIOM,GPION,GPIOP。如果我们想控制A0,这个输入变量要赋值GPIOA。第二个输入变量指定GPIO引脚,有效值包括PIN0,PIN1,PIN2等等。我们想控制A0,所以这个输入变量要赋值PIN0。第三个输入变量定义引脚方向,0输入,1输出。我们要输出高电平点灯,所以这个变量要赋值1。第四个输入变量定义上拉电阻,0关闭上拉,1开启上拉。我们点灯不要上拉电阻,所以要赋值0。第五个输入变量控制下拉电阻,0关闭下拉,1开启下拉。我们点灯也不要下拉电阻,所以这个变量要赋值0。 另外,当需要使用串口时,我们习惯上会新建一个串口初始化函数SerialInit(void),定义串口引脚和波特率。下面这个函数,定义串口为A2和A3引脚,定义串口波特率38400: ![](https://cf02.ickimg.com/bbsimages/201907/a8b0ebd470b81fda3fd282b3314e0e5b.jpg) SWM320的很多GPIO引脚除了数字GPIO功能,还支持FUNx配置功能,奇数的GPIO引脚GPI支持FUNA功能,偶数的GPIO引脚支持FUNB功能,除了A12/B12/N18/N19无FUNx配置功能。FUNA功能的引出脚可以通过重映射从任意一个支持FUNA的管脚引出;FUNB功能也是一样。 ![功能](https://cf02.ickimg.com/bbsimages/201907/7474211968aebbcc670f3a4a113393f7.jpg "功能") 这可以给你们的项目带来更高的容错率。比如,有一天,某个不靠谱的硬件工程小白做PCB把串口或I2C管脚给引错了,先不要着急烧掉PCB跑路,交给程序小哥看看,也许还能补救一下。如果需要串口TXD或I2C SDA的引脚虽然引错了但正好在支持FUNA的管脚上,且需要串口RXD或I2C SDC的引脚也引在支持FUNB的管脚上了,那你们的项目还有救! ![](https://cf02.ickimg.com/bbsimages/201907/63a9359be0895bde021d10fe80221de3.jpg) 扯远了,小伙伴们,我们收! 继续说说串口初始化函数里面的细节。(下面这段话,小伙伴们不用死抠里面的细节,串口初始化之所以封装成函数就是为了方便大家直接拷贝过去用的) 为了用UART_Open函数打开UART0(串口0),先要用UART_Init函数初始化UART0。UART_Init函数有两个输入变量,第一个是串口0的寄存器地址(APB_BASE + 0x10000)。UART_Init函数第二个变量是个结构体变量,包含10个子变量,第1个子变量是波特率,是个32位变量,第2到第10个子变量都是8位的;第2子变量是数据位数,可取值UART_DATA_8BIT或UART_DATA_9BIT;第3子变量是奇偶校验位,可取值UART_PARITY_NONE、UART_PARITY_ODD、UART_PARITY_EVEN、UART_PARITY_ONE、UART_PARITY_ZERO;第4子变量是停止位位数,可取值UART_STOP_1BIT、UART_STOP_2BIT;第5个RXThreshold代表RX FIFO大于多少个数据出发中断,可取值0-7,它只有在第6个RXThresholdIEn被启用(设为1)时才起作用,这里我们不启用该中断;第7和第8是TX中断控制,与RX相反的是,TX中断的触发机制是TX FIFO中数据小于TXThreshold时触发中断。第9和第10分别是Timeout超时时间和是否启用超时中断。以上这几个中断我们都没用到。我们设计用A3和A2作为UART0的TX和RX管脚,于是用PORT_Init函数设置引脚功能。其中,偶数的A2管脚可以使用FUNMUX0里的功能,作为UART0的RXD引脚;奇数的A3管脚可以使用FUNMUX1里的FUNMUX1_UART0_TXD。PORT_Init函数输入变量由3个,第1个变量指定PORT端口,第2个指定PORT引脚,第3个指定端口引脚要设定的功能,第4个数字输入使能。有一个注意事项,当引脚编号为偶数时只能用FUNMUX0(FUNB),奇数的话就只能用FUNMUX1(即FUNA),另外A12/B12/N18/N19无FUNx配置功能。 串口打印时,我们如果想使用printf函数,可以把fputc重定向一下 ![](https://cf02.ickimg.com/bbsimages/201907/0175078caf5274d0d4d4087aaf8dd3e2.jpg) 接着,我们一起写一下main函数。必须先完成SystemInit函数的初始化,才能对串口进行初始化、GPIO初始化,或定时器初始化。GPIO初始化与定时器初始化之间,本身并没有先后的必要性,但是我们今天的这个程序例子要定时触发GPIO翻转和串口输出,为了提高程序的稳定性,我们先把串口和GPIO完成初始化,然后再初始化定时器。我们可以想象得到,当定时器被初始化以后,定时触发函数就会每隔固定间隔被触发一次,而串口输出和GPIO操作的代码是在触发函数里的;如果串口和GPIO初始化函数的执行速度比较慢,还没完成初始化,但是定时触发函数已经开始执行了,就会对程序的稳定性造成影响;所以我们要尽量规避这种隐藏的BUG。我们的Main函数代码如下图所示: ![](https://cf02.ickimg.com/bbsimages/201907/0f307079c9b84e74c002908058c33c2d.jpg) 其中,当完成串口初始化以后,先打印Hello World输出调试信息。然后把A0引脚设置为输出(该引脚接了LED)。初始化定时器0,每隔0.5秒触发一次,然后把定时器打开。 然后,是定时器0的触发函数,每隔0.5秒进入一次。我们把需要的操作写进去,分别是A0引脚电平翻转和串口打印“TogglePin” ![](https://cf02.ickimg.com/bbsimages/201907/767fb3ef5015df52fb6b3462f77686b9.jpg) 有心急的已经坐不住了,要点build按钮编译了。 小伙伴们不要着急! 在编译前,还有一步设置,把输出hex打上勾,这样就可以生成用于串口下载的hex文件了。 ![](https://cf02.ickimg.com/bbsimages/201907/0f3e435ff08c60759968f31fdc9bd233.jpg) 编译一下,生成hex文件。 ![](https://cf02.ickimg.com/bbsimages/201907/bb5b36e2d57707157f9dda3251872fc6.jpg) 注意上图那个**0 Error,0 Warning**,这是程序员的骄傲。 接着,打开串口下载工具,并把板子的串口接上(烧写前需要把板子启动到ISP模式) ![](https://cf02.ickimg.com/bbsimages/201907/4f80236091b54a27b1fad38de6487c5e.jpg) 握手后自动烧写,会有提示“下载完成” ![](https://cf02.ickimg.com/bbsimages/201907/d384b2d036ffe905d3442eca01c44a1c.jpg) 程序是不是正常跑起来了呢? 打开串口调试助手,可以看到每个0.5秒的输出字符,字符与程序里的代码一致。(如果没有输出,按一下reset重启板子) ![](https://cf02.ickimg.com/bbsimages/201907/2a5c7c98cf6d6ad6bb4c23490d4bffc4.jpg) 我的板子上已经焊了led,所以程序一开始运行,灯就会亮起,一闪一闪的。 ![](https://cf02.ickimg.com/bbsimages/201907/f30bdb5ca85a22d76c4ebca249ef3416.jpg) 中断函数TIMR0_Handler每隔0.5秒就会进入一次,通过GPIO_InvBit函数翻转GPIO电平,使LED闪烁,让板子仿佛拥有了心跳一样。 这一颗LED,就像一个生命,在心里最幽静的地方,踽踽独行,他日化蝶飞去。你看它是不是跟你很像,只有拼命往前飞,最后飞到哪里,你自己也不知道。 而我们芯吧客,只是你路上的一个过客。今日有幸与我们同行,教了你一些微不足道的小技术;但是我们不能陪你走到最后,更多的路只能你一个人走。当然,碰到了便是缘,即使到文章的最后,也请心怀感激地点赞告别吧。
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
6
)
xukejing
擅长:其他应用
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交