嵌入式GPIO介面及操作(二)

来源:http://www.cnblogs.com/Ye-Jason/archive/2017/08/13/7353691.html
-Advertisement-
Play Games

目標:C語言實現點亮LED燈 首先是main函數,並不特殊,它是被系統調用來執行的,main函數結束後要返回調用main函數的地址處,那麼裸機程式,沒有操作系統做這些工作,就要自己寫調用main函數的程式了。軟體相關的初始化:1、設置棧 2、設置main函數返回地址 3、調用main 4、清理工作所 ...


目標:C語言實現點亮LED燈

首先是main函數,並不特殊,它是被系統調用來執行的,main函數結束後要返回調用main函數的地址處,那麼裸機程式,沒有操作系統做這些工作,就要自己寫調用main函數的程式了。
軟體相關的初始化:
1、設置棧 2、設置main函數返回地址 3、調用main 4、清理工作

所謂設置棧就是將棧指針SP指向某塊記憶體,在S3C2440中這塊記憶體可以是片內SRAM,這樣不用初始化記憶體了,如果指向SDRAM,那麼首先要初始化SDRAM。
硬體相關的初始化:
a、關閉看門狗;b、初始化時鐘;c、初始化SDRAM等
軟體相關初始化和硬體相關初始化結合一起就是啟動文件。

下麵是用C語言寫的代碼
這一段代碼是彙編語言,作用相當於啟動文件,在這裡為了簡單,在硬體方面初始化只關閉了看門狗,軟體方面初始化設置了棧。

crt.S

.text  
.global _start  
_start:  
            ldr r0,=0x53000000  @看門狗地址  
            mov r1,#0x0  
            str r1,[r0] @寫入0,關閉看門狗  
            ldr sp,=1024*4  @設置堆棧,註意不能大於4K  
              
            bl  main  
halt_loop:  
            b halt_loop  

分析這段彙編程式,首先初始化硬體相關的,關閉看門狗,然後設置堆棧,在s3c2440不能大於4K,因為s3c2440片內SRAM只有4K,再然後就是調到main函數,用了bl指令,bl有兩個功能,一是跳轉,二是設置了返回地址,就是bl    main指令的下一條指令b hail_loop,所以在這裡就初始化完返回地址了。
下麵就實現c語言的main函數。

#define GPFCON  (*(volatile unsigned long *)0x56000050)  
#define GPFDAT  (*(volatile unsigned long *)0x56000054)  
int  
main()  
{  
    GPFCON = 0x00000100;  
    GPFDAT = 0x00000000;  
      
    return 0;  
}  

2、用C語言輪流點亮LED

#define GPFCON  (*(volatile unsigned long *)0x56000050)  
#define GPFDAT  (*(volatile unsigned long *)0x56000054)  
#define GPF4_out ( 1 << 4*2 )  
#define GPF5_out ( 1 << 5*2 )  
#define GPF6_out ( 1 << 6*2 )  
void   
delay(volatile unsigned long dly)  
{  
    for(;dly > 0;dly--);  
}  
int  
main()  
{  
    unsigned i = 1;  
      
    GPFCON = GPF4_out | GPF5_out | GPF6_out;  
    while(1)  
    {  
        GPFDAT = ( ~( i << 4 ) );  
        i *=2;  
        if( i == 8)  
        {  
            i = 1;  
        }  
        delay(30000);  
  
          
    }  
      
      
    return 0;  
}  

Makefile

CFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding  
led_on.bin:ctr.S main.c  
    arm-linux-gcc $(CFLAGS) -c -o ctr.o ctr.S  
    arm-linux-gcc $(CFLAGS) -c -o main.o main.c  
    arm-linux-ld -Ttext 0x00000000 ctr.o main.o -o led_on.elf  
    arm-linux-objcopy -O binary -S led_on.elf led_on.bin  
    arm-linux-objdump -D -m arm led_on.elf>led_on.dis  
clean:  
    rm -f led_on.bin led_on.elf *.o led_on.dis  

3、按鍵操作

#define GPFCON  (*(volatile unsigned long *)0x56000050)  
#define GPFDAT  (*(volatile unsigned long *)0x56000054)  
#define GPGCON  (*(volatile unsigned long *)0x56000060)  
#define GPGDAT  (*(volatile unsigned long *)0x56000064)  
  
#define GPF4_out ( 1 << 4*2 )  
#define GPF5_out ( 1 << 5*2 )  
#define GPF6_out ( 1 << 6*2 )   
  
#define GPF4_msk ( 3 << ( 4*2 ) )  
#define GPF5_msk ( 3 << ( 5*2 ) )  
#define GPF6_msk ( 3 << ( 6*2 ) )  
  
#define GPF0_in ( 0 << 0*2 )  
#define GPF2_in ( 0 << 2*2 )  
#define GPG3_in ( 0 << 3*2 )  
#define GPF0_msk ( 3 << ( 0*2 ) )  
#define GPF2_msk ( 3 << ( 2*2 ) )  
#define GPG3_msk ( 3 << ( 3*2 ) )  
int  
main( void )  
{  
    unsigned long ysdat;  
    GPFCON &= ~( GPF4_msk | GPF5_msk | GPF6_msk );  
    GPFCON |= GPF4_out |GPF5_out | GPF5_out;  
      
    GPFCON &= ~( GPF0_msk | GPF2_msk );  
    GPFCON |= GPF0_in |GPF2_in;  
      
    GPGCON &= ~( GPG3_msk );  
    GPGCON |= GPG3_in;  
      
    while(1)  
    {  
         ysdat = GPFDAT;  
           
         if( ysdat & ( 1 << 0 ) )  
         {  
            GPFDAT |= ( 1 << 4 );           
         }    
         else  
         {  
            GPFDAT &= ~( 1 << 4 );  
         }  
           
         if( ysdat & ( 1 << 2 ) )  
         {  
            GPFDAT |= ( 1 << 5 );           
         }    
         else  
         {  
            GPFDAT &= ~( 1 << 5 );  
         }  
           
         ysdat = GPGDAT;  
           
         if( ysdat & ( 1 << 3 ) )  
         {  
            GPFDAT |= ( 1 << 6 );           
         }    
         else  
         {  
            GPFDAT &= ~( 1 << 6 );  
         }  
           
    }  
      
    return 0;  
}  

Makefile

CFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding  
led_on.bin:ctr.S main.c  
    arm-linux-gcc $(CFLAGS) -c -o ctr.o ctr.S  
    arm-linux-gcc $(CFLAGS) -c -o main.o main.c  
    arm-linux-ld -Ttext 0x00000000 ctr.o main.o -o led_on.elf  
    arm-linux-objcopy -O binary -S led_on.elf led_on.bin  
    arm-linux-objdump -D -m arm led_on.elf>led_on.dis  
clean:  
    rm -f led_on.bin led_on.elf *.o led_on.dis  

通過嵌入式GPIO介面及操作(一)及這篇兩個程式的練習,能夠掌握對GPIO的操作,這是操作硬體的基本技能。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、vivi虛擬攝像頭驅動 基於V4L2(video for linux 2)攝像頭驅動程式,我們減去不需要的ioctl_fops的函數,只增加ioctl函數增加的必要的攝像頭流查詢等函數; 二、虛擬攝像頭驅動應用程式調用過程流程圖: 虛擬攝像頭一般不用自己寫的程式,而是採用網路上提供的應用程式直接 ...
  • Microsoft Visual C++ 2005 Redistributable Package (x86):Microsoft Visual C++ 2005 可再發行組件包 (x86):https://www.microsoft.com/zh-CN/download/details.aspx? ...
  • Ubuntu16.04修改源 1.備份 2.修改 3.更新 ...
  • Nginx 出現 403 Forbidden 最終解決 步驟一: 檢查目錄許可權。許可權不足的就加個許可權吧。 例子:chmod -R 755 / var/www 步驟二: 打開nginx.conf 例子:vim /etc/nginx/nginx.conf 把 user 用戶名 改為 user root ...
  • 創建兩個 shell 腳本文件。 test1.sh 代碼如下: #!/bin/bash url="http://www.cnblogs.com/freescience" test2.sh 代碼如下: #!/bin/bash #使用 . 號來引用test1.sh 文件 . ./test1.sh # 或 ...
  • RHEL7.x(CentOS7.x)系統相對之前的6.x系統變化較大,雖然安裝時選擇了中文環境,但是進入系統後,在控制台及編輯器中仍無法切換輸入法進行中文輸入。 原來還要這麼配置,,才能愉快的使用“拼音”輸入法。 ...
  • 使用LD_LIBRARY_PATH變數 如:當運行scp時出現以下提示: scp: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory那麼 ...
  • 前言 最近一直忙於和小伙伴倒騰著關於人工智慧的比賽,一直都沒有時間停下來更新更新我的博客。不過在這一個過程中,遇到了一些問題,我還是記錄了下來,等到現在比較空閑了,於是一一整理出來寫成博客。希望對於大家有幫助,如果在此有不對的地方,請大家指正,謝謝! 比賽遇到spark開啟的問題 疑惑之處 在使用百 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...