c语言延时函数delay延时一秒_IMX6UL裸机实现C语言LED实验
C 語言部分有兩個文件 main.c 和 main.h,main.h 里面主要是定義的寄存器地址,在 main.h里面輸入代碼:
#ifndef MAIN_H #define MAIN_H1 /*2 * CCM 相關寄存器地址3 */4 #define CCM_CCGR0 *((volatile unsigned int *)0X020C4068)5 #define CCM_CCGR1 *((volatile unsigned int *)0X020C406C)6 #define CCM_CCGR2 *((volatile unsigned int *)0X020C4070)7 #define CCM_CCGR3 *((volatile unsigned int *)0X020C4074)8 #define CCM_CCGR4 *((volatile unsigned int *)0X020C4078)9 #define CCM_CCGR5 *((volatile unsigned int *)0X020C407C)10 #define CCM_CCGR6 *((volatile unsigned int *)0X020C4080)1112 /*13 * IOMUX 相關寄存器地址14 */15 #define SW_MUX_GPIO1_IO03 *((volatile unsigned int *)0X020E0068)16 #define SW_PAD_GPIO1_IO03 *((volatile unsigned int *)0X020E02F4)1718 /*19 * GPIO1 相關寄存器地址20 */21 #define GPIO1_DR *((volatile unsigned int *)0X0209C000)22 #define GPIO1_GDIR *((volatile unsigned int *)0X0209C004)23 #define GPIO1_PSR *((volatile unsigned int *)0X0209C008)24 #define GPIO1_ICR1 *((volatile unsigned int *)0X0209C00C)25 #define GPIO1_ICR2 *((volatile unsigned int *)0X0209C010)26 #define GPIO1_IMR *((volatile unsigned int *)0X0209C014)27 #define GPIO1_ISR *((volatile unsigned int *)0X0209C018)28 #define GPIO1_EDGE_SEL *((volatile unsigned int *)0X0209C01C)2930 #endif在 main.h 中我們以宏定義的形式定義了要使用到的所有寄存器,后面的數字就是其地址,比如CCM_CCGR0 寄存器的地址就是 0X020C4068,這個很簡單,很好理解。接下看一下 main.c 文件,在 main.c 里面輸入如下所示代碼:
1 #include "main.h" 23 /*4 * @description : 使能 I.MX6U 所有外設時鐘5 * @param : 無6 * @return : 無7 */8 void clk_enable(void) 9 {10 CCM_CCGR0 = 0xffffffff;11 CCM_CCGR1 = 0xffffffff;12 CCM_CCGR2 = 0xffffffff;13 CCM_CCGR3 = 0xffffffff;14 CCM_CCGR4 = 0xffffffff;15 CCM_CCGR5 = 0xffffffff;16 CCM_CCGR6 = 0xffffffff; 17 }1819 /*20 * @description : 初始化 LED 對應的 GPIO21 * @param : 無22 * @return : 無23 */24 void led_init(void) 25 {26 /* 1、初始化 IO 復用, 復用為 GPIO1_IO03 */27 SW_MUX_GPIO1_IO03 = 0x5; 2829 /* 2、配置 GPIO1_IO03 的 IO 屬性30 *bit 16:0 HYS 關閉31 *bit [15:14]: 00 默認下拉32 *bit [13]: 0 kepper 功能33 *bit [12]: 1 pull/keeper 使能34 *bit [11]: 0 關閉開路輸出35 *bit [7:6]: 10 速度 100Mhz36 *bit [5:3]: 110 R0/6 驅動能力37 *bit [0]: 0 低轉換率38 */39 SW_PAD_GPIO1_IO03 = 0X10B0;4041 /* 3、初始化 GPIO, GPIO1_IO03 設置為輸出 */ 42 GPIO1_GDIR = 0X0000008;4344 /* 4、設置 GPIO1_IO03 輸出低電平,打開 LED0 */45 GPIO1_DR = 0X0; 46 }4748 /*49 * @description : 打開 LED 燈50 * @param : 無51 * @return : 無52 */53 void led_on(void) 54 {55 /*56 * 將 GPIO1_DR 的 bit3 清零57 */58 GPIO1_DR &= ~(1<<3);59 }6061 /*62 * @description : 關閉 LED 燈63 * @param : 無64 * @return : 無65 */66 void led_off(void) 67 {68 /*69 * 將 GPIO1_DR 的 bit3 置 1 70 */71 GPIO1_DR |= (1<<3);72 }7374 /*75 * @description : 短時間延時函數76 * @param - n : 要延時循環次數(空操作循環次數,模式延時)77 * @return : 無78 */79 void delay_short(volatile unsigned int n) 80 {81 while(n--){}82 }8384 /*85 * @description : 延時函數,在 396Mhz 的主頻下延時時間大約為 1ms86 * @param - n : 要延時的 ms 數87 * @return : 無88 */89 void delay(volatile unsigned int n) 90 {91 while(n--)92 {93 delay_short(0x7ff); 94 }95 }9697 /*98 * @description : mian 函數99 * @param : 無100 * @return : 無101 */102 int main(void)103 {104 clk_enable(); /* 使能所有的時鐘 */105 led_init(); /* 初始化 led */ 106107 while(1) /* 死循環 */108 {109 led_off(); /* 關閉 LED */ 110 delay(500); /* 延時大約 500ms */ 111112 led_on(); /* 打開 LED */ 113 delay(500); /* 延時大約 500ms */114 }115116 return 0;117 }main.c 文件里面一共有 7 個函數, 這 7 個函數都很簡單。clk_enable 函數是使能CCGR0~CCGR6 所控制的所有外設時鐘。led_init 函數是初始化 LED 燈所使用的 IO,包括設置IO 的復用功能、IO 的屬性配置和 GPIO 功能,最終控制 GPIO 輸出低電平來打開 LED 燈。
led_on 和 led_off 這兩個函數看名字就知道,用來控制 LED 燈的亮滅的。delay_short()和 delay()這兩個函數是延時函數,delay_short()函數是靠空循環來實現延時的,delay()是對 delay_short()的簡單封裝, 在 I.MX6U 工作在 396MHz(Boot ROM 設置的 396MHz) 的主頻的時候delay_short(0x7ff)基本能夠實現大約 1ms 的延時,所以 delay()函數我們可以用來完成 ms 延時。main 函數就是我們的主函數了,在 main 函數中先調用函數 clk_enable()和 led_init()來完成時鐘使能和 LED 初始化,最終在 while(1)循環中實現 LED 循環亮滅,亮滅時間大約是 500ms。本實驗的程序部分就是這些了,接下來即使編譯和測試了。
新建 Makefile 文件,在 Makefile 文件里面輸入如下內容:
1 objs := start.o main.o23 ledc.bin:$(objs)4 arm-linux-gnueabihf-ld -T0X87800000 -o ledc.elf $^5 arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@6 arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis 78 %.o:%.s9 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $< 1011 %.o:%.S12 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<1314 %.o:%.c15 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<1617 clean:18 rm -rf *.o ledc.bin ledc.elf ledc.dis上述的 Makefile里面用到了 Makefile 變量和自動變量,關于 Makefile 的變量和自動變量的請參考《Linux下Makefile文件的模式規則和自動化變量》。
第 1 行定義了一個變量 objs,objs 包含著要生成 ledc.bin 所需的材料:start.o 和main.o,也就是當前工程下的 start.s 和 main.c 這兩個文件編譯后的.o 文件。這里要注意 start.o 一定要放到最前面!因為在后面鏈接的時候 start.o 要在最前面,因為 start.o 是最先要執行的文件!
第 3 行就是默認目標,目的是生成最終的可執行文件 ledc.bin,ledc.bin 依賴 start.o 和 main.o如果當前工程沒有 start.o 和 main.o 的時候就會找到相應的規則去生成 start.o 和 main.o。比如start.o 是 start.s 文件編譯生成的,因此會執行第 8 行的規則。
第 4 行是使用 arm-linux-gnueabihf-ld 進行鏈接,鏈接起始地址是 0X87800000,但是這一行用刀了自動變量“$^”,“$^”的意思是所有依賴文件的集合,在這里就是 objs 這個變量的值:
start.o 和 main.o。鏈接的時候 start.o 要鏈接到最前面,因為第一行代碼就是 start.o 里面的,因此這一行就相當于:
arm-linux-gnueabihf-ld -T0X87800000 -o ledc.elf start.o main.o第 5 行使用 arm-linux-gnueabihf-objcopy 來將 ledc.elf 文件轉為 ledc.bin,本行也用到了自動變量“$@”,“$@”的意思是目標集合,在這里就是“ledc.bin”,那么本行就相當于:
arm-linux-gnueabihf-objcopy -O binary -S ledc.elf ledc.bin第 6 行使用 arm-linux-gnueabihf-objdump 來反匯編,生成 ledc.dis 文件。
第 8~15 行就是針對不同的文件類型將其編譯成對應的.o 文件,其實就是匯編.s(.S)和.c 文件,比如 start.s 就會使用第 8 行的規則來生成對應的 start.o 文件。第 9 行就是具體的命令,這行也用到了自動變量“$@”和“$
start.o:start.sarm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o start.o start.s第 17 行就是工程清理規則,通過命令“make clean”就可以清理工程。
Makefile 文件就講到這里,我們可以將整個工程拿到 Ubuntu 下去編譯,編譯完成以后可以使用軟件 imxdownload 將其下載到 SD 卡中,命令如下:
chmod 777 imxdownload //給予 imxdownoad 可執行權限,一次即可./imxdownload ledc.bin /dev/sdd //下載到 SD 卡中使用軟件 imxdownload 將編譯出來的ledc.bin 燒寫到 SD 卡中,命令如下:
chmod 777 imxdownload //給予 imxdownload 可執行權限,一次即可./imxdownload ledc.bin /dev/sdd //燒寫到 SD 卡中燒寫成功以后將 SD 卡插到開發板的 SD 卡槽中,然后復位開發板,如果代碼運行正常的話 LED0 就會以 500ms 的時間間隔亮滅。
LED0閃爍
總結
以上是生活随笔為你收集整理的c语言延时函数delay延时一秒_IMX6UL裸机实现C语言LED实验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 的自动启动 使用配置文件 /
- 下一篇: VS.NET 控件命名规范(备忘)