国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

ARM:LED控制編程、電路原理、CPU數(shù)據(jù)手冊(cè)、位運(yùn)算、交叉編譯

2019-11-14 08:46:12
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
一、LED控制編程1、電路原理圖    【底板】env/DataSheet/x6818bv2.pdf      如果讓LED1亮(D25),找到'對(duì)應(yīng)標(biāo)號(hào)'為GPIOC12為低電平      反之--------------------------------------高電平    【核心板】env/DataSheet/x4418cv3_release20150713.pdf      在核心板里面'搜索標(biāo)號(hào)'GPIOC12      找到GPIOC12'導(dǎo)線接到對(duì)應(yīng)CPU的管腳'W15上,或者說(shuō)接到 CPU GPIOC12管腳上。問(wèn)題:    運(yùn)行在ARM CORE (CPU)中的程序如何才能控制GPIOC12管教上電平的變化?答案:    在CPU的說(shuō)明書(shū)里面 DataSheet 文件夾中    :SEC_S5P6818X_Users_Manual_PReliminary_Ver_0.00.pdf <第16章>2、CPU數(shù)據(jù)手冊(cè)--->P 56.   ' I/O Function Description    CPU上一共有 537 個(gè)管腳,<第16章>可用于通用GPIO的有 160 個(gè)管腳。--->P 68.        W15 - Alternate Function1[功能1] - GPIOC12 - I/O>>硬件工程師使用CPU芯片時(shí),關(guān)注CPU上的管腳>>軟件工程師使用CPU芯片時(shí),關(guān)注'CPU內(nèi)部的特殊功能寄存器'(register)>>每隔特殊功能寄存器都是32bit' GPIO[X]00  ---> CPU手冊(cè)GPIOx 00pin--->P 757. - 16.5.1.8 GPIOxALTFN0    GPIOCALTFN0 - bit[25:24] - 01=Function1 [01=功能1,即對(duì)應(yīng)I/O功能]    Address: 0xc001c020--->P 745. - 16.5.1.2 GPIOxOUTENB    GPIOCOUTENB - bit[12] - 1=Output Mode [0/1=輸入/輸出功能]    Address: 0xc001c004--->P 745. - 16.5.1.1 GPIOxOUT    GPIOCOUT - bit[12] - 1=High Level [0/1=輸出低/高電平]    Address: 0xc001c0003、C語(yǔ)言回顧 - register    register 關(guān)鍵字    register int i;  // int i; 默認(rèn)在內(nèi)存數(shù)據(jù)段中,加register關(guān)鍵字就把變量i的這所占4個(gè)字節(jié)的存儲(chǔ)空間放在CPU的寄存器中,可以加快變量i的訪問(wèn)速度3.1 C語(yǔ)言指針
    int a = 100;    * (&a) = 100;    0xc001c000   // 常量    (int*)0xc001c000   // 地址    * ((int*)0xc001c000) = 0x100;   // 寫(xiě)入數(shù)據(jù),按int-4字節(jié)寫(xiě)入0x100volatile 的作用,以及哪種場(chǎng)合需要使用該關(guān)鍵字?(課后查資料)>>表示'一個(gè)變量也許會(huì)被后臺(tái)程序意想不到的修改'。變量如果加了volatile修飾,則會(huì)從內(nèi)存重新裝載內(nèi)容,而不是直接從寄存器拷貝內(nèi)容。volatile可以保證對(duì)特殊地址的穩(wěn)定訪問(wèn)。>>寄存器地址要加volatile修飾,主要是因?yàn)榧拇嫫骼锩娴?#20540;是隨時(shí)變化的。    我們讀取數(shù)據(jù)的時(shí)候,CPU直接到內(nèi)存里面取值,而不是到cache里面。    1) 并行設(shè)備的硬件寄存器;    2) 中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量;    3) 多線程應(yīng)用中被及格任務(wù)共享的變量;

例如:

    volatile int i = 10;    int a = i;    // 其他代碼,并未告訴編譯器,對(duì)i進(jìn)行過(guò)操作    int b = i;"volatile 指出i是隨時(shí)可能發(fā)生變化的,每次使用它的時(shí)候必須從i的地址中讀取,因而編譯器生成的匯編代碼會(huì)重新從i的地址讀取數(shù)據(jù)放在b中。而優(yōu)化做法是,由于編譯器發(fā)現(xiàn)兩次從i讀數(shù)據(jù)的代碼之間的代碼沒(méi)有對(duì)i進(jìn)行過(guò)操作,它會(huì)自動(dòng)把上次讀的數(shù)據(jù)放在b中。而不是重新從i里面讀,這樣以來(lái),如果i是一個(gè)寄存器變量或者表示一個(gè)端口數(shù)據(jù)就容易出錯(cuò),所以說(shuō) volatile 可以保證特殊地質(zhì)的穩(wěn)定訪問(wèn)。"

    // 訪問(wèn)特殊功能寄存器的時(shí)候需要加 volatile 關(guān)鍵字,正確的寫(xiě)法:    a = * ((volatile unsigned int*)0xc001c000);    // 下面此條做法,不但將bit12清0,也導(dǎo)致其他的bit被清0了,錯(cuò)誤!!    * ((volatile unsigned int*)0xc001c000) = 0x00;3.2 位運(yùn)算    假設(shè)需要將 0xc001c020 寄存器的[25:24]bit位設(shè)置為 01 ,
    * ((volatile unsigned int*)0xc001c020) &= ~(0x03000000);  // 第一步    // 32bit :             xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx     // 0x03000000          0000 0011 0000 0000 0000 0000 0000 0000    // ~(0x03000000)       1111 1100 1111 1111 1111 1111 1111 1111    // &= ~(0x03000000)    xxxx xx00 xxxx xxxx xxxx xxxx xxxx xxxx    * ((volatile unsigned int*)0xc001c020) |= 0x01000000;  // 第二步    //  32bit : xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx     //                 01 ([25:24]bit)    //        0x0______01_0____0____0____0____0____0    "實(shí)際做法:"    * ((volatile unsigned int*)0xc001c020) &= ~(3<<24);  // 第一步    * ((volatile unsigned int*)0xc001c020) |= (1<<24);  // 第二步<tips>$:'file a.out// file 命令可以用來(lái)分析文件的一些屬性。x86-64 是x86的64位平臺(tái)運(yùn)行。4. 編碼    vi led.c
/** 代碼演示 **/#define  GPIOC_OUT     *((volatile unsigned int*)0xc001c000)#define  GPIOC_OUTENB  *((volatile unsigned int*)0xc001c004)#define  GPIOC_ALTFN0  *((volatile unsigned int*)0xc001c020)void delay (unsigned int); void led_test (void) {    // 配置對(duì)應(yīng)管腳為GPIO功能    GPIOC_ALTFN0 &= ~ (3 << 24); // clear bit 24,25    GPIOC_ALTFN0 |= (1 << 24); // set bit 24    // 選擇為輸出功能    GPIOC_OUTENB |= (1 << 12); // OUTPUT    while (1) {        // 亮 - 輸出低電平        GPIOC_OUT &= ~ (1 << 12); // clear bit 12        delay (0x1000000);        // 滅 - 輸出高電平        GPIOC_OUT |= (1 << 12); // set bit 12        delay (0x1000000);    }}// delay函數(shù)的實(shí)現(xiàn)不能放前面,只能先聲明后實(shí)現(xiàn)void delay (unsigned int n) {    unsigned int i = 0;    for (i = n; i != 0; i--); // CPU執(zhí)行空操作來(lái)耗時(shí)}

5. arm編譯器

5.1 安裝arm交叉編譯器>>位置:/home/tarena/workdir/arm-linux-gcc/    'arm-cortex_a9-eabi-4.7-eglibc-2.18.tar.gz    權(quán)限不夠時(shí)解決方法:    1> $:' sudo ...    2> $:' sudo chmod +w /opt/ -R    3> $:' sudo chmod 777 /opt/ -R    // 將交叉編譯器tar包文件拷貝到/opt/下,在此文件夾下解壓縮    $:'cd ~/opt/    $:'sudo cp ~/workdir/arm..<table>/arm... .tar.gz .    $:'sudo tar xvf *.gz>>位置:/opt/arm-cortex_a9-eabi-4.7-eglibc-2.18/bin/    'arm-cortex_a9-linux-gnueabi-gcc    $:'vi ~/.bashrc>>添加:<shift + g> // 添加到文件尾    'PATH=$PATH:/opt/arm-cortex_a9-eabi-4.7-eglibc-2.18/bin    $:'source ~/.bashrc5.2 編譯程序希望編譯出來(lái)的程序不使用共享庫(kù) (因?yàn)槭锹惆澹?nbsp;   1)編譯    $:'arm-cortex_a9-linux-gnueabi-gcc -c -nostdlib led.c -o led.o    2)連接    $:'arm-cortex_a9-linux-gnueabi-ld -nostdlib -nostartfiles -Ttext=0x48000000 -eled_test led.o -o led        // -no stdlib 不連接標(biāo)準(zhǔn)庫(kù)文件        // -no startfiles 不連接系統(tǒng)標(biāo)準(zhǔn)啟動(dòng)文件        // -Ttext 指定代碼段的起始地址        // -e 指定入口點(diǎn)函數(shù),默認(rèn)找_start    3)去掉附加信息,生成二進(jìn)制文件    $:'arm-cortex_a9-linux-gnueabi-objcopy -O binary led led.bin    $:' file led.bin<tips>$:'arm-cortex_a9-linux-gnueabi-readelf -d a.out// 顯示可執(zhí)行文件a.out文件中所需的共享庫(kù).so信息$:'arm-cortex_a9-linux-gnueabi-objdump -S led// 反匯編的命令,查看文件的具體的函數(shù)及信息6. 下載運(yùn)行:  X6818# 命令行    $:' cp led.bin /tftpboot/    X6818#:'tftp 48000000 led.bin   // uboot下數(shù)字都識(shí)別為十六進(jìn)制    X6818#:' go led.bin<tips>執(zhí)行tftp 48000000 led.bin 時(shí) Ubuntu-server報(bào) T..T..T...時(shí)需重啟服務(wù)器:$:'sudo /etc/init.d/tftpd-hpa restart補(bǔ)充:編程錯(cuò)誤>>語(yǔ)法錯(cuò)誤:    '只關(guān)注只解決第一個(gè)錯(cuò)誤。邏輯錯(cuò)誤:    ' printf / gdb    1. 是不是硬件問(wèn)題?        env/led.bin放進(jìn)去,燈亮硬件沒(méi)問(wèn)題(或者換到別人電腦上試一試)    2. 如果是軟件問(wèn)題,怎么查?        修改led.c的邏輯        讓對(duì)應(yīng)管腳一直輸出高電平        拿萬(wàn)用表量一下對(duì)應(yīng)的管腳上是否是高電平。env/BCompare-3.3.4.14431.zip   // 工具,對(duì)比文件夾和文件里面不同之處<tips>vi中的命令模式下:e ../xxx.c    // 在vi中直接打開(kāi)別的文件練習(xí):    1. LED1和LED2交替閃爍。(理清楚今天的整個(gè)流程,看手冊(cè),理流程)    2. beep蜂鳴器的控制管腳相關(guān)數(shù)據(jù)準(zhǔn)備:'led1 - GPIOC12 - W15 - Function1    GPIOCALTFN0 - 0xc001c020 - bit[25:24] - 01=Function1 (I/O功能)    GPIOCOUTENB - 0xc001c004 - bit[12] - 1=Output Mode (輸出功能)    GPIOCOUT - 0xc001c000 - bit[12] - 1=High Level (0/1 低高電平)'led2 - GPIOC7 - AE21 - Function1    GPIOCALTFN0 - 0xc001c020 - bit[15:14] - 01    GPIOCOUTENB - 0xc001c004 - bit[7] - 1    GPIOCOUT - 0xc001c000 - bit[7] - 1'led3 - GPIOC11 - W14 - Function1    GPIOCALTFN0 - 0xc001c020 - bit[23:22] - 01    GPIOCOUTENB - 0xc001c004 - bit[11] - 1    GPIOCOUT - 0xc001c000 - bit[11] - 1'led4 - GPIOB26 - MCU_SPI_WP AC25 - Function1 (暫略)
/** 代碼演示 **/#define GPIOC_ALTFN0  *((volatile unsigned int*)0xc001c020)#define GPIOC_OUTENB  *((volatile unsigned int*)0xc001c004)#define GPIOC_OUT     *((volatile unsigned int*)0xc001c000)void delay (unsigned int);void led_run (void) {    // 配置GPIOC管腳    // led1 25:24    GPIOC_ALTFN0 &= ~ (3 << 24);    GPIOC_ALTFN0 |= (1 << 24);    // led2 15:14    GPIOC_ALTFN0 &= ~ (3 << 14);    GPIOC_ALTFN0 |= (1 << 14);    // led3 23:22    GPIOC_ALTFN0 &= ~ (3 << 22);    GPIOC_ALTFN0 |= (1 << 22);    // 設(shè)置輸出功能    GPIOC_OUTENB |= (1 << 12);    GPIOC_OUTENB |= (1 << 11);    GPIOC_OUTENB |= (1 << 7);     for (;;) {        GPIOC_OUT &= ~ (1 << 12); // led1        delay (0x800000);        GPIOC_OUT &= ~ (1 << 11); // led2         delay (0x800000);        GPIOC_OUT &= ~ (1 << 7); // led3        delay (0x800000);        GPIOC_OUT |= (1 << 12);         delay (0x800000);        GPIOC_OUT |= (1 << 11);         delay (0x800000);        GPIOC_OUT |= (1 << 7);         delay (0x800000);    }   }void delay (unsigned int n) {    unsigned int i;    for (i = n; i; --i);}

    2. beep蜂鳴器的控制' beep蜂鳴器 - PWM2[GPIOC14] - AD12 - Function2    GPIOCALTFN0 - 0xc001c020 - bit[29:28] - 10=Function2 (I/O功能)    GPIOCOUTENB - 0xc001c004 - bit[14] - 1=Output Mode (輸出功能)    GPIOCOUT - 0xc001c000 - bit[14] - 1=High Level (0/1 低高電平)

/** 代碼演示 **/#define GPIOC_ALTFN0  *((volatile unsigned int*)0xc001c020)#define GPIOC_OUTENB  *((volatile unsigned int*)0xc001c004)#define GPIOC_OUT     *((volatile unsigned int*)0xc001c000)void delay (unsigned int);void beep_run (void) {    // 配置GPIO管腳    GPIOC_ALTFN0 &= ~(3 << 28);    GPIOC_ALTFN0 |= (2 << 28);    // 設(shè)置輸出功能    GPIOC_OUTENB |= (1 << 14);    for (;;) {        GPIOC_OUT &= ~(1 << 14); // 低電平 - 鳴叫        delay (0x2000000);        GPIOC_OUT |= (1 << 14); // 高電平 - 不叫 (無(wú)延時(shí)和停止蜂鳴效果)        delay (0x2000000);    }   }void delay (unsigned int n) {    unsigned int i;    for (i = n; i; --i);}


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 调兵山市| 江城| 涡阳县| 苏尼特右旗| 宽甸| 交口县| 罗源县| 沈阳市| 宝坻区| 浠水县| 西青区| 澎湖县| 平潭县| 泊头市| 交口县| 普兰县| 铜鼓县| 定结县| 灵石县| 康平县| 云浮市| 百色市| 英德市| 容城县| 邵阳县| 怀远县| 赤峰市| 彝良县| 建湖县| 上林县| 阿拉善右旗| 定安县| 临桂县| 潢川县| 枣庄市| 河北区| 塔河县| 旬邑县| 农安县| 武川县| 读书|