打印
[技术问题解答]

KL25 ADC+DMA配合

[复制链接]
7747|61
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ianhom|  楼主 | 2015-1-19 16:51 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ianhom 于 2015-4-27 14:12 编辑

请问ADC配合DMA使用是,如何配置ADC触发DMA呢,比如周期触发AD采样,采样完成后触发DMA,然后结果存在特定位置。全程不进入定时器中断、AD中断和DMA中断

2015-04-27更新:
代码已经移植到KL16上,配置方式与KL25相同。
KL25和KL16的DMA循环buffer必须定义在特定的对齐地址上,例如1024个字节的循环buffer,则DMA的目的地址必须是1024字节对齐(0xXXXXX000,0xXXXXX400,0xXXXXX800,0xXXXXC00),为了获取对齐的地址,测试代码中通过malloc的方式计算到对齐地址再进行申请,这里需要注意的一点,我采用官方FRDM-KL25Z开发板例程,使用的是工程中自带的alloc.c中的malloc函数去实现的,该函数每次malloc返回的地址是递减,所以测试代码在官方例程中应该是没有问题的。如果对测试代码进行移植并使用的是C标准库中的malloc函数(返回地址是递增的),则测试代码中地址对齐的函数是无效的,有兴趣的朋友可以自行实现一下,比较简单。
还有一个比较简单的方式实现对齐地址的变量申请:
#pragma data_alignment = 1024                             /* 下一行变量将定义在1024字节对齐的地址上 */
static unsigned char sg_aucAdData[1024]  = {0};   /* sg_aucAdData为DMA循环buffer的地址         */
不过该方法有个问题,就是循环buffer将建立在内存的静态全局区,因为1024字节对齐,会造成对齐地址之前的内存被浪费掉(全局变量在编译时就确定了)。如果是为了快速验证KL平台上ADC+DMA,可采用此方法。

更有效申请特定内存地址的方法还在摸索中,求大神指导。

此贴已结,测试代码在31楼

相关帖子

沙发
FSL_TICS_ZJJ| | 2015-1-20 09:13 | 只看该作者
你如果都不想进入中断,那么就只能使用查询方法去做了。
首先初始化ADC,DMA,然后初始化PIT并使能PIT。
查询法等待PIT定时到,定时到之后启动ADC转换,等待ADC转换完成标志COCO标志完成,如果初始化是通过ADC触发DMA,并且DMA设置好源地址为ADC数据结果寄存器,一旦ADC的COCO标志完成,DMA就会自动实现数据存储到特定位置。
然后你再等待下一次的定时到,启动ADC转换...
周而复始,思想就是这样。

使用特权

评论回复
板凳
ianhom|  楼主 | 2015-1-20 10:29 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-20 09:13
你如果都不想进入中断,那么就只能使用查询方法去做了。
首先初始化ADC,DMA,然后初始化PIT并使能PIT。
查 ...

感谢回复,我的思路与之类似,想实现周期触发ADC采样,采样后结果通过DMA直接存入某个区域的内存,全程不进入任何终端操作,采样的数据等主程序需要处理的时候再才做。但是细节方面有些地方我还没有搞清楚,PIT周期配置ADC采样后,COCO标志如何清除呢?

使用特权

评论回复
地板
FSL_TICS_ZJJ| | 2015-1-20 11:32 | 只看该作者
ianhom 发表于 2015-1-20 10:29
感谢回复,我的思路与之类似,想实现周期触发ADC采样,采样后结果通过DMA直接存入某个区域的内存,全程不 ...

你好,关于这个问题,在用户手册COCO寄存器描述的地方讲的很清楚:
COCO is cleared when the respective SC1n register is written
or when the respective Rn register is read.
也就是说,对于的SC1n寄存器写值或者结果寄存器被读取之后 就会清掉。

使用特权

评论回复
5
ianhom|  楼主 | 2015-1-20 13:39 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-20 11:32
你好,关于这个问题,在用户手册COCO寄存器描述的地方讲的很清楚:
COCO is cleared when the respective ...

感谢回复,可能我没有描述清楚。
首先,手册上的写SC1n和读Ra的方法之前在KL25的平台上实验过,写SC1n可以清除标志,但是我做Ra读取操作的时候未清除标志,有些疑惑。
其次,因为不开启中断,所以不打算在主程序里对SC1n进行写操作或对Ra进行读操作,所以我的问题是在ADC触发DMA数据转移时,如何清除COCO标志?是否在DMA执行时可视为对Ra进行了读操作,自动清除了COCO标志。

使用特权

评论回复
6
ianhom|  楼主 | 2015-1-21 09:25 | 只看该作者
ianhom 发表于 2015-1-20 13:39
感谢回复,可能我没有描述清楚。
首先,手册上的写SC1n和读Ra的方法之前在KL25的平台上实验过,写SC1n可 ...

问题补充:
在进行DMA循环存放时发现,循环的地址必须是对齐的,比如说64字节循环,DMA目的地址位0x20000010,则DMA循环转移的空间为0x20000000至0x20000040(64个字节),这样0x20000010之前的区域将被覆盖(有可能有变量申请在这个区域),想问下
1、是否有好的方法申请个变量,其地址正好是64字节对齐的,例如0xXXXXXX00、0xXXXXXX40、0xXXXXXX80、0xXXXXXXC0,作为DMA目的地址
2、能否取20个字节为一模而不是16、32、64....字节为一模
早复为盼

使用特权

评论回复
7
FSL_TICS_ZJJ| | 2015-1-21 10:23 | 只看该作者
ianhom 发表于 2015-1-20 13:39
感谢回复,可能我没有描述清楚。
首先,手册上的写SC1n和读Ra的方法之前在KL25的平台上实验过,写SC1n可 ...

读取转换值是可以清除COCO的,不知道你是用什么查看没有清楚? debug?
debug窗口查看是不准确的,你可以在读取转换值寄存器之后,加一个判断COCO是否是0的语句测试,就知道了。
比如:
                envia_dados[cnt++] = ADC0_RA;//store code and clear the coco bit
                if(!( ADC0_SC1A & ADC_SC1_COCO_MASK ))
                {
                       
                        test++;
                }
实际上test是会增加的。
DMA读取会自动清除COCO标志,因为DMA读取的还是结果寄存器,就相当于读命令。

使用特权

评论回复
8
ianhom|  楼主 | 2015-1-21 15:19 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-21 10:23
读取转换值是可以清除COCO的,不知道你是用什么查看没有清楚? debug?
debug窗口查看是不准确的,你可以 ...

非常感谢!问题补充:
在进行DMA循环存放时发现,循环的地址必须是对齐的,比如说64字节循环,DMA目的地址位0x20000010,则DMA循环转移的空间为0x20000000至0x20000040(64个字节),这样0x20000010之前的区域将被覆盖(有可能有变量申请在这个区域),想问下
1、是否有好的方法申请个变量,其地址正好是64字节对齐的,例如0xXXXXXX00、0xXXXXXX40、0xXXXXXX80、0xXXXXXXC0,作为DMA目的地址
2、能否取20个字节为一模而不是16、32、64....字节为一模
3、在CS=0的情况下,如果BCR归零了,就不在继续转移数据,这样我就必须给BCR赋值才能继续转换,请问如何配置才能让主程序完全不干预,也不进入中断。
早复为盼

使用特权

评论回复
9
FSL_TICS_ZJJ| | 2015-1-22 14:08 | 只看该作者
1,DMA的值的确是需要对齐的,你可以定义一个变量到具体的SRAM地址,这样就能保证对齐。
2,不可以,模值是固定的。
3,BCR到0之后,需要有主程序干预进行下一次的转换。

使用特权

评论回复
10
ianhom|  楼主 | 2015-1-22 14:39 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-22 14:08
1,DMA的值的确是需要对齐的,你可以定义一个变量到具体的SRAM地址,这样就能保证对齐。
2,不可以,模值是 ...

感谢回复!
请问是否有其他办法实现无限循坏DMA转移,主程序不干预,也不开启中断?

使用特权

评论回复
11
FSL_TICS_ZJJ| | 2015-1-22 15:10 | 只看该作者
ianhom 发表于 2015-1-22 14:39
感谢回复!
请问是否有其他办法实现无限循坏DMA转移,主程序不干预,也不开启中断? ...

KL系列结束后需要使用软件重新更新,通常我们是在DMA的结束中断中重新更新目的地址实现再一次的DMA loop
KL没有不用代码自动实现循环的功能,但是我们的K系列就有这样的功能了。

使用特权

评论回复
12
ianhom|  楼主 | 2015-1-22 15:17 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-22 15:10
KL系列结束后需要使用软件重新更新,通常我们是在DMA的结束中断中重新更新目的地址实现再一次的DMA loop
...

非常感谢!
我再整理一下内容,把代码贴出来

使用特权

评论回复
13
陌小生| | 2015-1-22 20:40 | 只看该作者

使用特权

评论回复
14
FSL_TICS_ZJJ| | 2015-1-22 22:06 | 只看该作者
ianhom 发表于 2015-1-22 15:17
非常感谢!
我再整理一下内容,把代码贴出来

不客气,后续有问题欢迎继续发帖交流。

使用特权

评论回复
15
huzi2099| | 2015-1-22 22:47 | 只看该作者
刚做完这个,dma+adc到+n个通道每次切换,数据存储到sram完全没有软件代码开销.kl25,cw10.6专家模式

使用特权

评论回复
16
huzi2099| | 2015-1-22 22:51 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-22 15:10
KL系列结束后需要使用软件重新更新,通常我们是在DMA的结束中断中重新更新目的地址实现再一次的DMA loop
...

k系列和kl25我都做了,都可以的,K系列和他的dma好多地方不太一样.

使用特权

评论回复
17
FSL_TICS_ZJJ| | 2015-1-23 09:33 | 只看该作者
huzi2099 发表于 2015-1-22 22:47
刚做完这个,dma+adc到+n个通道每次切换,数据存储到sram完全没有软件代码开销.kl25,cw10.6专家模式 ...

你如果有现成的工程,欢迎分享出来。

使用特权

评论回复
18
ianhom|  楼主 | 2015-1-24 12:36 | 只看该作者
huzi2099 发表于 2015-1-22 22:51
k系列和kl25我都做了,都可以的,K系列和他的dma好多地方不太一样.

求高人指导!
ADC通道切换需要用到另一个DMA通道使用LINK模式吧。

使用特权

评论回复
19
huzi2099| | 2015-1-25 10:42 | 只看该作者
cw10.6专家模式...

ADC_DMA.rar

755.43 KB

使用特权

评论回复
20
ianhom|  楼主 | 2015-1-25 20:48 | 只看该作者
huzi2099 发表于 2015-1-25 10:42
cw10.6专家模式...

感谢分享!!!
回头我整理个iar的工程贴出来

使用特权

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

本版积分规则

100

主题

181

帖子

3

粉丝