打印
[Kinetis]

史上最全的kinetis资料

[复制链接]
楼主: 偏爱番茄酱
手机看帖
扫描二维码
随时随地手机跟帖
21
非常感谢楼主
再接再厉

使用特权

评论回复
22
LG2012GG| | 2015-7-18 11:03 | 只看该作者
史上最全也看不到什么啊

使用特权

评论回复
23
偏爱番茄酱|  楼主 | 2015-7-19 15:22 | 只看该作者
仙女山 发表于 2015-7-16 15:53
非常感谢楼主
再接再厉

谢谢

使用特权

评论回复
24
偏爱番茄酱|  楼主 | 2015-7-19 15:23 | 只看该作者
仙女山 发表于 2015-7-16 15:53
非常感谢楼主
再接再厉

谢谢:):):)

使用特权

评论回复
25
偏爱番茄酱|  楼主 | 2015-7-19 15:23 | 只看该作者
LG2012GG 发表于 2015-7-18 11:03
史上最全也看不到什么啊

你想看到什么???

使用特权

评论回复
26
偏爱番茄酱|  楼主 | 2015-7-19 15:25 | 只看该作者
使用Kinetis系列中UART的IDLE Line功能识别帧结束

使用特权

评论回复
27
偏爱番茄酱|  楼主 | 2015-7-19 15:25 | 只看该作者
使用串口接收连续的一帧数据是我们平时比较常用到的一种方式(通过485或者232总线),而且往往这一帧数据的长度不确定,实现这种功能如果我们使用传统的接收中断方式的话会带来非常频繁的中断,查询方式的话则会造成系统大的延时,总之,这两种传统的方式都会对系统的实时性有较大的影响(频繁的中断或者大延时都会引起一些任务得不到实时响应)。

使用特权

评论回复
28
偏爱番茄酱|  楼主 | 2015-7-19 15:25 | 只看该作者
飞思卡尔Kinetis系列的UART模块自带IDLE Line即总线空闲检测功能,如下图。这个IDLE Line detection和DMA巧妙结合起来可以很好的解决上述的问题,即当连续的一帧数据发送过来时(长度不确定),可以通过DMA将数据存放到RAM区的Buffer中(事先给Buffer预留一定的空间),当一帧数据发送完成时IDLE Detection功能会从最后一个数据的STOP位开始检测,当检测到连续10或者13个高电平时,即表示没有start位过来了,即判断上一帧数据已经传输完毕,此时UART可以产生IDLE Line中断(即在整个传送过程中只有这一次中断),在此中断中可以置一个数据帧接收完成标志,然后在主程序可以对接收到的数据进行解包处理。

使用特权

评论回复
29
偏爱番茄酱|  楼主 | 2015-7-19 15:26 | 只看该作者
不过需要注意的是,DMA目标空间的buffer长度在实际使用中必须要大于外部总线有可能发送过来的最大长度(即先评估好外部总线最大可能发送的数据长度,最后留一定余量,前提是确保RAM空间足够大),否则buffer存满了之后会被剩下的数据覆盖掉。当然如果RAM不够大的话实际上也是可以解决的(即小RAM的芯片),则可以将RAM分成两个大小相等的小数据空间,然后在第一个小块存满之后产生DMA中断,切换到另一个数据块继续存,第一个存满的小块则可以拿去先处理了,然后在一帧数据接收完成之后触发IDLE Line中断读取剩下的数据(如果需要接收的数据大于两小数据块的大小,则可以在这两个数据块之间来回切换了,具体看我们自己的想象空间了)。

4077086449550.png (125.8 KB )

4077086449550.png

使用特权

评论回复
30
偏爱番茄酱|  楼主 | 2015-7-19 15:26 | 只看该作者
下图为我写的一个测试工程运行的效果图,跑在Kinetis KL26上面(FRDM-KL26板上),程序中我预留了1024字节的Buffer,每次上位机发送完一帧数据即会触发一次IDLE Line功能,在UART的IDLE Line中断里有一点需要注意,即每次IDLE Line都要记得把DMA的目标偏移地址重新复位到Buffer的首地址,否则的话下一帧的数据会继续往下存直至最后溢出,虽然我在程序中也做了DMA溢出中断对此做了处理,但是还是不要惹麻烦的好是吧,呵呵。

11111.jpg (489.56 KB )

11111.jpg

使用特权

评论回复
31
偏爱番茄酱|  楼主 | 2015-7-19 15:28 | 只看该作者
我把完整的测试代码已上传至附件中供广大网友借鉴参考。

KL26 UART Packet DMA Test.zip

1.25 MB

使用特权

评论回复
32
跟屁虫| | 2015-7-19 20:30 | 只看该作者

看一下智能车,电子竞赛上应该有用

使用特权

评论回复
33
偏爱番茄酱|  楼主 | 2015-7-20 12:32 | 只看该作者
IAR下使用noinit段的方法和指定地址的变量分配

使用特权

评论回复
34
偏爱番茄酱|  楼主 | 2015-7-20 12:33 | 只看该作者
noinit段对我们大多数搞单片机开发者来说并不陌生,该段如果被使用的话是会被编译器自动分配到芯片SRAM的一块区域中(注意是RAM区而非Flash),在该段定义的变量在除了掉电之外的任何芯片复位的情况下都不会被重新初始化,所以这个段的意义就大了,常用来保存一些敏感信息,特殊应用场合下的不能被复位的数据或者做复位判断标志等数据,个人感觉这个数据段的用途还是非常广的,且很好用。

使用特权

评论回复
35
偏爱番茄酱|  楼主 | 2015-7-20 12:33 | 只看该作者
那下面我们就以飞思卡尔Kinetis系列的KL26在IAR环境下为例,简单介绍一下noinit段的使用方法,方法还是非常简单的,如下图,定义noinit段的变量有两种形式,一种是直接在变量类型前面加上"__no_init”关键字,另一种是使用预编译指令#pragma这种IAR下常用的指定段的方式,俺还是prefer第一种方式的,简单明了。

01.png (27.33 KB )

01.png

使用特权

评论回复
36
偏爱番茄酱|  楼主 | 2015-7-20 12:33 | 只看该作者
实际上讲到这里已经算是结束了毕竟noinit段的使用方法还是比较简单的。但我并不想这么早就收尾了,还想介绍一下noinit使用的另一种情况(俺还没完了,呵呵),那就是正常情况下noinit段所在的SRAM区地址范围是被编译器自动分配的,但是如果我是强迫症的话(咳咳,俺不是啊,是假设啊,呵呵)或者用户有需要就是想把noinit中的变量指定到固定的地址中去(有些应用是需要的,比如带Bootloader的应用,因为Bootloader代码和用户代码是两个独立的工程且分开编译的,那Bootloader里面是没有这个变量的,所以需要告诉Bootloader用户代码中在noinit段定义的变量所在的具体地址,然后Bootloader直接去该地址读取),这就需要我们“耍些手段”去强制编译器把该noinit的变量分配到我们制定的地址去。当然实现这个功能,IAR下有几种方法,我这里只给出一种比较可靠的方法,即修改链接文件,在IAR的链接文件中给noinit区分配好指定的空间大小和地址范围,这样就可以根据外部变量的大小去来决定在链接文件中分给noinit区的空间大小和地址范围

使用特权

评论回复
37
偏爱番茄酱|  楼主 | 2015-7-20 12:34 | 只看该作者
具体方法如下:
1. 打开IAR下用户工程的链接文件(这里我以KL26 128kB flash的链接文件为例),如下图中所示在给RAM分配起始空间时可以预留出0x30即48个字节(下面应用中我定义了12个整型变量,需要48个字节);

02.jpg (77.58 KB )

02.jpg

使用特权

评论回复
38
偏爱番茄酱|  楼主 | 2015-7-20 12:35 | 只看该作者
2. 为noinit区指定一个固定的区(如果不指定的话是由编译器自动分配的),我这里给noinit区分配的地址范围设定为(RAMstart-0x30)到RAMstart(这样不会与其他数据冲突),占用0x30个字节,同时noinit区的首地址也确定下来了,即RAMstart-0x30;

03.jpg (91.82 KB )

03.jpg

使用特权

评论回复
39
偏爱番茄酱|  楼主 | 2015-7-20 12:35 | 只看该作者
3. 这一步就是把.noinit段范围分配到上面定义的noinit_region区,实际上就是告诉编译器以后被定义成__no_init的变量需要强制放到noinit_region区;

04.jpg (90.61 KB )

04.jpg

使用特权

评论回复
40
偏爱番茄酱|  楼主 | 2015-7-20 12:36 | 只看该作者
4. 然后在c文件中直接定义一个temp数组并声明成__no_init段,12个元素,共占用48个字节,如果你定义13个元素52个字节,编译器会出错提示超出范围了,所以如果我们需要更改变量的大小记得链接文件也要修改;

05.jpg (52.76 KB )

05.jpg

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则