日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FPGA 之 SOPC 系列(六)Nios II 程序开发 II

發布時間:2023/12/14 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FPGA 之 SOPC 系列(六)Nios II 程序开发 II 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

FPGA 之 SOPC 系列(六)Nios II 程序開發 II

今天給大俠帶來今天帶來FPGA 之 SOPC 系列第六篇,Nios II 程序開發 II,希望對各位大俠的學習有參考價值,話不多說,上貨。

本篇接著第五篇繼續介紹NIOS II的寄存器級編程方式,以該方式的定時器的編程實例應用。

以下為本篇的目錄簡介:

  • 6.1 項目文件的管理

  • 6.2 寄存器級編程

  • 6.3 定時器應用

?

6.1 項目文件的管理

每個C工程中,可以以功能為依據對源文件迕行文件夾分類。文件夾不可以出現空格、除英文字母、數字、下劃線外的字符;更不允許出現漢字等非 ASCII碼字符。例如某個工程可以劃分為如下文件夾:

  • doc 說明文檔

  • config 系統相關配置文件夾(系統參數配置、編譯器、連接器配置文件等)

  • driver 硬件驅動文件夾(包括芯片驅動、cpu外設驅動等)

  • font 字體驅動

  • Gui 圖形界面驅動

  • main 主程序

  • include 頭文件

  • obj 編譯后的目標文件

功能劃分應以邏輯清晰、層次關系明顯為目的。一旦劃分好后,不可越級調用系統資源(例如只有driver內文件內直接操作硬件資源,其他文件夾代碼均不可調用最底層硬件資源)。也不要互相調用而使系統資源很快耗盡

文件一旦建立,就需在文件頭說明文件目的、版權及歷史記錄,每次修改后必須記錄。工程完工或者是間歇性擱置時,需要對所有工程文件夾、文件進行只讀屬性設置及當前狀態設置。對源代碼最好做到每天一備份,以防意外篡改及丟失,以備恢復之用。

?

6.2 寄存器級編程

例:點亮LED的例子轉換新的編程方式

第一步,按照上述的文件管理方式,建立一個放置頭文件的文件夾,命名為inc, 在工程文件夾上點擊右鍵,然后點擊NEW中的SOURCE FOLDER。

下一步,在紅圈處輸入inc,點擊finish,完成文件夾建立。

下一步,在這個新建的文件夾下建立一個頭文件,方法如下圖所示,在inc上點擊右鍵,然后點擊NEW中的header file,輸入sopc.h。

打開剛才建立的頭文件,補充完代碼后如下:

#ifndef SOPC_H_ #define SOPC_H_ #include "system.h" #define _LED typedef struct { unsigned long int DATA; unsigned long int DIRECTION; unsigned long int INTERRUPT_MASK;; unsigned long int EDGE_CAPTURE; }PIO_STR; #ifdef _LED #define LED ((PIO_STR *)LED_PIO_BASE) #endif #endif /*SOPC_H_*/

其中定義了一個結構體,這個結構體被指向了LED_PIO_BASE,查相關手冊, n2cpu_Embedded Peripherals.pdf。

這兩個表格就是PIOCORE寄存器映射,我們這個結構體啊就是根據它寫出來的,名字不重要,重要的是順序,也就是偏移量。第一項是數據DATA,第二項是IO口方向,第三項是中斷控制位,第四項是邊沿控制位。他們每一項都有N位,這個N就是我們在軟件構建中的寬度,這個時候我們這里的N等于幾?

  • #define LED ((PIO_STR *)LED_PIO_BASE)

  • 它就是怎么把我們定義的結構體給勾上LED設備的。記得LED_PIO_BASE,它就是我們在SYSTEM.H中特別強調的。定義了一個宏,命名為LED,它是指向LED_PIO_BASE的結構指針,這個結構就是PIO_STR.

  • #define _LED

  • #ifdef _LED

  • #endif

  • 意思是為了控制定義#define LED ((PIO_STR *)LED_PIO_BASE)的,這樣做是為了增強代碼的嚴謹性和可控制性。

把之前的模板文件hello_world.c名字改為main.c并將它放到main文件夾中,右擊rename后,選中main.c右擊鼠標move后,選中main文件夾就ok了。

#include <stdio.h> #include <unistd.h> #include "../inc/sopc.h" int main (void) __attribute__ ((weak, alias ("alt_main"))); int alt_main() { int i; while (1) { for(i=0;i<4;i++){ LED->DATA =1<<i; usleep(500000); } } return 0; }

LED->DATA =1<<i;LED是在SOPC.H中定義的宏,是結構體指針,它的結構體中DATA的內容(不是地址)。這里的usleep是微秒級延時的。

總結一下:

  • 文檔的歸類管理。

  • Sopc.h定義來源是相關外設的文檔寄存器。

  • 操作定義好的外設結構體變量編程。

并不是,要看什么要的外設,想FLASH這種外設,采用這種方式的話,累死你,我們就直接可以使用API來寫就行了。這種方式對我們了解nios的本質是很有幫助的。

?

6.3 定時器應用

概覽

該時間計數器是一個為諸如NIOS II 等基于Avalon架構的處理器設計的時間計數器。該計數器有如下特點:

(1)32位和64位計數;

(2)具有計數開始、計數停止、和復位計數器功能;

(3)兩種技術模式:單次計數、連續計數;

(4)計數周期寄存器;

(5)當計數器計數到0時,可以選擇使能或者禁止觸發中斷(IRQ);

(6)可選作為看門狗,產生系統復位;

(7)可選產生周期脈沖,當計數器計數到0時;

(8)可用于32位或者16位處理器中。如16位的NIOS和32位的NIOS II。

Interval TimerCore 功能描述

(1)Avalon-MM提供可對6個16位寄存器操作的功能;

(2)可選周期脈沖輸出。

所有的寄存器都是16位寬度的,因此可適應于16位或者32位處理器。若該核被配置為一個固定的周期,那么,周期寄存器就不存在。

計數周期(Timeout Period)

計數周期決定了周期計數器值。當使能可寫周期(Writeableperiod),處理器可以通過寫周期計數器( period registers)改變計數器值?;蛘弋斀箍蓪懼芷?#xff08;Writeableperiod),周期計數器(period registers)不可經過處理器的寫操作而改變;此時周期計數器只能是一個不可改變的固定周期計數值。Interval Timer Core的計數周期是系統時鐘周期的整數倍。實際的時鐘周期讀者可以這樣求。

(1)求出系統的時鐘。指驅動Interval Timer Core的時鐘。一般與NIOS II 時鐘一致。

(2)將周期計數器里面高16位和低16位的值乘與時鐘時期即得計數周期。

計數大小(Counter Size)

該設定決定了計數器的位寬??梢栽O定為32位或者64位。32位位寬的計數器包含有2個16位的寄存器;而64位位寬的計數器包含有4個16位寬的寄存器。該設定同樣應用至snap單元。

硬件選項

(1)Simple periodic interrupt—該設定用于只需要一個帶有中斷(IRQ)的計數器。該方式下,計數周期是固定不可軟件更改的,且計數不能停止但中斷(IRQ)可禁止。

(2)Full-featured—該配置適用于一個可被處理器更改,可變計數周期,且其開始、停止均可被更改的計數器。

(3)Watchdog—適用于系統需要看門狗的情況。當系統停止響應,該配置能使系統復位。

寄存器(registeregister)設定說明

(1)Writeable period——當選中此項,則主外設(NIOS II)可通過寫周期寄存器(period registers)達到修改計數周期的目的。若未選中此項,則計數周期被確定為(Timeout Period),不可更改;同時周期寄存器(period registers)不再存在。

(2)Readable snapshot——當選中此項,則主外設(NIOS II )可以讀取當前計數值。若未選中此項,則主外設只能依靠查詢狀態寄存器(status register)或者中斷(IRQ)標志來得知計數狀態;此時(snap registers)并不存在,讀取該寄存器會有不確定的數值。

(3)Start/Stop control bits——當選中此項,則主外設( NIOS II )可以通過寫控制寄存器(control register)來啟動、停止計數器。若未選中此項,則計數器默認為連續計數模式。值得注意的是,當系統看門狗復位(System reset on timeout (watchdog))是使能狀態,則控制寄存器(control register)中的(start)位被置位,而不管Start/Stop 控制位的狀態。

信號輸出選項

( 1 ) Timeout pulse (1 clock wide) — — 當選中該項, 則計數器產生一個信號端口(timeout_pulse),該信號端口在計數器減計數至0時產生一個系統時鐘周期的高電平。若未選中該項,則計數器不產生該信號端口。

(2)System reset on timeout (watchdog)——當選中該項,則計數器產生一個復位信號端口(resetrequest port)該信號在計數器減計數至0時產生一個系統時鐘周期的高電平。若未選中該項,則該信號端口不存在。

配置計數器為看門狗

若要使用看門狗,則應作如下選擇。

(1)presets:選擇Watchdog;

(2)Timeout Period修改成所需要的時間

(3)Writeable period禁止;

(4)Readable snapshot禁止;

(5)Start/Stop control bits禁止;

(6)Timeout pulse禁止;

(7)System reset on timeout (watchdog)使能。

復位之后看門狗是禁止的。隨后,處理器往控制寄存器(control register)的START位寫1。開啟看門狗計數器??撮T狗一旦開啟,就不能結束。為了不使系統復位,處理器應該定時地復位計數值。

Interval Timer Core 軟件編寫

狀態寄存器(status Register Bits)

TO——當計數器減計數到0時,置1。一旦置1,則必須由主外設(NIOS II)清0;

RUN——當計數器在計數運行時,RUN=1;否則RUN=0。寫RUN對值無影響。

控制寄存器(control register)

ITO——當ITO=1時,計數器會產生中斷。反之則反。

CONT——若COUNT=1則計數器計數到0連續計數,知道STOP=1;若COUNT=0則計數器計數到0時,停止計數。

START——寫1到START則使計數器開始計數。當計數器正在計數運行,則寫START無效。

STOP——寫1到STOP則使計數器停止計數。若計數器已經停止計數,則寫STOP無效。當SOPC配置為Start/Stop control bits為關閉,則寫STOP無效。

中斷(IRQ)

當計數器減計數到0時并且控制寄存器(congtrol register)ITO位被置1,則可產生定時器中斷。

處理中斷應用以下兩種方式之一:

(1)清除狀態寄存器(status register)的TO位;

(2)清除控制寄存器(congtrol register)ITO位,禁止中斷。否則會產生不確定結果。

實例程序

/**//************************ 定時器中斷注冊初始化函數*****************************/ void InitInterrupt() { //----------------------------定時器中斷,系統時鐘66.7MHz-------------------- ------// alt_irq_register(TIMER_IRQ,NULL,Timer_interrupts); //注冊中斷函數 IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_BASE, 0x000A); IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_BASE, 0x2C2A);//修改定時時間10ms IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE, 7); //啟動定時器允許中斷,連續計數 } /**//*************************定時器中斷服務函數*****************************/ void Timer_interrupts(void* context, alt_u32 id) { /**//***************************服務代碼**************/ /**//**********************退出時清狀態寄存器***********/ IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0); //清狀態寄存器 } typedef struct{ union{ struct{ volatile unsigned long int TO :1; volatile unsigned long int RUN :1; volatile unsigned long int NC :30; }BITS; volatile unsigned long int WORD; }STATUS; union{ struct{ volatile unsigned long int ITO :1; volatile unsigned long int CONT :1; volatile unsigned long int START :1; volatile unsigned long int STOP : 1; volatile unsigned long int NC :28; }BITS; volatile unsigned long int WORD; }CONTROL; volatile unsigned long int PERIODL; volatile unsigned long int PERIODH; volatile unsigned long int SNAPL; volatile unsigned long int SNAPH; }TIMER;

FPGA 之 SOPC 系列第六篇就到這里結束,下一篇將帶來第七篇,NIOS II 高級技術等相關內容。

?

【QQ交流群】

群號:173560979,進群暗語:FPGA技術江湖粉絲。

多年的FPGA企業開發經驗,各種通俗易懂的學習資料以及學習方法,濃厚的交流學習氛圍,QQ群目前已有1000多名志同道合的小伙伴,無廣告純凈模式,給技術交流一片凈土,從初學小白到行業精英業界大佬等,從軍工領域到民用企業等,從通信、圖像處理到人工智能等各個方向應有盡有。

?

【微信交流群】

現微信交流群已建立08群,人數已達數千人,歡迎關注“FPGA技術江湖”微信公眾號,可獲取進群方式。

后續會持續更新,帶來Vivado、 ISE、Quartus II 、candence等安裝相關設計教程,學習資源、項目資源、好文推薦等,希望大俠持續關注。

江湖偌大,繼續闖蕩,愿大俠一切安好,有緣再見!

總結

以上是生活随笔為你收集整理的FPGA 之 SOPC 系列(六)Nios II 程序开发 II的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。