loongson 1B spi0 简单编程

芯片类型:MCP3201

 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");



发布了25 篇原创文章 · 获赞 5 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章