MCP3201串行通信
关键理解:主出从入, 主设备上升沿采集数据的同时,从设备为下降沿输出数据,以此往复,完成主设备与从设备之 间的全双工通信。
可用标准SPI兼容串行接口与该器件进行通信。 当CS变为低电平时,启动与MCP3201的通信。 如果器件上电时CS 引脚为低电平,则必须先将此引脚拉为高电平,然后再恢复至低电平以启动通信。 器件将在CS 变为低电平后在第一个上升沿开始对模拟输入信号进行采样。 采样周期将在第二个时钟周期的下降沿结束,此时器件将输出一个低电平空位。 接下来的12个时钟脉冲将以首先发送MSB位的格式输出转换结果,如图5-1所示。 器件总是在时钟下降沿输出数据。 所有12个数据位均发送完毕后,如果器件继续接收时钟脉冲,而CS保持为低电平,则器件将以首先发送LSB的格式输出转换结果,如图5-2所示。 如果在CS保持为低电平时继续向器件提供时钟脉冲 (在以首先发送LSB的格式发送完数据后),器件将持续输出零。
以上总述,8个周期完成一次数据寄存器的传递,但要获得完整数据需要16个周期,而在16个周期中,首先前两个周期是对模拟输入信号的采样,并不获取数据,接下来的第三个周期主要是发送MSB,而在第16个周期,发送LSB。所以说,在寄存器只能储存8个有效数字的情况下,真正获取数据的是寄存器第一次获取数值时后5位有效位数,寄存器第二次获取的有效数字是前7位有效位数。
以下例子只是简单实现 寄存器的读写:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/delay.h>
#define u8 volatile unsigned char
// 控制寄存器
#define CtrlRes *(u8 *) 0xbfe80000
//状态寄存器
#define StaticRes *(u8 *) 0xbfe80001
//数据寄存器
#define DataRes *(u8*) 0xbfe80002
// 外部寄存器
#define ExternRes *(u8 *) 0xbfe80003
// 参数控制寄存器
#define ParaCtrlRes *(u8 *) 0xbfe80004
// 片选寄存器
#define PianRes *(u8 *) 0xbfe80005
// 时序控制寄存器
#define TimingCtrlRes *(u8 *) 0xbfe80005
void init_master(void)
{
//停止 SPI 控制器工作,对控制寄存器 spcr 的 spe 位写 0
CtrlRes = 0x12;
//重置状态寄存器 spsr,对寄存器写入 8'b1100_0000
StaticRes = 0xc0 ;
//设置接口模式与分频系数
ExternRes = 0x05;
//时钟分频数选择 与 spi flash 读使能
ParaCtrlRes = 0x61;
//片选控制寄存器,不启用从设备
PianRes = 0xff;
//时钟周期设为8T
TimingCtrlRes = 0x03;
}
int i;
static int __init spi_init(void)
{
u8 low_data;
unsigned short data, high_data;
//init_master()函数 实现寄存器的初始值
init_master( );
//连续10次读取数据寄存器
for (i=0; i<10; i++)
{
//开启控制寄存器工作使能
CtrlRes = 0x52;
//开启片选cs3信号,
PianRes = 0x7f;
// 第一次数据寄存器获取值
// 可以任意给数据寄存器赋值,只是为了推动数据寄存器的运作
DataRes = 0xff;
printk("StaticRes : %x\n",StaticRes);
//判断状态寄存器读标志是否为空,当为空时,说明数据寄存器已经获取完
while (StaticRes &(0x1));
high_data = DataRes;
high_data= (high_data<<7);
//第二次数据寄存器获取值
DataRes = 0xff;
while (StaticRes &(0x1));
low_data = DataRes;
low_data = (low_data>>1);
// 将两次寄存器获取的值合并
data = high_data + low_data;
data &= 0x0fff;
printk("data : %d\n",data);
mdelay(5);
//在获取完值要关闭片选寄存器
PianRes = 0xff;
}
return 0;
}
static void __exit spi_exit(void)
{
printk("exit!\n");
}
module_init(spi_init);
module_exit(spi_exit);
MODULE_LICENSE("GPL");