ADC驱动 MCP3201 广州龙芯1B开发板.docx

上传人:b****1 文档编号:2394888 上传时间:2023-05-03 格式:DOCX 页数:87 大小:2.27MB
下载 相关 举报
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第1页
第1页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第2页
第2页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第3页
第3页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第4页
第4页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第5页
第5页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第6页
第6页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第7页
第7页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第8页
第8页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第9页
第9页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第10页
第10页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第11页
第11页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第12页
第12页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第13页
第13页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第14页
第14页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第15页
第15页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第16页
第16页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第17页
第17页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第18页
第18页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第19页
第19页 / 共87页
ADC驱动 MCP3201 广州龙芯1B开发板.docx_第20页
第20页 / 共87页
亲,该文档总共87页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

ADC驱动 MCP3201 广州龙芯1B开发板.docx

《ADC驱动 MCP3201 广州龙芯1B开发板.docx》由会员分享,可在线阅读,更多相关《ADC驱动 MCP3201 广州龙芯1B开发板.docx(87页珍藏版)》请在冰点文库上搜索。

ADC驱动 MCP3201 广州龙芯1B开发板.docx

ADC驱动MCP3201广州龙芯1B开发板

1.前言3

2.修正龙芯1B开发板资料中的错误3

2.1.运行出错3

2.1.1.我执行光盘中test-mcp3201的运行结果3

2.1.2.用户手册中的运行结果7

2.2.配置错误8

2.3.驱动源码错误9

2.4.修正驱动错误后的打印10

2.5.修改ADC应用后的打印11

2.6.应用程序源码注释错误12

3.硬件电路分析13

3.1.电路图分析13

3.1.1.电路图简述13

3.1.2.片选信号分析14

3.2.AD芯片MCP3201分析17

3.2.1.通信协议分析17

3.2.2.转换结果分析19

3.2.3.参考电路图22

4.驱动程序分析23

4.1.LinuxSPI子系统驱动分析23

4.2.重点代码分析23

4.2.1.SPI0的IO基地址和相关寄存器地址24

4.2.2.SPI0初始化25

4.3.带注释驱动源码30

4.3.1.platform.c30

4.3.2.spi.c32

4.3.3.ls1b_spi.c32

4.3.4.mcp3201.c44

5.应用程序分析47

5.1.应用程序思路分析47

5.2.带注释源码47

5.3.我修改代码后的运行结果分析48

6.参考文档66

版本

更新日期

更新内容

V1.0

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]:

Cpu0

$0:

000000001000bc0083a17dbc83a56200

$4:

0000000083a17df00000000081074ac0

$8:

00000000000000000000000100000000

$12:

00000010807c0000000000000040088c

$16:

83a5620000000000807e000000000002

$20:

8076000083a17eb80000000083a17eb0

$24:

000000052bacdc00

$28:

83a1600083a17da87feb4320804df1a4

Hi:

00000157

Lo:

000001e3

epc:

804defc0__spi_sync+0x2c/0x104

Tainted:

GD

ra:

804df1a4spi_write_then_read+0x104/0x1dc

Status:

1000bc03KERNELEXLIE

Cause:

10800008

BadVA:

000000a8

PrId:

00004220(LoongsonLS1X)

Moduleslinkedin:

Processtest-mcp3201(pid:

659,threadinfo=83a16000,task=839ed0c0,tls=00000000)

Stack:

8076000083a17eb8802a27bc000000000000000083a17dbc83a17dbc8047fd58

83a5620000000000807e00000000000280760000804df1a483a1cb6c00000000

83a562808046661c83a17e6083a17e6000000000000000000000000000000000

000000000000000000000000000000000000000083a1d01083a5620000000000

0000000000000000000000000000000000000000000000000000000000000000

...

CallTrace:

[<804defc0>]__spi_sync+0x2c/0x104

[<804df1a4>]spi_write_then_read+0x104/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

Segmentationfault

/dev#

后面会分析为什么出错。

2.1.2.用户手册中的运行结果

首先您的运行结果的打印值全为0,表示什么意思,就只打印出0就能说明您的驱动和硬件没问题吗?

个人认为应该改变阻值后,打印出不同的值才算正确。

还有为什么需要拷贝到/dev目录下啊,这也不太好吧?

2.2.配置错误

MCP3201用的是SPI0吧?

为什么不选上“SPIController0”,反而选上“SPIController1”呢?

原理图中也是用的"SPI0"。

2.3.驱动源码错误

经过一路跟踪调试,发现启动时有如下打印

ls1b-spils1b-spi.0:

chipselect0alreadyinuse

ls1b-spils1b-spi.0:

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

/test#./test-mcp3201

Startingmcp3201

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3^C

/test#

一直打印,我赶忙用ctrl+c结束掉,这很明显也是不合理的地方。

为什么广州龙芯的人没发现呢?

发现了,为什么不改呢?

2.5.修改ADC应用后的打印

这里主要增加一个延时操作,采集一次后延时一秒再采集。

目的就是解决之前的不停的刷屏的问题。

修改后的源码清单

#include

#include

#include

#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){

printf("DeviceOpenfailure\n");

returnfd;

}

for(;;){

sleep

(1);//睡眠1秒

read(fd,ret,2);

printf("Thevalueis0x%x0x%x\n",ret[0],ret[1]);

}

close(fd);

return0;

}

运行结果

/test#./ls1b_adc_app_mcp3201

Startingmcp3201

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0x800x3

Thevalueis0xf00x3

Thevalueis0xf00x3

Thevalueis0xf00x7

Thevalueis0x800x7

Thevalueis0x800x7

Thevalueis0xf00xd

Thevalueis0xf80xd

Thevalueis0xf80x1

Thevalueis0xf80x1

Thevalueis0xb10x1

Thevalueis0x800x7

Thevalueis0xff0x7

Thevalueis0xf00x7

Thevalueis0x600xc

Thevalueis0x600xc

Thevalueis0x600xc

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

csn

片选2输出值(1:

输出高电平;0:

输出低电平)

5

csn

片选1输出值(1:

输出高电平;0:

输出低电平)

4

csn

片选0输出值(1:

输出高电平;0:

输出低电平)

3

csen

片选3输出使能(1:

允许输出;0:

禁止输出)

2

csen

片选2输出使能(1:

允许输出;0:

禁止输出)

1

csen

片选1输出使能(1:

允许输出;0:

禁止输出)

0

csen

片选0输出使能(1:

允许输出;0:

禁止输出)

这样够详细了吧,明白这个很重要,下面马上就会用到。

对应的软件部分代码为

注意两次设置的值,第一次为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<0){

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;

}

return0;

}

3.2.2.转换结果分析

这一小节详细讲解,通过AD转换所得的12位数据计算所测的电压值。

MCP3201的手册中已经详细讲清楚了。

这里把截图贴上

再来回归一下我们的电

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2