1. 程式人生 > >暫存器操作方法

暫存器操作方法

一, 暫存器的設定和操作特性

1,一個暫存器的每個位有其不同的意義,進行不同的設定會使硬體產生不同的效果和功能;

2,有些情況下需要對一個暫存器進行連續的不同的甚至完全相反的設定;

3,有些情況下需要對一個暫存器中的某一位或一位進行連續的不同的甚至完全相反的設定,而其餘的位要保持不變;

4,有時,對一個暫存器進行設定時,對其不同的位進行先後順序不同的設定,即對其各個位有先後設定的順序的要求,使硬體產生的結果也不同;

5,有時,對於一個暫存器要求必須一次賦值,若對其某些位賦值先後順序不同,便達不到預期的效果和功能。

二,暫存器的賦值操作方法

為說明方便,定義如下3個8位的暫存器:

#define   REG     0xFFFFFF10

1,對單個的位進行賦值

(1)    將暫存器REG的第5位置“1”

REG |= (1 << 5);

(2)    將暫存器REG的第5位清零

REG &= ~(1 << 5);

(3)    將暫存器REG的第3、5位置“1”

REG |= (1 << 5) | (1 << 3);

(4)    將暫存器REG的第3、5位清零

REG &= ~( (1 << 5) | (1 << 3) );

2,直接賦值

(1)將暫存器REG的0、1、2、3、5、7位置“1”

REG = 0x5F;

(即給暫存器REG1賦值為1010 1111,這種方法多在初始化中使用)

(2)分別將暫存器REG的1、3、5、7位置“1”,0、2位置“0”

uint32 temp;

tmep = REG;               

temp &= ~0x01;       //等價於 temp &= ~(1<<0) 

 將第0位清零       

temp |= (1 << 1); 

temp &= ~(1 << 2);

temp |= (1 << 3);

temp |= (1 << 5);

temp |= (1 << 7);

REG = temp;

----------------------------------------------------------------------------------------------

1 暫存器地址的定義:
    #define UART_BASE_ADRS (0x10000000)     /* 串列埠的基地址 */
    #define UART_RHR *(volatile unsigned char *)(UART_BASE_ADRS + 0)  /* 資料接受暫存器 */  //?????????
    #define UART_THR *(volatile unsigned char *)(UART_BASE_ADRS + 0)  /* 資料傳送暫存器 */ 
2 暫存器讀寫操作:
    UART_THR = ch; /* 傳送資料 */
    ch = UART_RHR; /* 接收資料 */
    也可採用定義帶引數巨集實現
    #define WRITE_REG(addr, ch) *(volatile unsigned char *)(addr) = ch
    #define READ_REG(addr, ch) ch = *(volatile unsigned char *)(addr)
    
    
3 對暫存器相應位的操作方法:
    定義暫存器
    #define UART_LCR *(volatile unsigned char *)(UART_BASE_ADRS + 3)  /* 線控制暫存器 */
    
    定義暫存器相應位的值
    #define CHAR_LEN_5 0x00
    #define CHAR_LEN_6 0x01
    #define CHAR_LEN_7 0x02
    #define CHAR_LEN_8 0x03    /* 8 data bit */
    #define LCR_STB  0x04 /* Stop bit control */
    #define ONE_STOP 0x00 /* One stop bit! */
    #define LCR_PEN  0x08 /* Parity Enable */
    #define PARITY_NONE 0x00
    #define LCR_EPS  0x10 /* Even Parity Select */
    #define LCR_SP  0x20 /* Force Parity */
    #define LCR_SBRK 0x40 /* Start Break */
    #define LCR_DLAB 0x80 /* Divisor Latch Access Bit */
    
    定義暫存器相應位的值另一種方法
    #define CHAR_LEN_5 0<<0
    #define CHAR_LEN_6 1<<0
    #define CHAR_LEN_7 1<<1
    #define CHAR_LEN_8 (1<<0)|(1<<1)    /* 8 data bit */
    #define LCR_STB  1<<2 /* Stop bit control */
    #define ONE_STOP 0<<2 /* One stop bit! */
    #define LCR_PEN  1<<3 /* Parity Enable */
    #define PARITY_NONE 0<<3
    #define LCR_EPS  1<<4 /* Even Parity Select */
    #define LCR_SP  1<<5 /* Force Parity */
    #define LCR_SBRK 1<<6 /* Start Break */
    #define LCR_DLAB 1<<7 /* Divisor Latch Access Bit */
    
    對暫存器操作只需對相應位或賦值
    UART_LCR = CHAR_LEN_8 | ONE_STOP | PARITY_NONE;    /* 設定 8位資料位,1位停止位,無校驗位 */
    
4 對暫存器某一位置位與清零
    對某一暫存器第7位置位
    XX_CRTL |= 1<<7;
    XX_CRTL &= ~(1<<7);
       
    UART_LCR |= LCR_DLAB;           /* 時鐘分頻器鎖存使能 */
    UART_LCR &= ~(LCR_DLAB);        /* 禁止時鐘分頻器鎖存 */
    
5 判斷暫存器某一位是否置位或為0的方法
    #define UART_LSR *(volatile unsigned char *)(UART_BASE_ADRS + 5)  /* 線狀態暫存器 */
    #define LSR_DR  1<<0 /* Data Ready */
    
    當UART_LSR的第0位為1時結束迴圈
    while (!(UART_LSR & LSR_DR)) /* 等待資料接收完 */