Data:2019/1/23 author:wangsong
需求:要求能有产生一路1MHZ以上的正弦激励信号,预留外接时钟接口,频率、幅值可调。
方案:
1、PWM波转模拟量(PAC =PWM to Analog Convertor)是一种PWM信号转模拟信号的专用芯片,模块最大频率只够200KHZ。(否决)
2、外接DDS模块,由beaglebone控制DDS模块,从而产生不同相位频率的正弦波,需要自己写驱动直接控制DDS。(测试)
3、DDS最基础的AD9833的频率就能达到需求,用集成STM32作为局部控制器,AM335X通过串口发送控制指令。(否决)
遇到问题:采购的AD9833用的是标准三线式串行接口兼容SPI,根据数据手册和电路原理图,则只需要这三个数据口;而beaglebone预留的是4线的SPI,其中对应引脚和设备树中对应如下表,来自于博客:https://blog.csdn.net/wyt2013/article/details/16921573 ,而三线制SPI和四线制的SPI是否只是删除一个单向数据线我没有深究,直接做法是根据AD8933数据手册里提供的时序,使用GPIO口模拟。其中数据手册以及其他参考资料在亚德诺(ADI)半导体官网下载:https://www.analog.com/cn/products/ad9833.html
说明:FSYNC输入是电平触发输入,用作帧同步和芯片使能。仅当FSYNC处于低电平时,才可将数据传输至器件。要开始串行数据传输,应将FSYNC拉低,并注意FSYNC至SCLK下降沿建立时间t 7 的最小值。FSYNC变为低电平后,串行数据即会在16个时钟脉冲的SCLK下降沿移入器件的输入移位寄存器。可在SCLK的第16个下降沿后将FSYNC拉高,并注意SCLK下降沿至FSYNC上升沿时间t 8 的最小值。或者,FSYNC可以在16倍数个SCLK脉冲期间保持低电平,然后在数据传输结束时变为高电平。这样,在FSYNC保持低电平期间,可以连续流形式载入16位字;FSYNC仅在载入最后一个字的第16个SCLK下降沿之后变为高电平。SCLK可以是连续的,也可以在写操作期间置于高电平或低电平空闲状态。无论何种情况,当FSYNC变为低电平(t 11 )时,SCLK都必须处于高电平。
实施情况:
参考源码:https://www.analog.com/cn/products/ad9833.html#product-requirement
参考博客:基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read、write
https://blog.csdn.net/u014281970/article/details/82145664
对作者的源码的说明:
- 源码将硬件资源引脚写死,固定的三个引脚,所以不考虑设备树等高级写法。
- 源码采用的GPIO口模拟三线式串行通信,根据上面的时序写成。
调试过程中遇到的问题:
- GPIO口的定义,在程序中将GPIO口硬件资源写死指定的对应引脚,按照网上百度到的说明GPIO1_17指的则是32*1+17=49,则引脚号宏定义为49。根据BBB_Header_Table.pdf查得BBB的引脚号。但是调试时候发现不对,不知道是不是因为接了扩展板。
经过调试,大学霸博客提供的这两个图配上微雪的LCD扩展板可以使用,其中定义的GPIO_XX,驱动程序中写死的引脚号则是XX。但也不是所有的都能用,因为有很多引脚以及被使用,查看微雪扩展板的原理图,看看能使用哪些引脚,最好在beaglebone的、sys/class/gpio中添加下引脚进行测试,看看是否能正常输出高低电平。最终本人使用的引脚是P9header:P11 、P15 、 P22引脚,对应的驱动程序中引脚号是:30、48、49.
- 驱动源码中相关函数说明:
- file_operations结构体详解:
https://www.cnblogs.com/chen-farsight/p/6181341.html
- copy_to_user 、copy_from_user函数:
https://blog.csdn.net/xiaodingqq/article/details/80150347
- 内核MKDEV(MAJOR, MINOR)宏:
http://blog.sina.com.cn/s/blog_752fa65f0100osao.html
https://blog.csdn.net/angle_birds/article/details/7822416?utm_source=blogxgwz4
- gpio_request()函数:
https://blog.csdn.net/beyondioi/article/details/6984406
- Linux字符设备驱动之cdev_init()系列:
https://blog.csdn.net/tigerjibo/article/details/6412613
- linux硬件设备操作函数 open(/dev/ietctl, O_RDWR|...)
https://blog.csdn.net/pkigavin/article/details/8580703
- IOCTL函数用法详解:
https://blog.csdn.net/z_hualin/article/details/77892932
- 驱动模块编译时要保证依赖的内核源码和板子上运行的内核一致:
https://blog.csdn.net/qq_32059343/article/details/86572422
https://blog.csdn.net/qq_32059343/article/details/86572477
- 修改调试成功的源码分析:
https://blog.csdn.net/qq_32059343/article/details/86583353
实验结果: