日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]一、開(kāi)發(fā)環(huán)境主 機(jī):VMWare--Fedora 9開(kāi)發(fā)板:Mini2440--64MB Nand, Kernel:2.6.30.4編譯器:arm-linux-gcc-4.3.2二、硬件原理分析 S3C2440內(nèi)部ADC結(jié)構(gòu)圖我們從上面的結(jié)構(gòu)圖和數(shù)據(jù)手冊(cè)可以知道,該ADC模塊總共有8個(gè)通

一、開(kāi)發(fā)環(huán)境

主 機(jī):VMWare--Fedora 9

開(kāi)發(fā)板:Mini2440--64MB Nand, Kernel:2.6.30.4

編譯器:arm-linux-gcc-4.3.2

二、硬件原理分析
S3C2440內(nèi)部ADC結(jié)構(gòu)圖

我們從上面的結(jié)構(gòu)圖和數(shù)據(jù)手冊(cè)可以知道,該ADC模塊總共有8個(gè)通道可以進(jìn)行模擬信號(hào)的輸入,分別是AIN0、AIN1、AIN2、AIN3、YM、YP、XM、XP。那么ADC是怎么實(shí)現(xiàn)模擬信號(hào)到數(shù)字信號(hào)的轉(zhuǎn)換呢?首先模擬信號(hào)從任一通道輸入,然后設(shè)定寄存器中預(yù)分頻器的值來(lái)確定AD轉(zhuǎn)換器頻率,最后ADC將模擬信號(hào)轉(zhuǎn)換為數(shù)字信號(hào)保存到ADC數(shù)據(jù)寄存器0中(ADCDAT0),然后ADCDAT0中的數(shù)據(jù)可以通過(guò)中斷或查詢的方式來(lái)訪問(wèn)。對(duì)于ADC的各寄存器的操作和注意事項(xiàng)請(qǐng)參閱數(shù)據(jù)手冊(cè)。

上圖是mini2440上的ADC應(yīng)用實(shí)例,開(kāi)發(fā)板通過(guò)一個(gè)10K的電位器(可變電阻)來(lái)產(chǎn)生電壓模擬信號(hào),然后通過(guò)第一個(gè)通道(即:AIN0)將模擬信號(hào)輸入ADC。

三、實(shí)現(xiàn)步驟

ADC設(shè)備在Linux中可以看做是簡(jiǎn)單的字符設(shè)備,也可以當(dāng)做是一混雜設(shè)備(misc設(shè)備),這里我們就看做是misc設(shè)備來(lái)實(shí)現(xiàn)ADC的驅(qū)動(dòng)。注意:這里我們獲取AD轉(zhuǎn)換后的數(shù)據(jù)將采用中斷的方式,即當(dāng)AD轉(zhuǎn)換完成后產(chǎn)生AD中斷,在中斷服務(wù)程序中來(lái)讀取ADCDAT0的第0-9位的值(即AD轉(zhuǎn)換后的值)。

1、建立驅(qū)動(dòng)程序文件my2440_adc.c,實(shí)現(xiàn)驅(qū)動(dòng)的初始化和退出,代碼如下:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

/*定義了一個(gè)用來(lái)保存經(jīng)過(guò)虛擬映射后的內(nèi)存地址*/
staticvoid__iomem*adc_base;

/*保存從平臺(tái)時(shí)鐘隊(duì)列中獲取ADC的時(shí)鐘*/
staticstructclk*adc_clk;

/*申明并初始化一個(gè)信號(hào)量ADC_LOCK,對(duì)ADC資源進(jìn)行互斥訪問(wèn)*/
DECLARE_MUTEX(ADC_LOCK);

staticint__init adc_init(void)
{
intret;

/*從平臺(tái)時(shí)鐘隊(duì)列中獲取ADC的時(shí)鐘,這里為什么要取得這個(gè)時(shí)鐘,因?yàn)锳DC的轉(zhuǎn)換頻率跟時(shí)鐘有關(guān)。
系統(tǒng)的一些時(shí)鐘定義在arch/arm/plat-s3c24xx/s3c2410-clock.c中*/
adc_clk=clk_get(NULL,"adc");
if(!adc_clk)
{
/*錯(cuò)誤處理*/
printk(KERN_ERR"failed to find adc clock sourcen");
return-ENOENT;
}

/*時(shí)鐘獲取后要使能后才可以使用,clk_enable定義在arch/arm/plat-s3c/clock.c中*/
clk_enable(adc_clk);

/*將ADC的IO端口占用的這段IO空間映射到內(nèi)存的虛擬地址,ioremap定義在io.h中。
注意:IO空間要映射后才能使用,以后對(duì)虛擬地址的操作就是對(duì)IO空間的操作,
S3C2410_PA_ADC是ADC控制器的基地址,定義在mach-s3c2410/include/mach/map.h中,0x20是虛擬地址長(zhǎng)度大小*/
adc_base=ioremap(S3C2410_PA_ADC,0x20);
if(adc_base==NULL)
{
/*錯(cuò)誤處理*/
printk(KERN_ERR"Failed to remap register blockn");
ret=-EINVAL;
gotoerr_noclk;
}

/*把看ADC注冊(cè)成為misc設(shè)備,misc_register定義在miscdevice.h中
adc_miscdev結(jié)構(gòu)體定義及內(nèi)部接口函數(shù)在第②步中講,MISC_DYNAMIC_MINOR是次設(shè)備號(hào),定義在miscdevice.h中*/
ret=misc_register(&adc_miscdev);
if(ret)
{
/*錯(cuò)誤處理*/
printk(KERN_ERR"cannot register miscdev on minor=%d (%d)n",MISC_DYNAMIC_MINOR,ret);
gotoerr_nomap;
}

printk(DEVICE_NAME" initialized!n");

return0;

//以下是上面錯(cuò)誤處理的跳轉(zhuǎn)點(diǎn)
err_noclk:
clk_disable(adc_clk);
clk_put(adc_clk);

err_nomap:
iounmap(adc_base);

returnret;
}

staticvoid__exit adc_exit(void)
{
free_irq(IRQ_ADC,1);/*釋放中斷*/
iounmap(adc_base);/*釋放虛擬地址映射空間*/

if(adc_clk)/*屏蔽和銷毀時(shí)鐘*/
{
clk_disable(adc_clk);
clk_put(adc_clk);
adc_clk=NULL;
}

misc_deregister(&adc_miscdev);/*注銷misc設(shè)備*/
}

/*導(dǎo)出信號(hào)量ADC_LOCK在觸摸屏驅(qū)動(dòng)中使用,因?yàn)橛|摸屏驅(qū)動(dòng)和ADC驅(qū)動(dòng)公用
相關(guān)的寄存器,為了不產(chǎn)生資源競(jìng)態(tài),就用信號(hào)量來(lái)保證資源的互斥訪問(wèn)*/
EXPORT_SYMBOL(ADC_LOCK);

module_init(adc_init);
module_exit(adc_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Huang Gang");
MODULE_DESCRIPTION("My2440 ADC Driver");DE>


2、adc_miscdev結(jié)構(gòu)體定義及內(nèi)部各接口函數(shù)的實(shí)現(xiàn),代碼如下:

#include

/*設(shè)備名稱*/
#defineDEVICE_NAME"my2440_adc"

/*定義并初始化一個(gè)等待隊(duì)列adc_waitq,對(duì)ADC資源進(jìn)行阻塞訪問(wèn)*/
staticDECLARE_WAIT_QUEUE_HEAD(adc_waitq);

/*用于標(biāo)識(shí)AD轉(zhuǎn)換后的數(shù)據(jù)是否可以讀取,0表示不可讀取*/
staticvolatileintev_adc=0;

/*用于保存讀取的AD轉(zhuǎn)換后的值,該值在ADC中斷中讀取*/
staticintadc_data;

/*misc設(shè)備結(jié)構(gòu)體實(shí)現(xiàn)*/
staticstructmiscdevice adc_miscdev=
{
.minor=MISC_DYNAMIC_MINOR,/*次設(shè)備號(hào),定義在miscdevice.h中,為255*/
.name=DEVICE_NAME,/*設(shè)備名稱*/
.fops=&adc_fops,/*對(duì)ADC設(shè)備文件操作*/
};

/*字符設(shè)備的相關(guān)操作實(shí)現(xiàn)*/
staticstructfile_operations adc_fops=
{
.owner=THIS_MODULE,
.open=adc_open,
.read=adc_read,
.release=adc_release,
};

/*ADC設(shè)備驅(qū)動(dòng)的打開(kāi)接口函數(shù)*/
staticintadc_open(structinode*inode,structfile*file)
{
intret;

/*申請(qǐng)ADC中斷服務(wù),這里使用的是共享中斷:IRQF_SHARED,為什么要使用共享中斷,因?yàn)樵谟|摸屏驅(qū)動(dòng)中
也使用了這個(gè)中斷號(hào)。中斷服務(wù)程序?yàn)?adc_irq在下面實(shí)現(xiàn),IRQ_ADC是ADC的中斷號(hào),這里注意:
申請(qǐng)中斷函數(shù)的最后一個(gè)參數(shù)一定不能為NULL,否則中斷申請(qǐng)會(huì)失敗,如果中斷服務(wù)程序中用不到這個(gè)
參數(shù),就隨便給個(gè)值就好了,我這里就給個(gè)1*/
ret=request_irq(IRQ_ADC,adc_irq,IRQF_SHARED,DEVICE_NAME,1);
if(ret)
{
/*錯(cuò)誤處理*/
printk(KERN_ERR"IRQ%d error %dn",IRQ_ADC,ret);
return-EINVAL;
}

return0;
}

/*ADC中斷服務(wù)程序,該服務(wù)程序主要是從ADC數(shù)據(jù)寄存器中讀取AD轉(zhuǎn)換后的值*/
staticirqreturn_t adc_irq(intirq,void*dev_id)
{
/*保證了應(yīng)用程序讀取一次這里就讀取AD轉(zhuǎn)換的值一次,
避免應(yīng)用程序讀取一次后發(fā)生多次中斷多次讀取AD轉(zhuǎn)換值*/
if(!ev_adc)
{
/*讀取AD轉(zhuǎn)換后的值保存到全局變量adc_data中,S3C2410_ADCDAT0定義在regs-adc.h中,
這里為什么要與上一個(gè)0x3ff,很簡(jiǎn)單,因?yàn)锳D轉(zhuǎn)換后的數(shù)據(jù)是保存在ADCDAT0的第0-9位,
所以與上0x3ff(即:1111111111)后就得到第0-9位的數(shù)據(jù),多余的位就都為0*/
adc_data=readl(adc_base+S3C2410_ADCDAT0)&0x3ff;

/*將可讀標(biāo)識(shí)為1,并喚醒等待隊(duì)列*/
ev_adc=1;
wake_up_interruptible(&adc_waitq);
}

returnIRQ_HANDLED;
}

/*ADC設(shè)備驅(qū)動(dòng)的讀接口函數(shù)*/
staticssize_t adc_read(structfile*filp,char*buffer,size_tcount,loff_t*ppos)
{
/*試著獲取信號(hào)量(即:加鎖)*/
if(down_trylock(&ADC_LOCK))
{
return-EBUSY;
}

if(!ev_adc)/*表示還沒(méi)有AD轉(zhuǎn)換后的數(shù)據(jù),不可讀取*/
{
if(filp->f_flags&O_NONBLOCK)
{
/*應(yīng)用程序若采用非阻塞方式讀取則返回錯(cuò)誤*/
return-EAGAIN;
}
else/*以阻塞方式進(jìn)行讀取*/
{
/*設(shè)置ADC控制寄存器,開(kāi)啟AD轉(zhuǎn)換*/
start_adc();

/*使等待隊(duì)列進(jìn)入睡眠*/
wait_event_interruptible(adc_waitq,ev_adc);
}
}

/*能到這里就表示已有AD轉(zhuǎn)換后的數(shù)據(jù),則標(biāo)識(shí)清0,給下一次讀做判斷用*/
ev_adc=0;

/*將讀取到的AD轉(zhuǎn)換后的值發(fā)往到上層應(yīng)用程序*/
copy_to_user(buffer,(char*)&adc_data,sizeof(adc_data));

/*釋放獲取的信號(hào)量(即:解鎖)*/
up(&ADC_LOCK);

returnsizeof(adc_data);
}

/*設(shè)置ADC控制寄存器,開(kāi)啟AD轉(zhuǎn)換*/
staticvoidstart_adc(void)
{
unsignedinttmp;

tmp=(1<<14)|(255<<6)|(0<<3);/* 0 1 00000011 000 0 0 0 */
writel(tmp,adc_base+S3C2410_ADCCON);/*AD預(yù)分頻器使能、模擬輸入通道設(shè)為AIN0*/

tmp=readl(adc_base+S3C2410_ADCCON);
tmp=tmp|(1<<0);/* 0 1 00000011 000 0 0 1 */
writel(tmp,adc_base+S3C2410_ADCCON);/*AD轉(zhuǎn)換開(kāi)始*/
}

/*ADC設(shè)備驅(qū)動(dòng)的關(guān)閉接口函數(shù)*/
staticintadc_release(structinode*inode,structfile*filp)
{
return0;
}

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉