2013年8月30日 星期五

SPI(Serial Peripheral Interface)

Overview

  • Serial interface
  • Synchronous
  • Master-Slave
  • Data Exchange

其中Synchronous protocol

  1. 資料沿著clock(SCK)來傳送
  2. 當data 需改變及被讀取時,對clock 控制
  3. 因為是同步(synchronous),所以化的clock rate是可變的,不像RS-232等的通訊

Master-Slave protocol

  • 只有一個master可以去控制SCK(clock)
  • 直到其clock signal 出現才可以傳送資料
  • all slave 都是由master clock來控制
  • slave device 可能不會去管clock

Data Exchange protocol

  • data is being clocked out,new data is clocked in
  • data is exchanged-no device is only transmitter or receive only
  • the master controls the exchange by the clock line

它在"transmits" data一筆後,必先去讀取進來的資料,若進來的資料不可讀時

這一筆的資料,就會loss並且其SPI module變成disable as result.

 

SS(CS) pin define: Slave Select/Chip Select. the master wisch to staart an SPI data exchange between that slave device and itself.

it often used to improve noise (to reset the SPI slave so that it is ready to receive the next byte)

 

Data(MOSI/MISO): data is only output during the rising or falling edge of SCK.

而data會在相對的負edge(+->-)來latche;並確認資料正確後讀取

image

pin descritor:

SS(chip Select or Slave Select):

when this signal go to low ,the slave will listend for SPI clock and data

SCK(serial clock):

to control when data in/out

SDO(serial data out):

this signal carries the data sent out of the device.

SDI(serial data input):

this signal carries the data sent into the device.

image

image

SSPSR (shift register) for SPI module. it shift data in and out of the device . the data travels in a loop to the next shift register

image

image

 

image

image

 

74HC595+ SPI =expander(output)

&4HC165+SPI=

自強基金協會-上課心得Stellaris EKS_LM3S3748

image

image

image

image

image

image

image

image

image

 

其中,特別的是為了可以在多個開發工具(不同cpu/compiler..)

將其環境,以bat file 來加以設定.而非固定

path=C:\Program Files\Putty;%path%

set MCU_ROOT=c:
path=%MCU_ROOT%\UnxUtils\winXpBin;%MCU_ROOT%\UnxUtils\bin;%MCU_ROOT%\UnxUtils\usr\local\wbin;%path%

path=C:\Program Files\CodeSourcery\Sourcery_CodeBench_Lite_for_ARM_EABI\bin;%path%

ARM的定址與組合語言

ARM的定址:

在ARM中運算方式是採用Load/Stor架構

(即其運算,需先放在暫存器中且結果也是)

image

image

  • 立即定址:
    • 即其運算元本身即為其資料。故取出指令也就取得運算元.
    • ADD R3,R3,#1 ;R3=R3+1
    • ADD R8,R7,#&ff ;R8=R7[7:0]
    • 是"#"為頭開.十六進位為在"#"後加0x or &
  • 暫存器定址:
    • 以暫存器中的內含值作為運算元。
    • ADD r1,r2,r3 ;r1=r2+r3
  • 暫存器間接定址:
    • 以暫存器中的數值作為運算元的位址,而真正的運算元放在"memory"
    • ADD r0,r1,[r2] ;r0=r1+[r2]
    • Ldr r0,[r1] ; r0=[r1]
    • 暫存器間接定址大多使用一個暫存器(基底暫存器)的數值作為記憶体的位址.
  • 基底定址:
    • 將暫存器(基底)的內容與指今中所給多的位址偏移量加以相加,並進而得到一個運算元的有效位址
    • LDR r0,[r1,#4] ; r0=[r1+4]
    • 用來處理基底附近的記憶体,基底加偏移量:前索引(pre-index)和後索引(基底+索引定址)
    • "暫存器間接定址[]"是移移量為0的氐加上偏移定址 ;"基底加偏移[,#]"定址中基底暫存器包含的並非是確定位址,基底需加(減)若干偏移量(max 4KB)來計算所要處理的位址。
    • 除了找到基底定址所指資料外,還可改為基底暫存器內容
    • LDR r0,[r1,#4]! ;r0=[r1+4],r1=r1+4,以"!"表示在完成資料傳送後,同時更新基底暫存器內容.
    • 前索引 [r1,#4] ;後索引[r1],#4。
    • 後索引:基底不包今偏移量來做傳送的位址,且再傳送後,自動加上索引
    • LDR r0,[r1],#4 ;r0=[r1],r1=r1+#4
    • image
  • 相對定址:
    • 以PC計數暫存器為基底,而指今中的位址作為偏移量來得到有效位址
    • BL Next
    • Next
    • mov pc,lr
  • 多暫存器定址:
    • 一個指今完成多個暫存器的傳送
    • LDMIA R0,{R1,R2,R3,R4}; R1=[R0];R2=[R0+4];R3=[R0+8];R4=[R0+12]
    • 最多可傳16個暫存器及其"IA"為表示在執行完LOAD/STOR後,r0以work增加長度。
  • 堆疊定址:
    • LIFO/FILO
    • 以一個堆疊指標器來指向一塊stack的頂端,並且可分為
      • 向上:向高位址生長,
      • 向下:向低位址
    • 可分為滿遞增(FA)、空遞增(EA)、滿遞減(FD)及空遞減(ED)
    • 要pop, push存取

組合組言:

<opcode>{<cond>}{S} <Rd>,<Rn>,<Shifter-operand>

ADD r0,r1,r2 ; r0=r1+r2 ,no update flage

ADDS r0,r1,r2 ; r0=r1+r2,update flage

ADDCSS r0,r1,r2 ;if C flage set then r0=r1+r2 and update flage

CMP r0,r1 ;update flage based on r0-r1

//---------------

c file

if(z==1) r1=r2+(r3*4) ;

a.ADDS r1,r2,r3,LSL #2 ; r1=r2+r3*4 and update flage

b.EQADDS …; if zero flage is 1

其符號<>: 必存在; {}選擇項

//-----------------

ARM的指令集分為

  • 跳躍指今
  • 資料處理指令
  • 程式狀態暫存器(PSR)處理指令
  • 載入/存回指令
  • 協同處理器指今
  • 例外事件產生指令

 

image

image

image

image

image

 

image

image

image

image

 

image

image

 

image

image

image

 

image

image

image

image

 

image

image

 

image

image

程式狀態暫存器:

image

image

image

image

http://www.slideshare.net/jserv/arm-and-soc-traning-part-ii-system

Caption

電容器,基本構造為二塊相距很近並且中間夾著絶緣体(固体、氣体及液体)的導電極皮來構成一個簡單的電容器。當電容器的兩極分別帶有正、負電荷時,由於異性電荷的相互吸引,它們能儲存在電容器中,所以電容器實質上是儲存電能的元件。而電容器儲存電荷的能力越大,它的電容量就愈大。電容器具有阻止直流電通過,而允許交流通過(同時有阻疑作用)的特性。

  1. 振蘯
  2. 調諧
  3. 濾波
  4. 旁路
  5. 藉合

以其結構:

  • 固定式
  • 可變

以其介質:

  • 紙介
  • 瓷介
  • 有機薄膜
  • 電解
  • 空氣

"電容器的電性能及應用場合在很大程度是取介功介質的特性"

 

固定式電容:

 

主要參數:

  1. 電容量
  2. 額定直流工作電壓
  3. 電容量允許誤差

電容量,儲存電荷的能力大小,由其電容本身的構造決定。電容器的極皮面積愈大,介質越蒲,介電常數(由介質決定)愈大,其所得電容量愈大,反之則愈小。

 

電容器的額定直流工作電壓,"耐壓"。當電容器的工作電壓超過耐壓,就會擊穿裡面的介質,造成其不可修複。

 

電容器的誤差,是指它的容量的實際值和標準值的百分比。通常分為3個等級。

1.+- 5%

2.+- 10%

3.+- 20% .

ps.普通鋁質電解電容的誤差大,+-30~~+ – 100%

 

電容值標注方法:

1.直接標注:

大都標注在元件上,標準容量、耐壓及誤差。

規定是:

容量用小數點時,則省略的單位微法(uF)。若是整數時,則省略的是皮法(pF)。

而對於幾~千微法的大電容器,其標式單位應不可省略。另外,若是零點零幾的,常會去省略整數"0"省略。

0.001uF==>.001uF。

而對於較小的,則其標示法普通為"數字符號法"。其用法為用2-4位數和一個字母表示電容量。

其中數字表示有效數值,字母表示量級,即p(皮法 10^-12F),n(表毫微法10^-9);u(表微法10^-6);m(表毫法10^-3)。.同時字母表示其小數點位置。1p5==1.5 x 10^-12F。而其誤差為字母表示,F=+-1%; G=+-2%;J=+- 5%;K=+- 10%;L=+- 15%;M=+-20%;

N=+-30%。

 

另外也有"用數碼標示法",其規則是:三個數字。一及二為有效數字,第三則是其倍乘數。其單位為皮法(pF)。

104K=10 x10^4x 10^-12=10x10^-8=0.1uF +-10%。

使用時,注意其特定使用條件;

1.紙介電容不能用於高頻電路。

2.容量足夠,直流耐壓毫的電解,不能代替交流電路(如電動機啓動)中的電容器。

3.有極性的電容器不能用於純交流電路,但可以用於脈動直流電路。

4.多電容串/並聯,其計算方法和電阻相反。

5.需較大的無極電容時,可用有極性電解電容器反向串聯後代替。

負極對負極或正極對正極串聯後,就變為無極性電解器其大小為一半。

--||----||---

   +  +

6.電容器在接入時,應檢查是否有短路、漏電和斷路,並校對其數值後使用。

image

Diode 二極管(体)

功用:

整流、濾波 及 開關。

其結構有:

點接觸式:接觸面積小,故其通過電流小。用於高頻檢波及微弱交流的整流。

面接觸式:其PN接面大,使其通過電流大,用於大交流的整流。

硅平面型:一般類型,其穩定性高,多用於開關、脈沖及高頻電路。

特性:

正向,小電阻。反正,大電阻。

同可能會因其電流過大而燒毀。

電氣特性:

1.最大整流電流(Ifm),指二極体在長其連續工作時,允許正向通過PN接面的"最大平均電流"。

2.最高反向工作電壓(Urm),指反向君在二極体二端而不致引起PN擊穿的最大電壓。實際選擇二倍的二極体。

3.正向電壓降(Uf),愈小愈好,導通時兩端產生的正向壓降。

4.反向電流(Ir),指diode在規定溫度和最高反向電壓下其反相電流。愈小愈好。

5.最高工作頻率(Fm),因其接面中的電容影響,其二極体可應用的工作頻率的上限。檢波'整流時。

 

檢測方法:

好壞,以電表(RX100 或 RX1K)量測。

正向小(Ge, 200~500;Si,3K;反向大。

 

使用常識;

1.電路中作用、型號及主要參數要求。

在整流中,需反向電壓及整流電流。小信號時,多使用Ge(0.2);信號強時,用Si(0.65,耐高溫及不易擊穿)

焊接其,極性正確外,其引線不要短於0.8cm,離根部3mm以內不可彎,可以其焊接時應用60W(2~3 S,需用夾子散熱)

C.安裝位置,其散熱。工作在高頻或脈沖時其引線要短,不應用長引線來散熱。而其最大整流電流Irm是指在"電阻或電感負載時的半波平均值;若用於電容負載時,則應降低20%使用)

D.可用二個diode來代替高電流/電壓 diode.

 

===============================================

穩壓二極体(齊納),用來穩定工作電壓的二極体。

普通的二極体外加反向電壓到一定數值後,反向電流會加大到燒毀(擊穿)。而齊納二極体卻可以在反向擊穿下工作,只要限制其工作電流)

使其PN接反被擊穿後,其端電壓在一定範圍內不隨反向電流而變化。

其相關的參數有;

1.穩定電壓(Uz);指穩壓二極体在起穩壓作作的範圍,其兩端的反向電壓值,"穩壓值"(需實測,並隨溫度改變)

2.工作電流(Iz);指在穩壓下其反向工作電流。(由負到正向)

3.最大工作電流(Izm);穩壓二極体長期工作時,所允許通過的最大反向電流值。

4.最大消耗功率(Pm): Uz X Iz

5.動態電阻(Rz);穩壓(反向)下,其電阻變化小。delta Rz.

 

實際電路中,其穩壓電流要取大一點(Izm的 1/2~1/5) 。並以最大功率及穩壓,反求其Iz.

 

檢測方法;

跟一般dideo一樣。

使用常識;

1.遵循三要點;

a,配合合適的限流電阻,

b.反相

c.在工作溫度中,要求穩壓二極体Izm' Pzm

d.可串聯其VD(齊納)。但不可並接。

e.焊接時,散熱

f.可以普通二極体+齊納組合。或是用三極体(9013)中的B, E(6~9),Iz=10mA.做穩壓

g.具溫度補償的穩壓二極体(3根),有一根不用(用於測量,分析)

C語言中的記憶体佈局

記憶体佈局結構,即在linker過程中各段的組成以及在執行中各段的載入的情況。

  • 記憶体中各個段的組成
  • 程式的連結過程中的特性及常見錯誤
  • 執行的方式。

其所產生的binary file中,其組成有

  1. code(text):即所執行的程序。
  2. Ro data:即不會被改變的的資料。像是"字串,"xxxx"。
  3. RW data:其變數(非區域)且有被正確初始化,其會佔用記憶体空間,以供程式讀寫。
  4. BSS:未始化資料,其不會佔用binary file的大小。而是在程式執行時才去建立。
  5. heap:只在程式執行時出現,由程式者建立及釋放。
  6. stack:只在程式執行時出現,內容為函式中變數、參數或返回值。均是建立在stack上。

因為有些是一開始binary file中就存在的;而某些則是在程式開始執行時才出現的。故又可分為:

"映射"(code、RO and RW)及"執行"(BSS,stack and heap)。

其各個組件,可以稱為"段,segment"。

 

C語言中各段說明:

  • Code:
    • 各函式
    • 基本運算(+,-,* and / . &&, ||,&,| and ~)
    • if ..else …
    • while/for.
  • Ro data:
    • 任何在程式中不會被改變的數值,即為Ro data
    • 唯讀的全域變數: const char a[]={“abcd”};
    • 唯讀的局域變數:const char b[]={“test”};
    • 常數:printf("test\n"); 其中會把test\n.視為常數。
    • "使用時const 時,必定需要初始化"
    • const char ro[] , const char* ptr;均指向RO。而其指向的內容都不可改變。其差別在於ro[]在程式中不可改變;而ptr在程式中可以改。
    • error: incompatible types when assigning to type 'const char[4]' from type 'char *'|
  • Rw data:
    • 已初始化的全域變數。char a[]={“1234”};
    • 已初始化的局域靜態變數。static char b[]={"test"};
    • "只有初始化才會形成RW data。若沒有時,則會成為BSS"
    • 若其初始化的全域變數+static 時,則代表其只能在這個檔案內可存取。
  • BSS:
    • block start by symbol。即沒有被初始化的資料,因此它只有在object file中被標示,而不會真正成為object file中的一部份。
  • **static修飾;不論其變數是宣告在函式內/外。其compiler/linker均把它放在全域段中。但其函式內外其可視的範圍不同。
  • 函式內,只能在此函式內;函式外,只能在此檔案內。
  • 若其在函式內變數,沒有修飾(static/const)則為statck 。Static 視是否有初始?有,RW :否,BSS。const 均在RO中。
   1: const char ro[]={"abc"};
   2: const char* ptr="test";

imageptr為D ,RW 全域。 而ro為R,RO,全域。


而若你將其const char 放在函式內則其視其為區域變數(stack),只是它不改變...而已.



   1: static char ro[]={"abc"};



函式外;


有無static, 外部可讀否。均放在RW中


函式內;


有無 static,為RW,或stack


image


最後,在C語言中,讀寫資料段和末初始化資料段中是包含了;全域變數、單個檔案內使用的全域變數(加static)、局部靜態變數(加static)。


 


各個目的檔的關係

callback functioin

callback機制在系統中運作時機。各層次軟体協同處理時用到。

下層是一個GUI系統,具有繪製介面功能,上層將callback function point傳給下層,而當介面產生事件時,callback function回到上層中,,去執行其行為。

基本:

   1: #include <stdio.h>
   2: #include <stdlib.h>
   3: #include <string.h>
   4: typedef void (*T_SIMPLE_CALLBACK)(void);
   5: void simple_callback(void)
   6: {
   7:     printf("++++simple callback++++++\n");
   8: }
   9:  
  10: void test_simple_callback(T_SIMPLE_CALLBACK p_simple)
  11: {
  12:     printf("=========test the callback function start==\n");
  13:     if(p_simple)//
  14:         (*p_simple)();
  15:     else
  16:         printf("no callback function\n");
  17:     printf("=========test the callback function end==\n");
  18:     return;
  19: }
  20:  
  21: int main()
  22: {
  23: test_simple_callback(simple_callback);
  24: return 0;
  25: }

image


image


由結果看出其,在test_simple_callback function執行中,實際上透過參數傳遞進來的函數指標呼叫了回呼函數simple_callback。


其順序為main->test_simple_callback—>simple_callback。而main及simple_callback為上層模組;而test_simple_callback為下層。故當在test_simple_callback中時,called 屬於上層的simple_callback時。即為callback 。


 


干預的callback


典型callback function,含有二個整數參數及整數的返回值。第一個參數是由下層定義的,第二個參數由下層定義,返回值是經由上層經由callback functiion回授給下層的。



   1: #include <stdio.h>
   2: #include <stdlib.h>
   3: #include <string.h>
   4: typedef void (*T_SIMPLE_CALLBACK)(void);
   5: typedef unsigned int (*T_FULL_CALLBACK)(unsigned int para1,unsigned int para2);
   6: void simple_callback(void)
   7: {
   8:     printf("++++simple callback++++++\n");
   9: }
  10: unsigned int full_callback(unsigned int para1,unsigned int para2)
  11: {
  12:     printf("++++full callback++++++\n");
  13:     printf("+para1 :%d, +para2 :%d\n",para1 ,para2 );
  14:     return para2 +para1 ;
  15: }
  16:  
  17: void test_full_callback(T_FULL_CALLBACK p_full,unsigned int para2 )
  18: {
  19:     unsigned int para_callback;
  20:     unsigned int ret_callback;
  21:     para_callback =100;
  22:     printf("===test_full_call_begin\n");
  23:     if(p_full)
  24:     {
  25:         ret_callback =(*p_full)(para_callback ,para2);
  26:         printf("====ret_callback=%d===\n", ret_callback);
  27:     }
  28:     else
  29:         printf("------no_callback----\n");
  30:     printf("===test_full_callback end====\n");
  31:  
  32:  
  33: }
  34:  
  35: void test_simple_callback(T_SIMPLE_CALLBACK p_simple)
  36: {
  37:     printf("=========test the callback function start==\n");
  38:     if(p_simple)//
  39:         (*p_simple)();
  40:     else
  41:         printf("no callback function\n");
  42:     printf("=========test the callback function end==\n");
  43:     return;
  44: }
  45:  
  46: int main()
  47: {
  48: //test_simple_callback(simple_callback);
  49: test_full_callback(full_callback ,1234);
  50: return 0;
  51: }




image


在full_callback 中,第一參數是由下層給的,代表著下層的狀態;而第二個則是main經由test_full_callback間接再給full_callback用著表示上層的資訊。而full_callback function依這二值去運作,並在full_callback返回(到下層)去確定其執行情況。


"透過callback functiion干預了下層模組的執行"


image


 


callback function 使用


使用C語言中,標準函式庫中的函式qsort(void *base,size_t nmemb,size_t size,int(*compar)(const void *,const void *));


其中



  • base:排序的陣列開頭
  • nmemb:陣列中元素數量
  • size:每一個元素的大小
  • compara:為一個函式指標,用來判斷二個元素間的大小關係,若第一個參數值大於第二個則傳回大於0的值;相等時傳回0及小於時傳回小於0值。


   1: #include <stdio.h>
   2: #include <stdlib.h>
   3: #include <string.h>
   4:  
   5: #define ARRAY_MAX 5
   6: int array_1[ARRAY_MAX]={23,46,19,77,35};
   7: static int sort_int_function(const void *a,const void *b)
   8: {
   9:     return *(int*)a-*(int*)b;
  10: }
  11:  
  12:  
  13: int main()
  14: {
  15:     int i;
  16:     printf("====befor sort===\n");
  17:     for(  i = 0; i < ARRAY_MAX; i += 1)
  18:     {
  19:         printf("array[%d]:%d\n", i, array_1[i]);
  20:  
  21:     }
  22:     qsort((void*)array_1,ARRAY_MAX,sizeof(int),sort_int_function);
  23:     printf("====after sort===\n");
  24:     for(  i = 0; i < ARRAY_MAX; i += 1)
  25:     {
  26:         printf("array[%d]:%d\n", i, array_1[i]);
  27:  
  28:     }
  29:  
  30: return 0;
  31: }

image