ADC驱动 MCP3201 广州龙芯1B开发板Word下载.docx
- 文档编号:4472576
- 上传时间:2023-05-03
- 格式:DOCX
- 页数:87
- 大小:2.27MB
ADC驱动 MCP3201 广州龙芯1B开发板Word下载.docx
《ADC驱动 MCP3201 广州龙芯1B开发板Word下载.docx》由会员分享,可在线阅读,更多相关《ADC驱动 MCP3201 广州龙芯1B开发板Word下载.docx(87页珍藏版)》请在冰点文库上搜索。
2013,9,26
创建
1.
前言
由于龙芯资料较少,现在又有点时间,写了两句,仅供初学者入门时参考,还望高手多多指教。
2.修正龙芯1B开发板资料中的错误
2.1.运行出错
2.1.1.我执行光盘中test-mcp3201的运行结果
我按照手册中的说明,将文件“test-mcp3201”拷贝到开发板nfs根文件系统中,运行结果如下
/test#./test-mcp3201
Startingmcp3201CPU0Unabletohandlekernelpagingrequestatvirtualaddress000000a8,epc==804defc0,ra==804df254
Oops[#1]:
Cpu0
$0:
000000000000000183a17dbc83856080
$4:
0000000083a17df00000000083a17eb0
$8:
00000000000000000000000100000000
$12:
00000010807c0000000000000040088c
$16:
8385608000000000807e000000000002
$20:
8076000083a17eb80000000083a17eb0
$24:
000000052b6c4c00
$28:
83a1600083a17da87f911840804df254
Hi:
00000157
Lo:
000001e3
epc:
804defc0__spi_sync+0x2c/0x104
Nottainted
ra:
804df254spi_write_then_read+0x1b4/0x1dc
Status:
1000bc03KERNELEXLIE
Cause:
10800008
BadVA:
000000a8
PrId:
00004220(LoongsonLS1X)
Moduleslinkedin:
Processtest-mcp3201(pid:
655,threadinfo=83a16000,task=839ed0c0,tls=00000000)
Stack:
00000002804841e4802964d4000000000000000083a17dbc83a17dbc8047fd58
8385608000000000807e00000000000280760000804df25483a1cb6c00000000
83a562808046661c83a17e6083a17e6000000000000000000000000000000000
d010********
0000000000000000000000000000000000000000000000000000000000000000
...
CallTrace:
[<
804defc0>
]__spi_sync+0x2c/0x104
804df254>
]spi_write_then_read+0x1b4/0x1dc
804df3d0>
]mcp3201_read+0x44/0x108
802a6dc4>
]vfs_read+0xac/0x198
802a71a0>
]sys_read+0x54/0xb4
8020b76c>
]stack_done+0x20/0x40
Code:
afb00020afbf0034afb10024<
8c9100a8>
3c02804e27b300102442ef8c0080802100a09021
Disablinglockdebuggingduetokerneltaint
Segmentationfault
/test#
我这里出异常了。
然后拷贝到/dev/目录下,还是出错
/test#cptest-mcp3201/dev/
/test#cd/dev/
/dev#ls
autofsmtdblock6tty16tty51
bobodog_io_controlnetwork_latencytty17tty52
consolenetwork_throughputtty18tty53
cpu_dma_latencynulltty19tty54
dspppptty2tty55
fullpsauxtty20tty56
kmsgptmxtty21tty57
loop0ptstty22tty58
loop1ptyp0tty23tty59
loop2ptyp1tty24tty6
loop3ptyp2tty25tty60
loop4ptyp3tty26tty61
loop5ram0tty27tty62
loop6ram1tty28tty63
loop7ram10tty29tty7
mcp3201ram11tty3tty8
memram12tty30tty9
miceram13tty31ttyS0
mixerram14tty32ttyS1
mtd0ram15tty33ttyS2
mtd0roram2tty34ttyS3
mtd1ram3tty35ttyS4
mtd1roram4tty36ttyS5
mtd2ram5tty37ttyp0
mtd2roram6tty38ttyp1
mtd3ram7tty39ttyp2
mtd3roram8tty4ttyp3
mtd4ram9tty40urandom
mtd4rorandomtty41usbdev1.1
mtd5test-mcp3201tty42usbdev1.2
mtd5rottytty43usbdev2.1
mtd6tty0tty44vcs
mtd6rotty1tty45vcs1
mtdblock0tty10tty46vcsa
mtdblock1tty11tty47vcsa1
mtdblock2tty12tty48zero
mtdblock3tty13tty49
mtdblock4tty14tty5
mtdblock5tty15tty50
/dev#./test-mcp3201
Startingmcp3201CPU0Unabletohandlekernelpagingrequestatvirtualaddress000000a8,epc==804defc0,ra==804df1a4
Oops[#2]:
000000001000bc0083a17dbc83a56200
0000000083a17df00000000081074ac0
83a5620000000000807e000000000002
000000052bacdc00
83a1600083a17da87feb4320804df1a4
Tainted:
GD
804df1a4spi_write_then_read+0x104/0x1dc
659,threadinfo=83a16000,task=839ed0c0,tls=00000000)
8076000083a17eb8802a27bc000000000000000083a17dbc83a17dbc8047fd58
83a5620000000000807e00000000000280760000804df1a483a1cb6c00000000
000000000000000000000000000000000000000083a1d01083a5620000000000
804df1a4>
]spi_write_then_read+0x104/0x1dc
/dev#
后面会分析为什么出错。
2.1.2.用户手册中的运行结果
首先您的运行结果的打印值全为0,表示什么意思,就只打印出0就能说明您的驱动和硬件没问题吗?
个人认为应该改变阻值后,打印出不同的值才算正确。
还有为什么需要拷贝到/dev目录下啊,这也不太好吧?
2.2.配置错误
MCP3201用的是SPI0吧?
为什么不选上“SPIController0”,反而选上“SPIController1”呢?
原理图中也是用的"
SPI0"
。
2.3.驱动源码错误
经过一路跟踪调试,发现启动时有如下打印
ls1b-spils1b-spi.0:
chipselect0alreadyinuse
can'
tcreatenewdeviceformcp3201
打印已经提示出错地方了,具体错误如下
这里把片选设置为0了。
而原理图中用的是片选3。
修改一下源码就可以了,修改为
重新编译,运行就不会异常了。
2.4.修正驱动错误后的打印
/#cdtest/
/test#ls
ShowKernelVariableValuels1b_adc_app_mcp3201serial
button_testls1b_led_apptest-mcp3201
close_kernel_debug.shls1b_led_driver.ko
helloopen_kernel_debug.sh
/test#ls-l/dev/mcp3201
crw-rw----10010,63Jan100:
00/dev/mcp3201
Startingmcp3201
Thevalueis0x800x3
Thevalueis0x800x3^C
一直打印,我赶忙用ctrl+c结束掉,这很明显也是不合理的地方。
为什么广州龙芯的人没发现呢?
发现了,为什么不改呢?
2.5.修改ADC应用后的打印
这里主要增加一个延时操作,采集一次后延时一秒再采集。
目的就是解决之前的不停的刷屏的问题。
修改后的源码清单
#include<
stdio.h>
unistd.h>
fcntl.h>
#defineADC_DEVICE"
/dev/mcp3201"
/*******************程序说明*********************
ADCMCP3201具有12位的分辨率,对MCP3201的访问每次读
取的数据存放在一个2字节数组中,在例子程序中,ret[0]
中是12位数据的高4位,ret[1]存放的是12位数据的低八位
**********************End***********************/
intmain(void){
intfd,i;
unsignedcharret[2]={0x0};
fd=open(ADC_DEVICE,O_RDONLY);
printf("
Startingmcp3201\n"
);
if(fd<
0){
DeviceOpenfailure\n"
returnfd;
}
for(;
;
){
sleep
(1);
//睡眠1秒
read(fd,ret,2);
Thevalueis0x%x0x%x\n"
ret[0],ret[1]);
close(fd);
return0;
}
运行结果
/test#./ls1b_adc_app_mcp3201
Thevalueis0xf00x3
Thevalueis0xf00x7
Thevalueis0x800x7
Thevalueis0xf00xd
Thevalueis0xf80xd
Thevalueis0xf80x1
Thevalueis0xb10x1
Thevalueis0xff0x7
Thevalueis0x600xc
您看,打印出的值在变,具体表示什么意思,后面再分析。
龙芯1B开发板资料还需要改进,同时也需要我们大家的呵护!
哈哈!
2.6.应用程序源码注释错误
经过前面的努力已经能正常打印AD转换后的结果了,具体结果表示什么意思呢?
请参考本文的芯片MCP3201的通信协议分析章节。
简单的说,打印的就是MCP3201返回的AD转换结果。
这个结果为12位的数据。
但是关于12位数据的顺序问题,我的理解和开发板光盘中MCP3201应用程序源码的注释有些不一致。
光盘中代码的注释为
注释中写的是ret[0]存放的是12位数据的高4位。
但是我对MCP3201驱动的分析和注释是
我对驱动的理解刚好相反。
我的理解是驱动中val[1]存放的是12位数据的高4位,对应应用程序中ret[1]存放12位数据的高4位。
3.硬件电路分析
3.1.电路图分析
3.1.1.电路图简述
首先将模拟电源和数字电源分离。
其中的FB69为磁珠,用于抑制电源线、信号线上的高频噪声和尖峰干扰,还具有吸收静电脉冲的能力。
上图就是MCP3201的电路图。
其中通过调节VR1的阻值来检测MCP3201是否正常工作。
上面的图也比较简单,左边模拟信号输入,右边将转换结果通过spi输出。
3.1.2.片选信号分析
从电路图中可以看出,MCP3201使用了龙芯1B处理器的SPIO的片选3信号。
MCP3201芯片手册中对片选引脚的描述为
驱动中肯定有对SPI设置的部分,其中肯定有对片选信号的操作。
首先看一下龙芯1B处理器手册对SPIO_CS3的描述
通过一个8位的寄存器来控制4根片选线。
这个8位寄存器和普通的GPIO的控制寄存器差不了多少,其中一部分控制使能输出,另外一部分控制输出值。
再写详细点就是
位域
位域名称
描述
7
csn
片选3输出值(1:
输出高电平;
0:
输出低电平)
6
片选2输出值(1:
5
片选1输出值(1:
4
片选0输出值(1:
3
csen
片选3输出使能(1:
允许输出;
禁止输出)
2
片选2输出使能(1:
1
片选1输出使能(1:
片选0输出使能(1:
这样够详细了吧,明白这个很重要,下面马上就会用到。
对应的软件部分代码为
注意两次设置的值,第一次为0xff,第二次为0x7f,不同的地方就是把最高位也就是片选3的值由1变为0,同时片选引脚由高电平变为低电平,按照MCP3201中的说明,这时候MCP3201被选通。
这里驱动源码中的寄存器名字和龙芯1B处理器手册中的不一致,这样欠佳。
其实源码中也有和处理器手册中一致的定义,不知道为什么没用。
Platform框架中也有相关定义,源文件为“arch/mips/loongson/ls1x/platform.c”
这里的片选设置错误在前面已经讲了。
3.2.AD芯片MCP3201分析
开发板光盘中的芯片手册是中文的,自己慢慢看。
这里把重点提一下。
3.2.1.通信协议分析
简单来说,MCP3201是通过选片引脚出现“低电平跳变(下降沿)”时执行一次AD转换操作。
转换操作的时间长短和SPI的CLK信号相关,为2个时钟周期。
采样结束后,输出一个低电平空位,然后以高位在前的模式移位输出12位数据。
详细请看手册,如下图所示
具体怎样实现读取操作的呢?
如手册中所说,是通过连续读取两个字节来实现的。
读出的两字节数据格式为
2个未知位+1个空位+转换结果的高5位=第一个字节
转换结果的低7位+重复的B1位=第二个字节
这就是MCP3201驱动中的核心函数mcp3201_read()的原理。
staticssize_tmcp3201_read(structfile*file,char__user*buf,size_tcount,loff_t*ptr)
{
ssize_tretval;
unsignedcharval[2]={0x0};
unsignedchartx_buf[1]={0x0};
unsignedcharrx_buf[2]={0};
//读取转换结果
retval=spi_write_then_read(adc,tx_buf,0,rx_buf,2);
if(retval<
dev_err(&
adc->
dev,"
error%dreadingSR\n"
(int)retval);
returnretval;
}
//对从mcp3201读来的数据,按照其datasheet的要求取出编码
//格式为
//2个未知位+1个空位+转换结果的高5位=第一个字节
//转换结果的低7位+重复的B1位=第二个字节
val[0]=rx_buf[1]>
>
1;
//去掉第二字节的B1位
val[0]|=(rx_buf[0]&
0x01)<
<
7;
//将第一字节的最后一位和第二字节的前7位数据,组合为转换结果的低8位
val[1]=(rx_buf[0]>
1)&
0xf;
//转换结果的高4位
//将转换结果传递给应用程序
if(copy_to_user(buf,val,2))
{
printk("
Copydatatouserspaceerror!
\n"
return-EFAULT;
3.2.2.转换结果分析
这一小节详细讲解,通过AD转换所得的12位数据计算所测的电压值。
MCP3201的手册中已经详细讲清楚了。
这里把截图贴上
再来回归一下我们的电
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ADC驱动 MCP3201 广州龙芯1B开发板 ADC 驱动 广州 开发