在《英創(chuàng)嵌入式主板支持精確延時操作》這篇文章中已經(jīng)講解了如何在EM335x系列的主板中進行精確延時的操作?,F(xiàn)在英創(chuàng)公司已經(jīng)將這部分工作移植到了EM9x60系列的主板中,這樣用戶在EM9x60上面同樣也可以進行精確延時的操作。
以EM9160工控主板為例,用其內(nèi)部的定時器來實現(xiàn)精確延時的功能,EM9160內(nèi)部定時器的輸入時鐘為50MHz,單位時間為20ns,通過將Linux系統(tǒng)的mem設(shè)備文件和mmap()函數(shù)結(jié)合起來使用,可直接對EM9160內(nèi)部定時器的寄存器進行操作。為了使用示波器查看定時器的工作效果,再通過同樣的方式控制GPIO,通過mmap()的方式操作一路GPIO,在定時器開始計數(shù)和結(jié)束計數(shù)的時候進行拉高拉低的操作,這樣就能清楚直觀的在示波器中看到實際的延時時間。實現(xiàn):(1)設(shè)置GPIO,(2)啟動定時器,當(dāng)檢測到定時器計數(shù)完畢,(3)再設(shè)置GPIO,共三個步驟,就可產(chǎn)生精確時間間隔的脈沖。
將/dev/mem/設(shè)備文件中定時器的地址映射到用戶進程空間的代碼:
void *timer_em9x60_pin_config(unsigned int BASE)
{
int mem_fd;
void *base;
mem_fd = open('/dev/mem', O_RDWR|O_SYNC);
printf('mem_fd is %d\n', mem_fd);
/* mmap Timer */
base = mmap(
NULL, //起始地址
DMTIMER_DEV_SIZE,//映射的文件內(nèi)容的大小
PROT_READ|PROT_WRITE,//映射區(qū)域可讀可寫
MAP_SHARED,//映射區(qū)域的寫入數(shù)據(jù)會寫回到原來的文件
mem_fd,
BASE //被映射的硬件地址
);
close(mem_fd);
return base;
}
成功執(zhí)行時,mmap()函數(shù)返回被映射區(qū)的指針。普通文件被映射到進程地址空間后,進程可以像訪問普通內(nèi)存一樣對文件進行訪問,不必再調(diào)用read(),write()等操作。只需要使用返回的地址指針在對應(yīng)的寄存器的偏移地址賦值,就可以完成操作。在例程中已經(jīng)將函數(shù)接口引出(詳細的代碼請參考例程):
ptr=Timer_Init(); //初始化,將定時器地址映射到用戶進程
ptr1=PMC_Init(); //初始化定時器時鐘
Timer_Start(ptr, ptr1, GPIO1, 0x00ff); //啟動定時器,并設(shè)置時間和哪一位GPIO
定時器是從0計數(shù)到0xffff,需要實現(xiàn)定時功能,我們就要改變定時器的初值,上面的程序中0x00ff為定時器的初值,前面提到過由于EM9160定時器時鐘為50MHz,所以定時器單位時間為1/50000000=20ns,假設(shè)程序訪問寄存器還需要花費時間T0,在計算初值的時候,就需要加上這一部分時間才能保證準(zhǔn)確性,因此定時器取值的計算公式為:
T = 目標(biāo)延時 / 20ns - T0
經(jīng)過測試,執(zhí)行一次程序訪問寄存器所需花費的時間大約為T0=600ns。舉個例子,比如目標(biāo)延時為2μs,那么定時器初值為:(2000/20)-0x1b,也就是0x0049,測試的時候帶入這個值,再進行微調(diào),即可得到想要的結(jié)果。
使用英創(chuàng)工控主板運行例程測試,分別測試延時1μs,1.5μs,2μs,5μs,時的精度,結(jié)果如下:
目標(biāo)延時 | 定時器取值 | 實際延時 | |
Min | Max | ||
1us | 0x0017 | 0.95us | 1.16us |
1μs的測試波形
目標(biāo)延時 | 定時器取值 | 實際延時 | |
Min | Max | ||
1.5us | 0x0030 | 1.40us | 1.62us |
1.5μs的測試波形
目標(biāo)延時 | 定時器取值 | 實際延時 | |
Min | Max | ||
2us | 0x0049 | 1.86us | 2.12us |
2μs的測試波形
目標(biāo)延時 | 定時器取值 | 實際延時 | |
Min | Max | ||
5us | 0x00df | 4.88us | 5.12us |
5μs的測試波形
目標(biāo)延時 | 定時器取值 | 實際延時 | |
Min | Max | ||
10us | 0x01d9 | 9.90us | 10.20us |
10μs的測試波形
可以看到,在1μs時,誤差范圍在±200ns左右,隨著延時的增加,精確度將越來越高,在10μs的時候,誤差已經(jīng)非常小了。
通過以上方案實現(xiàn)了在用戶進程對精確延時的操作,詳細的操作代碼請參考例程。
注意事項:我們推薦客戶直接使用例程中引出的接口進行操作,不推薦客戶對硬件訪問這一部分代碼進行修改,以免在操作的時候出現(xiàn)無法預(yù)估的錯誤。
-
Linux
+關(guān)注
關(guān)注
87文章
11232瀏覽量
208958 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6085瀏覽量
35227
發(fā)布評論請先 登錄
相關(guān)推薦
評論