




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
編寫PWM驅(qū)動以及測試程序開發(fā)板的BEEP燈電路在Exynos4412中,一共有5個32位定時器,這些定時器課發(fā)送中斷信號給ARM處理器,另外,定時器0、1、2、3包含了脈沖寬度調(diào)制(PWM),并可驅(qū)動其對應(yīng)的I/O引腳。每個定時器都有一個獨(dú)立的32位遞減計數(shù)器,定時器啟動后,計數(shù)緩沖寄存器(TCNTBn)將初始值加載到遞減計數(shù)器,定時器時鐘驅(qū)動遞減計數(shù)器,當(dāng)遞減計數(shù)器達(dá)到零,自動產(chǎn)生計時器中斷請求,同時相應(yīng)TCNTBn的值自動重新加載,開始下一個循環(huán)。但是,如果定時器停止,如清除TCONn的定時器使能位,TCNTBn的值將不會重新加載到計數(shù)器中。每個定時器都有一個獨(dú)立的32位比較緩沖寄存器(TCMPBn)。當(dāng)遞減計數(shù)器與定時器控制邏輯中比較寄存器的值相匹配時,PWM輸出會產(chǎn)生由低到高的電平跳變,因此,比較寄存器決定PWM輸出的開啟時間或關(guān)閉時間。1、初始化定時器n對應(yīng)的計數(shù)緩沖寄存器TCNTBn為159,定時器n對應(yīng)的計數(shù)比較緩沖寄存器TCMPBn為109。2、啟動定時器n:設(shè)置定時器n的啟動位為1,并手動更新為為零。此時寄存器TCNTBn的值159自動加載到內(nèi)部的遞減寄存器中,并開始遞減計數(shù),同時輸出引腳TOUTn輸出低電平。3、當(dāng)遞減寄存器的值遞減到109(TCMPBn的數(shù)值)時,定時器n對應(yīng)的電平輸出引腳TOUTn從低電平翻轉(zhuǎn)到高電平。4、當(dāng)遞減寄存器的值遞減到0時,計數(shù)緩沖寄存器TCNTBn的值159重新被加載到定時器的遞減器,定時器n對應(yīng)的電平輸出引腳TOUTn重新輸出低電平,這樣流程重復(fù)進(jìn)行,引腳TOUTn就輸出占空比可控的PWM波。值得注意的是,修改計數(shù)緩沖寄存器TCNTBn或比較緩沖寄存器TCMPBn的值,只能在下一個PWM周期起作用,不影響當(dāng)前周期PWM的占空比。PWM驅(qū)動源程序文件(pwm_dev.c)設(shè)計,關(guān)鍵步驟為:pwm_dev_open:主要實(shí)現(xiàn)對PWM的寄存器進(jìn)行初始化工作,pwm_dev_release:主要實(shí)現(xiàn)停止PWM波形的輸出,pwm_dev_ioctl:分別設(shè)置了四個命令實(shí)現(xiàn)PWM的啟動,停止,設(shè)置分頻系數(shù)以及設(shè)置頻率。在驅(qū)動加載時,即pwm_dev_init函數(shù)中,將實(shí)例化的文件操作結(jié)構(gòu)體pwm_ops與設(shè)備號關(guān)聯(lián)并注冊到內(nèi)核中,同時生成對應(yīng)的設(shè)備文件。#include<linux/module.h>#include<linux/kernel.h>#include<linux/init.h>#include<linux/platform_device.h>#include<linux/fb.h>#include<linux/err.h>#include<linux/slab.h>#include<linux/delay.h>#include<linux/gpio.h>#include<mach/gpio.h>#include<plat/gpio-cfg.h>
MODULE_LICENSE("GPLv2");
#defineDEVICE_NAME "pwm"http://定義設(shè)備的名字為
pwm#defineDEVICE_NUM 1staticintmajor=0;//主設(shè)備號,次設(shè)備號staticintminor=0;
structcdevpwm_dev_cdev;staticstructclass*pwm_class;
pwm_dev.c
#defineNS_IN_1HZ 0x6400//100MHz/256/16
#defineBUZZER_PMW_GPIO EXYNOS4_GPD0(0)//蜂鳴器GPIO配置
#defineTIMER_BASE 0X139D0000void__iomem *timer_base;#defineTCFG0 (void__iomem *)(timer_base+0X00)#defineTCFG1 (void__iomem *)(timer_base+0X04)#defineTCON (void__iomem *)(timer_base+0X08)#defineTCNTB1 (void__iomem *)(timer_base+0X0C)#defineTCMPB1 (void__iomem *)(timer_base+0X10)
#definePWM_ON _IO('K',0)#definePWM_OFF _IO('K',1)#definePWM_SET_PRE _IOW('K',2,int)#definePWM_SET_FREQ _IOW('K',3,int)//open方法函數(shù),主要打開pwm的操作staticintpwm_dev_open(structinode*inode,structfile*file){ printk(KERN_INFO"pwm_openstart"); s3c_gpio_cfgpin(BUZZER_PMW_GPIO,S3C_GPIO_SFN(2));
writel(readl(TCFG0)|0xff,TCFG0); writel((readl(TCFG1)&(~0x0f))|0x04,TCFG1); writel(300,TCNTB1); writel(150,TCMPB1); writel((readl(TCON)&(~0x1f))|0X02,TCON); return0;}//close方法函數(shù),主要是關(guān)閉pwm操作staticintpwm_dev_release(structinode*inode,structfile*file){ printk(KERN_INFO"pwm_close"); writel(readl(TCON)&(~0x1f),TCON); s3c_gpio_cfgpin(BUZZER_PMW_GPIO,S3C_GPIO_OUTPUT); return0;}//控制io口方法函數(shù)staticlongpwm_dev_ioctl(structfile*filep,unsignedintcmd,unsignedlongarg){ intdata=arg;
if(_IOC_TYPE(cmd)!='K') return-ENOTTY; if(_IOC_NR(cmd)>3) return-ENOTTY;
printk(KERN_INFO"pwm_ioctlstart");
switch(cmd){ casePWM_ON: writel((readl(TCON)&(~0x1f))|0X0D,TCON); break; casePWM_SET_PRE: if(data==0) return-EINVAL; writel(readl(TCON)&(~0x1f),TCON); writel((readl(TCFG0)&(~0xff))|(data&0xff),TCFG0); writel((readl(TCON)&(~0x1f))|0X0D,TCON); break; casePWM_SET_FREQ: if(data==0) return-EINVAL;data=(NS_IN_1HZ)/data; writel(data,TCNTB1); writel(data>>1,TCMPB1); break; casePWM_OFF: writel(readl(TCON)&(~0x1f),TCON); break; } return0;}//operations結(jié)構(gòu)體staticstructfile_operationspwm_ops={ .owner=THIS_MODULE, .unlocked_ioctl=pwm_dev_ioctl, .open=pwm_dev_open, .release=pwm_dev_release};
//pwm設(shè)備初始化,設(shè)備在被insmod插入模塊到內(nèi)核的過程中會調(diào)用這個函數(shù)staticint__initpwm_dev_init(void){ intret=0; dev_tdevno; printk(KERN_INFO"pwm_dev_initstart");
gpio_free(BUZZER_PMW_GPIO); ret=gpio_request(BUZZER_PMW_GPIO,DEVICE_NAME);
if(ret){ printk(KERN_INFO"requestGPIO%dforpwmfailed\n",BUZZER_PMW_GPIO); gotoERR1; } s3c_gpio_cfgpin(BUZZER_PMW_GPIO,S3C_GPIO_OUTPUT); gpio_set_value(BUZZER_PMW_GPIO,0);/*動態(tài)注冊設(shè)備號*/ ret=alloc_chrdev_region(&devno,minor,DEVICE_NUM,"pwmdriver"); /*獲得主設(shè)備號*/ major=MAJOR(devno); printk(KERN_INFO"dynamicadev_regionmajoris%d!\n",major); if(ret<0){ printk(KERN_INFO"register_chrdev_regionreq%disfailed!\n",major); gotoERR2;}else{ cdev_init(&pwm_dev_cdev,&pwm_ops); pwm_dev_cdev.owner=THIS_MODULE; ret=cdev_add(&pwm_dev_cdev,devno,DEVICE_NUM); if(ret<0){ printk(KERN_INFO"cdev_add%disfailed!\n",ret); gotoERR3; } else{ pwm_class=class_create(THIS_MODULE,DEVICE_NAME); device_create(pwm_class,NULL,devno,NULL,DEVICE_NAME); }}//地址映射timer_base=ioremap(TIMER_BASE,0x20);if(timer_base==NULL){ printk(KERN_INFO"ioremapfailed!\n"); ret=-ENOMEM; gotoERR4;} printk(KERN_INFODEVICE_NAME"\tinitialized\n");return0;
ERR4: device_destroy(pwm_class,devno); class_unregister(pwm_class); class_destroy(pwm_class); cdev_del(&pwm_dev_cdev);ERR3: unregister_chrdev_region(devno,DEVICE_NUM);ERR2: gpio_free(BUZZER_PMW_GPIO);ERR1: returnret;}
//設(shè)備在被卸載rmmod的過程中會調(diào)用這個函數(shù)staticvoid__exitpwm_dev_exit(void){ dev_tdevno=MKDEV(major,minor);
printk("pwm_exitstart");
gpio_free(BUZZER_PMW_GPIO); device_destroy(pwm_class,devno); class_unregister(pwm_class); class_destroy(pwm_class); cdev_del(&pwm_dev_cdev); unregister_chrdev_region(devno,DEVICE_NUM); iounmap(timer_base); printk(KERN_INFO"pwm_dev_exit!\n"); return;}
//模塊初始化module_init(pwm_dev_init);//銷毀模塊module_exit(pwm_dev_exit);Makefileobj-m=pwm_dev.oKERNELDIR:=/root/yizhi/boot-kernel-source/iTop4412_Kernel_3.0PWD:=$(shellpwd)modules: $(MAKE)-C$(KERNELDIR)M=$(PWD)modulesclean: rm-rf*.o~core.depend*.ko*.mod.c*.*.cmd rm–rf.tmp_versions要編譯的結(jié)果,名字和驅(qū)動源程序相同在PWM測試應(yīng)用程序中,根據(jù)PWM驅(qū)動設(shè)計的3個文件操作open、close、ioctl,操作對應(yīng)的PWM設(shè)備驅(qū)動文件/dev/pwm,來實(shí)現(xiàn)對PWM的控制。本例中,通過PWM驅(qū)動設(shè)置不同音調(diào)的頻率,以及設(shè)置不同頻率的播放時間,實(shí)現(xiàn)控制蜂鳴器輸出音樂旋律。/*pwm_music.c*/#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#include<string.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/ioctl.h>#include"pwm_music.h“intmain(){inti=0;intdev_fd;intpre=255;arm-none-linux-gnueabi-gcc–opwm_musicpwm_music.cdev_fd=open("/dev/pwm",O_RDWR|O_NONBLOCK);if(dev_fd<0){printf("error!\n");return-1;}ioctl(dev_fd,PWM_ON);ioctl(dev_fd,PWM_SET_PRE,pre);for(i=0;i<sizeof(Twotigers)/sizeof(Note);i++){ ioctl(dev_fd,PWM_SET_FREQ,Twotigers[i].pitch); usleep(Twotigers[i].dimation*50);}ioctl(dev_fd,PWM_OFF);close(dev_fd);return0;}打開pwm設(shè)置基本頻率播放音調(diào)音調(diào)的持續(xù)時間停止pwm/*pwm_music.h*/#ifnd
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 出國打工合同范例
- 五年級心理降上冊3交往從尊重開始教案北師大版
- 入股店鋪協(xié)議合同范例
- 涂料涂抹施工方案
- ktv托管經(jīng)營合同范例
- 業(yè)主工人裝修合同范例
- 企業(yè)回收電池合同范例
- l拉運(yùn)合同范例
- 樂高合同范例
- 公司雇傭員工合同范例
- 2025年鐵嶺衛(wèi)生職業(yè)學(xué)院單招職業(yè)傾向性測試題庫學(xué)生專用
- (一模)2025屆安徽省“江南十?!备呷?lián)考地理試卷(含官方答案)
- 數(shù)學(xué)-2025屆安徽省江南十校聯(lián)考試題和解析
- 2025年遼寧現(xiàn)代服務(wù)職業(yè)技術(shù)學(xué)院單招職業(yè)技能測試題庫(含答案)
- 高考模擬作文“中國游”“city不city”導(dǎo)寫及范文
- 福建省福州市2024-2025學(xué)年九年級上學(xué)期期末語文試題(解析版)
- 普通高中學(xué)生綜合素質(zhì)評價自我陳述報告
- 2025年江西電力職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測試近5年??及鎱⒖碱}庫含答案解析
- 2025年吉安職業(yè)技術(shù)學(xué)院高職單招職業(yè)技能測試近5年常考版參考題庫含答案解析
- 《展示設(shè)計》課件-第一章 展示設(shè)計概述
- 建筑施工安全管理存在的問題及對策【15000字(論文)】
評論
0/150
提交評論