娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

s3c2440串口使用

發布者:文江桂青最新更新時間:2020-06-11 來源: elecfans關鍵字:s3c2440  串口使用 手機看文章 掃描二維碼
隨時隨地手機看文章

一、串口通信原理


UART:Universal Asynchronous Receiver/Transmitter(通用異步收發送器),用來傳輸串行數據,發送數據時,CPU將并行數據寫入UART,UART按照一定格式在TxD線上串行發出;接收數據時,UART檢測到RxD線上的信號,將串行收集放到緩沖區中,CPU即可讀取UART獲得的這些數據。

UART最精簡的連線形式只有3根線,TXD用于發送,RXD用于接收,GND用于提供參考電平。UART之間以幀作為數據傳輸單位,幀由具有完整意義的若干位組成,它包含開始位、數據位、校驗位和停止位。發送數據之前,互相通信的UART之間要約定好數據傳輸速率(波特率的倒數)、數據的傳輸格式(多少個數據位、是否使用校驗位、奇校驗還是偶校驗、多少個停止位)。


二、S3C2440串口介紹


s3c2440提供了三個UART端口,它們都可以通過查詢、中斷和DMA方式傳輸數據,而且每個UART都分別有一個64個字節的接收FIFO和一個64個字節的發送FIFO。如下圖所示:每個UART包含一個波特率發生器、發送器、接收器和一個控制單元。波特率發生器可以由PCLK、FCLK/n或UEXTCLK(外部輸入時鐘)時鐘驅動。UART通過使用系統時鐘可以支持最高115.2Kbps的比特率。如果是使用外部器件提供UEXTCLK的UART,則UART可以運行在更高的速度。發送器和接收器各包含一個64字節的FIFO和數據移位器。要發送數據時,先將數據寫入到FIFO接著在發送前復制到發送移位器中,隨后將數據從發送數據引腳(TXDn)移出;接收數據時,從接收數據引腳(RXDn)移入收到的數據,接著從移位器復制到FIFO。

三、S3C2440的串口寄存器配置


3.1 串行數據格式設置


例子:ULCON0=0x03    //8N1(正常模式 8個數據位,無較驗,1個停止位)


3.2 UART控制寄存器




例子:UCON=0x05 //時鐘使用PLCK,中斷為邊沿觸發,禁止接受和發送超時,不產生接受錯誤中斷,不采用RX、TX直接相連的調節模式,rx和tx處于中斷或者查詢模式。


3.3 UART發送接受狀態寄存器


當程序使用的是查詢方式收發數據時,必須通過讀取UART寄存器的值來正確控制UART數據的收發。


#define TXD0READY   (1<<2)

#define RXD0READY   (1)


//發送字符

void putc(unsigned char c)

{

    /* 等待,直到發送緩沖區中的數據已經全部發送出去 */

    while (!(UTRSTAT0 & TXD0READY));

    

    /* 向UTXH0寄存器中寫入數據,UART即自動將它發送出去 */

    UTXH0 = c;

}


//接受字符

unsigned char getc(void)

{

    /* 等待,直到接收緩沖區中的有數據 */

    while (!(UTRSTAT0 & RXD0READY));

    

    /* 直接讀取URXH0寄存器,即可獲得接收到的數據 */

    return URXH0;

}


3.4  發送和接受緩沖寄存器

當串口有數據可讀時,程序直接讀取URXHn,當用戶想發送數據時直接將數據寫入到UTXHn即可。


3.5 波特率寄存器


UBRDIVn由下列表達式確定:

UBRDIVn=(int)(UART時鐘/(波特率*16))-1

假如uart0采用中斷模式來收發數據我們必須要做三件事:


        1.在程序的啟動代碼中開中斷


        2.設置INTMSK和INTSUBMSK,打開uart0中斷


        3.配置GPH2,GPH3用作TXD0,RXD0


四、串口中斷控制led燈實例(tq2440)


啟動代碼:初始化時鐘、led引腳配置、uart0初始化以及中斷相關設定



.extern     main

.text 

.global _start 

_start:

@******************************************************************************       

@ 異常向量,本程序中,除Reset和HandleIRQ外,其它異常都沒有使用

@******************************************************************************       

    b   Reset


@ 0x04: 未定義指令中止模式的向量地址

HandleUndef:

    b   HandleUndef 

 

@ 0x08: 管理模式的向量地址,通過SWI指令進入此模式

HandleSWI:

    b   HandleSWI


@ 0x0c: 指令預取終止導致的異常的向量地址

HandlePrefetchAbort:

    b   HandlePrefetchAbort


@ 0x10: 數據訪問終止導致的異常的向量地址

HandleDataAbort:

    b   HandleDataAbort


@ 0x14: 保留

HandleNotUsed:

    b   HandleNotUsed


@ 0x18: 中斷模式的向量地址

    b   HandleIRQ


@ 0x1c: 快中斷模式的向量地址

HandleFIQ:

    b   HandleFIQ


Reset:                  

    ldr sp, =4096           @ 設置棧指針,以下都是C函數,調用前需要設好棧

    bl  disable_watch_dog   @ 關閉WATCHDOG,否則CPU會不斷重啟

    

    msr cpsr_c, #0xd2       @ 進入中斷模式

    ldr sp, =3072           @ 設置中斷模式棧指針


    msr cpsr_c, #0xd3       @ 進入管理模式

    ldr sp, =4096           @ 設置管理模式棧指針,

                            @ 其實復位之后,CPU就處于管理模式,

                            @ 前面的“ldr sp, =4096”完成同樣的功能,此句可省略

                           

    bl  clock_init

    bl  init_led            @ 初始化LED的GPIO管腳

    bl  init_irq            @ 調用中斷初始化函數,在init.c中

    msr cpsr_c, #0x53       @ 設置I-bit=0,開IRQ中斷

    

    ldr lr, =halt_loop      @ 設置返回地址

    ldr pc, =main           @ 調用main函數

halt_loop:

    b   halt_loop


HandleIRQ:

    sub lr, lr, #4                  @ 計算返回地址

    stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器

                                    @ 注意,此時的sp是中斷模式的sp

                                    @ 初始值是上面設置的3072

    

    ldr lr, =int_return             @ 設置調用ISR即EINT_Handle函數后的返回地址  

    ldr pc, =EINT_Handle            @ 調用中斷服務函數,在interrupt.c中

int_return:

    ldmia   sp!,    { r0-r12,pc }^  @ 中斷返回, ^表示將spsr的值復制到cpsr

啟動代碼中使用到的初始化代碼


#define GPB5_out (1<<(5*2))

#define GPB6_out (1<<(6*2))

#define GPB7_out (1<<(7*2))

#define GPB8_out (1<<(8*2))


#define GPB5_msk (3<<(5*2))

#define GPB6_msk (3<<(6*2))

#define GPB7_msk (3<<(7*2))

#define GPB8_msk (3<<(8*2))


/*

 * K1,K2,K3,K4對應GPF1、GPF4、GPF2、GPF0

 */

#define GPF0_int     (0x2<<(0*2))

#define GPF1_int     (0x2<<(1*2))

#define GPF2_int     (0x2<<(2*2))

#define GPF4_int     (0x2<<(4*2))


#define GPF0_msk    (3<<(0*2))

#define GPF1_msk    (3<<(1*2))

#define GPF2_msk    (3<<(2*2))

#define GPF4_msk    (3<<(4*2))


/*

 * 關閉WATCHDOG,否則CPU會不斷重啟

 */

void disable_watch_dog(void)

{

    WTCON = 0;  // 關閉WATCHDOG很簡單,往這個寄存器寫0即可

}


void init_led(void)

{

// LED1,LED2,LED3,LED4對應的4根引腳設為輸出

GPBCON &= ~(GPB5_msk | GPB6_msk | GPB7_msk | GPB8_msk);

GPBCON |= GPB5_out | GPB6_out | GPB7_out | GPB8_out;

}


/*

 * 初始化GPIO引腳為外部中斷

 * GPIO引腳用作外部中斷時,默認為低電平觸發、IRQ方式(不用設置INTMOD)

 */ 

void init_irq( )

{


     INTMSK &=~(1<<28);  //開啟uart0中斷

     INTSUBMSK &=~(3<<0);//開啟uart0的接收和發送中斷

     

     GPHCON  |= 0xa0;    // GPH2,GPH3用作TXD0,RXD0

     GPHUP   = 0x0c;     // GPH2,GPH3內部上拉


     ULCON0  = 0x03;     // 8N1(8個數據位,無較驗,1個停止位)

     UCON0   = 0x05;     // 查詢方式,UART時鐘源為PCLK

     UFCON0  = 0x00;     // 不使用FIFO

     UMCON0  = 0x00;     // 不使用流控

     UBRDIV0 = 0x1a;     // 波特率為115200

            

    /*

     * 設定優先級:

     * ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ2 > REQ3,即EINT0 > EINT1 > EINT2

     * 仲裁器1、6無需設置

     * 最終:

     * EINT0 > EINT1> EINT2 > EINT4 即K4 > K1 > K3 > K2

     */

    PRIORITY = (PRIORITY & ((~0x01) | ~(0x3<<7)));


    // EINT0、EINT1、EINT2、EINT4_7使能

    INTMSK   &= (~(1<<0)) & (~(1<<1)) & (~(1<<2)) & (~(1<<4));

}


/*

 * 對于MPLLCON寄存器,[19:12]為MDIV,[9:4]為PDIV,[1:0]為SDIV

 * 有如下計算公式:

 *  S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)

 *  S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)

 *  其中: m = MDIV + 8, p = PDIV + 2, s = SDIV

 * 對于本開發板,Fin = 12MHz

 * 設置CLKDIVN,令分頻比為:FCLK:HCLK:PCLK=1:2:4,

 * FCLK=200MHz,HCLK=100MHz,PCLK=50MHz

 */

void clock_init(void)

{

    CLKDIVN  = 0x03;            // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1


    /* 如果HDIVN非0,CPU的總線模式應該從“fast bus mode”變為“asynchronous bus mode” */

__asm__(

    "mrc    p15, 0, r1, c1, c0, 0n"        /* 讀出控制寄存器 */ 

    "orr    r1, r1, #0xc0000000n"          /* 設置為“asynchronous bus mode” */

    "mcr    p15, 0, r1, c1, c0, 0n"        /* 寫入控制寄存器 */

    );

    MPLLCON =((0x5c<<12)|(0x01<<4)|(0x02));  /* 現在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */

}

中斷處理函數


#include "s3c24xx.h"


void EINT_Handle()

{

/*

* K1,K2,K3,K4對應GPF1、GPF4、GPF2、GPF0

*            即 EINT1, ETIN4, EINT2, EINT0

*            oft為 1, 4, 2, 0 (對應INTMSK寄存器)

*/

    

    switch(URXH0)

    {

        // K1被按下

        case '1': 

        {   

            GPBDAT |= (0xF<<5);   // 所有LED熄滅

            GPBDAT &= ~(1<<5);      // LED1點亮

            break;

        }       

        // K2被按下

        case '2':

        {   

            GPBDAT |= (0xF<<5);   // 所有LED熄滅

            GPBDAT &= ~(1<<6);      // LED2點亮

            break;

        }

        // K3被按下

        case '3':

        {   

            GPBDAT |= (0xF<<5);   // 所有LED熄滅

            GPBDAT &= ~(1<<7);      // LED3點亮

            break;

        }

       // K4被按下

        case '4':

        {   

[1] [2]
關鍵字:s3c2440  串口使用 引用地址:s3c2440串口使用

上一篇:S3C2440串口學習
下一篇:S3C2440開發板的學習使用(一)----串口的安裝

小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京B2-20211791 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 舒城县| 都安| 承德市| 威宁| 新安县| 江门市| 陇川县| 凤台县| 神农架林区| 天全县| 泗水县| 奎屯市| 辉县市| 临沭县| 宣汉县| 固阳县| 郸城县| 监利县| 常宁市| 广河县| 东乡县| 盐津县| 乌恰县| 吉木乃县| 左云县| 丰县| 平陆县| 新营市| 大余县| 西乌珠穆沁旗| 抚州市| 旅游| 六枝特区| 桐梓县| 潜江市| 本溪市| 清水县| 巴南区| 普陀区| 耿马| 马关县|