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

歷史上的今天

今天是:2024年09月01日(星期日)

正在發生

2021年09月01日 | S3C2440—12.按鍵中斷

發布者:數字沖浪 來源: eefocus關鍵字:S3C2440  按鍵中斷 手機看文章 掃描二維碼
隨時隨地手機看文章

一. 總體

要驅動按鍵中斷控制LED亮滅,程序要進行如下幾部分操作:


在start.S中對CPSR寄存器中清除I位,使能IRQ,這是大前提

根據原理圖找出按鍵對應的外部中斷,對外部中斷對應引腳做相應配置,使能相應的外部中斷:EINTMASK

開啟中斷使能:INTMSK要設置

編寫C中斷處理函數,通過INTOFFSET、EINTPEND確定哪個中斷觸發,并做相應處理,還要清除中斷標志位

編寫start.S中的IRQ異常處理函數


二. CPSR設置

在這里插入圖片描述

CPSR的IRQ中斷使能位不使能,都行不通,我就找bug找了一天。。。


在代碼重定位之后就對CPSR的I位清零,并且分配棧指針,如下:


mrs r0, cpsr         /* 讀出cpsr */

bic r0, r0, #0xf     /* 修改M4-M0為0b10000, 進入usr模式 */

bic r0, r0, #(1<<7)  /* 清除I位, 使能中斷 */

msr cpsr, r0


/* 設置 sp_usr */

ldr sp, =0x33f00000


CPU再運行程序的時候,會自動使用棧,棧指針sp在調用C程序之前就要設定。 CPU的內存RAM空間存放規律一般是分段的,從地址向高地址,依次為:程序段(.text),BSS段,然后上面還可能會有堆空間,然后最上面才是堆棧段,這樣安排堆棧,是因為堆棧的特點決定的,所以堆棧的指針SP初始化一般在堆棧段的高地址,也就是內存的高地址,然后讓堆棧指針向下增長(其實就是遞減)。這樣做的好處就是堆棧空間遠離了其他段,不會跟其他段重疊,造成修改其他段數據,而引起不可預料的后果,還有設置堆棧大小的原則,要保證棧不會下溢出到數據空間或者程序空間。所謂堆棧溢出,是指堆棧指針SP向下增長到其他段空間,如果棧指針向下增長到其他段空間,稱為堆棧溢出。堆棧溢出會修改其他空間的值,嚴重情況下可造成死機.


三. 中斷源設置

中斷源的設置,主要是三點:


配置按鍵引腳為外部中斷模式

配置外部中斷的觸發方式:上升沿、下降沿都觸發

使能相應的外部中斷線(EINT0~3默認開啟使能)

通過查看板子的原理圖獲取按鍵對應的引腳,以及對應的外部中斷線,中斷源配置的代碼如下:


/* 中斷源(按鍵引腳)初始化 

 * EINT0  EINT2  EINT11  EINT19

 * GPF0   GPF2   GPG3    GPG11

 *  S2     S3     S4      S5

 * 說明:配置按鍵對應的引腳、配置中斷觸發方式

*/

void Exti_SoucreKeyInit( void )

{

    /* GPF0、2配置為外部中斷引腳模式 */

    GPFCON &= ~( (3<<0)|(3<<4) );

    GPFCON |=  ( (2<<0)|(2<<4) ); 


    /* GPG3、11配置為外部中斷引腳模式 */

    GPGCON &= ~( (3<<6)|(3<<22) );

    GPGCON |=  ( (2<<6)|(2<<22) );


    /* EXTINTx 外部中斷控制寄存器設置中斷觸發模式:上升沿、下降沿都觸發 配置相應位為11x */

    EXTINT0 |= ( (7<<0)|(7<<8) );   //EXINT0、2

    EXTINT1 |=  (7<<12);            //EXINT11

    EXTINT2 |=  (7<<12);            //EXINT19


        /* EINTMASK 外部中斷使能寄存器,開啟對應的外部中斷,清零開啟 */

    EINTMASK &= ~( (1<<11)|(1<<19) ); //EINT0~3默認開啟使能 

}


四. 中斷控制器設置

根據中斷的流程圖來配置,先分析一下各個寄存器:

在這里插入圖片描述

MODE用來配置中斷的模式,可以選擇中斷模式為FIQ,這里我們只使用IRQ,所以MODE寄存器不需要設置,如圖:默認是IRQ

在這里插入圖片描述

MASK相當于使能位(默認是屏蔽的),所以要清零INTMASK寄存器使能相應的中斷。設置INTMASK來使能:

在這里插入圖片描述

讀取INTPND可以得到當前正在處理的中斷是哪一個,因為可能存在多個中斷請求在排隊,優先級問題。配合OFFSET寄存器使用效果更加。


而且不需要手動清除INTPND,在清除SRCPND的時候,INTPND會自動清除


SRCPND寄存器用來產看發生請求的中斷控制線(中斷源):

外部中斷是without sub-register的,所以中斷的請求直達SRCPND,所以可以通過SRCPND寄存器來顯示是否有中斷請求,相當于中斷標志位,所以在處理中斷之后需要清除SRCPND。


所以在初始化中斷控制器的時候,只要打開使能位即可,就是配置一下INTMASK就可以。SRCPND和INTPND是在中斷處理函數里使用的,判斷是哪一個中斷請求的


中斷控制器有關的初始化代碼如下:


/* 中斷控制器初始化 

 * 說明:開啟中斷使能,在EINTMASK、INTMSK中,只有EINT0~3是默認不屏蔽的

 */

void Exti_InterruptControlInit( void )

{

    /* 開啟中斷使能 */

    INTMSK &= ~( (1<<0)|(1<<2)|(1<<5) );

}


五. C中斷處理函數

在C中斷處理函數中,要分辨中斷請求,根據相應的中斷請求做出回應,我使用按鍵來控制三個LED的亮滅狀態,具體代碼如下:


#define LED1_ON  GPFDAT &= ~(1<<4)

#define LED2_ON  GPFDAT &= ~(1<<5)

#define LED3_ON  GPFDAT &= ~(1<<6)


#define LED1_OFF  GPFDAT |= (1<<4)

#define LED2_OFF  GPFDAT |= (1<<5)

#define LED3_OFF  GPFDAT |= (1<<6)


/* 中斷處理函數 

 * 說明:觸發外部中斷后,進入中斷處理函數,通過SRCPND來判斷觸發了哪一個中斷,從而進行相應的操作。退出時要清理中斷

 */

void Exti_ProcessingInterrupt( void )

{


      unsigned int temp = INTOFFSET;

    unsigned int reset = 0;//用來清零up,

    puts("nrIRQ!nr");

    /*  可以通過INTOFFSET寄存器的值來直接判斷哪個中斷觸發了 */

    if( temp==0 )      //EINT0

    {

        if(GPFDAT&(1<<0))  //引腳高電平,按鍵按下,點亮LED

        {

            LED1_ON;

        }

        else

        {

            LED1_OFF;

        }

        reset |= (1<<0);

    }

    else if( temp==2 ) //EINT2

    {

        if(GPFDAT&(1<<2)) //GPF2

        {

            LED2_ON;

        }

        else

        {

            LED2_OFF;

        }

        reset |= (1<<2);

    }

    else if( temp==5 ) //EINT8_23

    {

        if( EINTPEND&(1<<11) )

        {

            if(GPGDAT&(1<<3)) //GPG3

            {

              LED3_ON;

            }

          else

          {

             LED3_OFF;

          }

        }

        

        else if( EINTPEND&(1<<19) )

        {

            if(GPGDAT&(1<<11)) //GPG11

        {

            LED1_ON;

            LED2_ON;

            LED3_ON;

        }

        else

        {

            LED1_OFF;

            LED2_OFF;

            LED3_OFF;

        }

        }

        

        reset |= (1<<5);

    }


    /* 清除SRCPND、INTPND標志位 */

    EINTPEND |= ( (1<<11)|(1<19) );//寫1清除


    SRCPND |= ( (1<<0)|(1<2)|(1<<5) );

    INTPND |= ( (1<<0)|(1<2)|(1<<5) ); 


}


最后還要清除EINTPEND、SRCPND、INTPND中的標志位,不然程序會一直處于中斷中。


六. 匯編IRQ異常處理程序

當觸發外部中斷時,CPU會去中斷向量表中IRQ的指令位置,跳轉到IRQ的處理程序中,所以首先得在_start之后的0X18處寫一個跳轉指令,跳轉至IRQ處理程序,如下:


_start:

/* 異常向量表 */

bl reset   /* 0X0  Reset 上電復位,從0地址開始執行程序,依次:關閉看門狗、配置時鐘系統、初始化sdram、拷貝代碼到sdram(重定位)、清除.bcc段、進入mian函數 */

bl halt     /* 0X4  Undefined instruction */

bl halt     /* 0X8  Software Interrupt */

bl halt      /* 0XC  Abort(prefetch) */

bl halt      /* 0X10 Abort(data) */

bl halt      /* 0X14 Reserved */

ldr pc, =irq_addr      /* 0X18 IRQ */

bl halt              /* 0X1C FIQ */ 


.align 4

irq_addr:

.word do_irq


在do_irq程序中,首先指定棧指針,然后保存現場(注意返回的值是lr-4),然后調用C處理函數,然后恢復現場,如下:


.align 4

do_irq:

ldr sp, =0x33d00000


sub lr, lr, #4            /* 發生中斷時,返回值是lr-4 */

stmdb sp!, {r0-r12,lr}


bl Exti_ProcessingInterrupt


ldmia sp!, {r0-r12,pc}^

在這里插入圖片描述

七. 源碼

start.S


.text

.global _start


_start:

/* 異常向量表 */

bl reset   /* 0X0  Reset 上電復位,從0地址開始執行程序,依次:關閉看門狗、配置時鐘系統、初始化sdram、拷貝代碼到sdram(重定位)、清除.bcc段、進入mian函數 */

bl halt     /* 0X4  Undefined instruction */

bl halt     /* 0X8  Software Interrupt */

bl halt      /* 0XC  Abort(prefetch) */

bl halt      /* 0X10 Abort(data) */

bl halt      /* 0X14 Reserved */

ldr pc, =irq_addr      /* 0X18 IRQ */

bl halt              /* 0X1C FIQ */ 


.align 4

irq_addr:

.word do_irq


.align 4

do_irq:

ldr sp, =0x33d00000


sub lr, lr, #4            /* 發生中斷時,返回值是lr-4 */

stmdb sp!, {r0-r12,lr}


bl Exti_ProcessingInterrupt


ldmia sp!, {r0-r12,pc}^


.align 4

reset:

/* 關閉看門狗 */

ldr r0, =0x53000000

ldr r1, =0

str r1, [r0]


/* 設置MPLL, FCLK : HCLK : PCLK = 400m : 100m : 50m */

/* LOCKTIME(0x4C000000) = 0xFFFFFFFF */

ldr r0, =0x4C000000

ldr r1, =0xFFFFFFFF

str r1, [r0]


/* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8  */

ldr r0, =0x4C000014

ldr r1, =0x5

str r1, [r0]


/* 設置CPU工作于異步模式 */

mrc p15,0,r0,c1,c0,0

orr r0,r0,#0xc0000000   //R1_nF:OR:R1_iA

mcr p15,0,r0,c1,c0,0


/* 設置MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0) 

*  m = MDIV+8 = 92+8=100

*  p = PDIV+2 = 1+2 = 3

*  s = SDIV = 1

*  FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M

*/

ldr r0, =0x4C000004

ldr r1, =(92<<12)|(1<<4)|(1<<0)

str r1, [r0]


/* 一旦設置PLL, 就會鎖定lock time直到PLL輸出穩定

* 然后CPU工作于新的頻率FCLK

*/


/* 設置內存: sp 棧 */

/* 分辨是nor/nand啟動

* 寫0到0地址, 再讀出來

* 如果得到0, 表示0地址上的內容被修改了, 它對應ram, 這就是nand啟動

* 否則就是nor啟動

*/

mov r1, #0

ldr r0, [r1] /* 讀出原來的值備份 */

str r1, [r1] /* 0->[0] */ 

ldr r2, [r1] /* r2=[0] */

cmp r1, r2   /* r1==r2? 如果相等表示是NAND啟動 */

ldr sp, =0x40000000+4096 /* 先假設是nor啟動 */

moveq sp, #4096  /* nand啟動 */

streq r0, [r1]   /* 恢復原來的值 */


/* 代碼重定位的時候,首先初始化SDRAM,然后拷貝代碼,然后清除.bss段(防止內存訪問出錯),最后執行main函數,main就在重定位的SDRAM中去執行 */

bl sdram_init


/* 重定位text, rodata, data段整個程序 */

bl copy2sdram


/* 清除BSS段 */

bl clean_bss


mrs r0, cpsr         /* 讀出cpsr */

bic r0, r0, #0xf     /* 修改M4-M0為0b10000, 進入usr模式 */

bic r0, r0, #(1<<7)  /* 清除I位, 使能中斷 */

msr cpsr, r0


/* 設置 sp_usr */

ldr sp, =0x33f00000


//bl main  /* 使用BL命令相對跳轉, 程序仍然在NOR/sram執行 */

ldr pc, =main  /* 絕對跳轉, 跳到SDRAM */


.align 4

halt:

b halt


exti.c


#include "s3c2440_soc.h"

#include "uart.h"


/* LED引腳低電平點亮 */

#define LED1_ON  GPFDAT &= ~(1<<4)

#define LED2_ON  GPFDAT &= ~(1<<5)

#define LED3_ON  GPFDAT &= ~(1<<6)


#define LED1_OFF  GPFDAT |= (1<<4)

#define LED2_OFF  GPFDAT |= (1<<5)

#define LED3_OFF  GPFDAT |= (1<<6)


/* 中斷控制器初始化 

 * 說明:開啟中斷使能,在EINTMASK中,只有EINT0~3是默認不屏蔽的

 */

void Exti_InterruptControlInit( void )

{

    /* 開啟中斷使能 */

    INTMSK &= ~( (1<<0)|(1<<2)|(1<<5) );

}



/* 中斷源(按鍵引腳)初始化 

 * EINT0  EINT2  EINT11  EINT19

 * GPF0   GPF2   GPG3    GPG11

[1] [2]
關鍵字:S3C2440  按鍵中斷 引用地址:S3C2440—12.按鍵中斷

上一篇:LPC2000系列學習筆記4--存儲器映射控制
下一篇:S3C2440—11.und異常

推薦閱讀

智能化時代已經到來,在人工智能技術的助力下,新一代服務機器人逐漸走進人們的生活場景當中,同時顯現出巨大的市場機遇。從醫療到家庭、教育、養老、商場服務等,智能服務機器人為人類工作和生活提供了極大的便利和創造了更先進的體驗。 2018年8月30-9月1日,由中國高科技行業門戶OFweek維科網、HTC高科會主辦,OFweek人工智能網承辦的2018中國(上海...
近日,印度研究人員宣布開發出一種可充電的鐵離子電池,它以低碳鋼為陽極,具備性價比高、可儲存電量高等優勢。相關研究成果近期發表在英國皇家化學會期刊《化學通訊》上。論文說,印度理工學院馬德拉斯分院研究團隊研發的這種鐵離子電池,以低碳鋼為陽極,五氧化二釩為陰極,電解液為含高氯酸鐵的醚基電解液。研究顯示,這種電池可進行150次循環充放電,...
TCL科技于周五晚間宣布“拿下”韓商三星在蘇州的LCD產線,其控股子公司TCL華星將以10.80億美元收購蘇州三星電子液晶顯示科技有限公司(SSL)60%的股權、蘇州三星顯示有限公司(SSM)100%的股權...TCL科技8月28日晚公告,子公司TCL華星于28日與三星顯示株式會社(三星顯示)簽署《股權轉讓協議》、《增資協議》,公司與TCL華星、SSL簽署了《股東間協議》。...
市場對領先和前沿技術節點半導體器件的強勁需求,促使全球廠商迫切需要盡可能提高設備故障排查、維修和升級速度,同時加快裝機和產品驗證以加速產能攀升。最近,新冠疫情導致全球差旅受限和供應鏈中斷,使得上述挑戰變得更加棘手。這種情況凸顯了晶圓廠管理者需要進一步重視業務連續性規劃、確保合理的資源調配,即便發生最嚴重的意外事件,也能保證持續的...

史海拾趣

問答坊 | AI 解惑

portel dxp 2004 的教程

有誰有portel dxp 2004 的教程的么?給我份??謝謝!!…

查看全部問答∨

LPC1114 I2C 的問題?

不知大家有沒有弄過I2C的 原來沒有弄過, 想弄下, 前幾天看啦1114的例程大概了解,這幾天 尋思再研究下, 不知有沒有弄過的 , 分享下,     單片機的I2C 倒是弄啦下, 就是AT24C02 的EEPROM , 但是弄到1114上, 應該是有點不得 ...…

查看全部問答∨

有誰知道WinUSB怎么用的啊

主要是INF文檔怎么寫的啊,是不是裝好WINDDK后,用INF去安裝winusb.sys文件啊,弄了好久都沒弄出來不知道有沒有人在成功過的,幫幫忙啊。…

查看全部問答∨

欲購買MTK開發板

  我現在想研究一下在MTK下的開發,現在想購買一塊MTK開發板,有預售者可和我用QQ聯系331901119  (9:30~17:30均在線)…

查看全部問答∨

mini2440 與數據庫連接及處理問題

現有一個運行在IBM大型主機上的DB2數據庫,數據量比較大,LS讓我找一個攜帶方便的小開發板(價錢不要超過一臺普通PC,可以掛在墻上,能手持的最好),我選了MINI2440,現在需要從數據庫里取一部分數據,在板子上用形象一點的圖顯示出來,同時也能往 ...…

查看全部問答∨

學硬件和嵌入式系統方面的一般有什么證要考呢

學硬件和嵌入式系統方面的一般有什么證要考呢? 其考試時間一般是什么時候? 在哪里可以找到相關的考試資料和信息? 這些證的含金量怎樣?我是學硬件的,將來也想從事嵌入式系統設計方面工作,考什么證好些呢?…

查看全部問答∨

wince能手都來看看

2009年應是金融危機體現最大一年,但是我們公司逆流而上,借此機遇擴充、收編開發隊伍。只要符合招聘要求的,愿意到珠三角工作,薪金待遇絕對豐厚。 高級wince開發工程師 職責描述: 1、負責WinCE嵌入式產品底層驅動、軟件的開發,主要包括CE內 ...…

查看全部問答∨

CEPC選擇"Enable Kernel Debugger"后出現錯誤

1.我用CEPC創建了一個工程,但是發現使用KITL和"Enable Full Kernel Mode"項后,是可以啟動的 2.增加"Enable Kernel Debugger"項后,CEPC無法起來   彈出"The Debugger KITL packet receive has timed out. Do you wish to retr ...…

查看全部問答∨

用vs2005mfc編寫wince程序,如何遍歷系統下的所有目錄及子目錄?

用vs2005mfc編寫wince程序,如何遍歷系統下的所有目錄及子目錄? 試過了很多方法,都不行,mfc中的CFileFind類在人wince下不支持,郁悶哦! 請高手指教!!…

查看全部問答∨

新手發帖,壇子里的51板子有問題?

SOSO姐,TIANKAI大哥。首先謝謝你們的板子。雖然到現在還用不上,但是通過這幾天自己的擺弄,對51有了初步的認識。 51MUC內部結構還不是很懂,但是對咱壇子里的板子原理,我是了解的很深了。現在,我發現了一個問題。不知道對不對。   大家 ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

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

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

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 小金县| 左贡县| 绍兴市| 南丰县| 伊川县| 久治县| 平罗县| 平邑县| 绥宁县| 鹤峰县| 汉中市| 株洲市| 宁德市| 泸定县| 蓝山县| 武陟县| 卢龙县| 彰化市| 沅江市| 信丰县| 阿荣旗| 比如县| 东海县| 女性| 南溪县| 开化县| 伊宁县| 冷水江市| 喀喇沁旗| 康定县| 新源县| 金坛市| 白河县| 鸡西市| 息烽县| 赞皇县| 新宁县| 南木林县| 聊城市| 洛浦县| 江西省|