嵌入式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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...