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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章