一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>電子元器件>二極管>

如何用繼電器的發(fā)光二極管閃爍電路圖

2018年08月27日 11:10 作者:工程師譚軍 用戶評(píng)論(0

本文主要是關(guān)于發(fā)光二極管的相關(guān)介紹,并著重對(duì)使用繼電器的發(fā)光二極管閃爍電路進(jìn)行了詳盡的描述。

如何用繼電器的發(fā)光二極管閃爍電路圖

原理圖如圖一

連接電路前先不要接二極管D1,一會(huì)再解釋二極管的作用。三極管是2n3904 NPN型三極管,基極電阻68歐姆,要把圖中的5v電源vcc1和gnd1分別接到單片機(jī)的電源和地上.,

LED燈的電路由外電源供電,R2取1k歐姆,限制電流

實(shí)物圖如下,圖二和圖三分別是LED燈亮和滅的照片。雖然我拿個(gè)一個(gè)開(kāi)發(fā)板,但是只用了其單片機(jī)的最小系統(tǒng)。

示波器測(cè)三極管集電極的波形,發(fā)現(xiàn)有圖五所示的一個(gè)尖刺,分析過(guò)后,是因?yàn)槔^電器本身就是一個(gè)線圈,在電流突然變化的瞬間會(huì)起到阻礙其變化的作用,左移在繼電器的兩端并聯(lián)一個(gè)二極管,穩(wěn)定輸出的作用。加入二極管后的波形如圖六中最后一組波形。

  控制單片機(jī)P2^0口的代碼如下:

  #include《reg52.h》

  #include《intrins.h》

  sbit P20=P2^0 ;

  void Delay1000ms() //@11.0592MHz

  {

  unsigned char i, j, k;

  _nop_();

  i = 8;

  j = 1;

  k = 243;

  do

  {

  do

  {

  while (--k);

  } while (--j);

  } while (--i);

  }

  void main()

  {

  while(1)

  {

  P20=1;

  Delay1000ms();

  P20=0;

  Delay1000ms();

  }

  }

  LED閃爍電路

  該Linux驅(qū)動(dòng)用來(lái)控制開(kāi)發(fā)板上的4個(gè)LED燈,即通過(guò)向Linux驅(qū)動(dòng)發(fā)送數(shù)據(jù)可以控制LED燈的開(kāi)關(guān)。LED驅(qū)動(dòng)提供兩種交互方式:命令和讀寫(xiě)設(shè)備文件。

  測(cè)試LED驅(qū)動(dòng)之前需用USB線連接開(kāi)發(fā)板,然后打開(kāi)開(kāi)發(fā)板。成功啟動(dòng)后,執(zhí)行build.sh腳本文件編譯和安裝LED驅(qū)動(dòng)。build.sh腳本文件會(huì)自動(dòng)將s3c6410_leds.ko文件上傳到開(kāi)發(fā)板并安裝。LED驅(qū)動(dòng)只能在開(kāi)發(fā)板上安裝,build.sh執(zhí)行了build_s3c6410.sh腳本文件進(jìn)行編譯和安裝。LED驅(qū)動(dòng)會(huì)建立一個(gè)/dev/s3c6410_leds設(shè)備文件,該Linux驅(qū)動(dòng)可控制4個(gè)LED,通過(guò)向設(shè)備文件發(fā)送長(zhǎng)度為1到4的字符串可以控制這4個(gè)LED的開(kāi)關(guān)。1表示開(kāi),0表示關(guān)。字符串長(zhǎng)度不足4個(gè),相當(dāng)于后面補(bǔ)0。執(zhí)行命令

  “# adb shell “echo ‘1’》 /dev/s3c6410_leds” #打開(kāi)第一個(gè)LED,其他的都關(guān)閉

  # adb shell “echo ‘1010’》 /dev/s3c6410_leds” #第一個(gè)和第三個(gè)LED打開(kāi),第二個(gè)和第四個(gè)關(guān)閉

  # adb shell “echo ‘1111’》 /dev/s3c6410_leds” #打開(kāi)所有的LED”可控制開(kāi)發(fā)板上的LED。可使用命令“# sh ~/drivers/s3c6410_leds/test_leds.sh”執(zhí)行test_leds.sh腳本文件測(cè)試LED。執(zhí)行腳本文件后,開(kāi)發(fā)板上的4個(gè)LED會(huì)根據(jù)0到15的二進(jìn)制形式控制LED,第一個(gè)為最低位。腳本文件使用的是標(biāo)準(zhǔn)的Bash Shell,如果在Ubuntu下無(wú)法成功執(zhí)行,是因?yàn)槠鋵ash作為默認(rèn)的腳本解析器??墒褂妹睢? dpkg-reconfigure dash”將默認(rèn)腳本解析器改成Bash,出現(xiàn)設(shè)置界面時(shí),選擇“否”,再回車(chē)即可。

  創(chuàng)建LED驅(qū)動(dòng)的設(shè)備文件,步驟如下;1.描述設(shè)備文件需要使用一個(gè)cdev結(jié)構(gòu)體,該結(jié)構(gòu)體在《Linux內(nèi)核源代碼》/include/linux/cdev.h文件中定義。其中的大多數(shù)成員變量只需調(diào)用cdev_init()就可被初始化,該函數(shù)在《Linux內(nèi)核源代碼》/fs/char_dev.c文件中。若要在一個(gè)Linux驅(qū)動(dòng)中建立多個(gè)設(shè)備文件,cdev.count變量的值就是要建立的設(shè)備文件數(shù)。這些設(shè)備文件對(duì)應(yīng)的cdev結(jié)構(gòu)體就通過(guò)cdev.list.prev和cdev.list.next指針變量連接,從而形成一個(gè)雙向鏈表。cdev.owner變量未在cdev.init函數(shù)中初始化,使用語(yǔ)句“l(fā)eds_cdev.owner=THIS_MODULE;”來(lái)初始化2.Linux設(shè)備文件的設(shè)備號(hào)分為主設(shè)備號(hào)和次設(shè)備號(hào)。用一個(gè)int類型表示,其中前12位表示主設(shè)備號(hào),后20位表示次設(shè)備號(hào)。設(shè)備號(hào)有兩種指定方法:直接在代碼中指定和動(dòng)態(tài)分配。第一種方法雖比較直觀,但如果主設(shè)備號(hào)和次設(shè)備號(hào)已存在,建立設(shè)備文件就會(huì)失敗。以防萬(wàn)一,可使用alloc_chrdev_region()自動(dòng)分配一個(gè)未使用的主設(shè)備號(hào)。習(xí)慣上將次設(shè)備號(hào)設(shè)為0。函數(shù)原型為int alloc_chrdev_region(dev_t*dev,unsigned baseminor,unsigned count,const char *name),其中dev表示設(shè)備號(hào)指針,函數(shù)會(huì)隨機(jī)分配一個(gè)未使用的主設(shè)備號(hào),根據(jù)baseminor參數(shù)值分配次設(shè)備號(hào)。count表示分配的次設(shè)備號(hào)范圍。name表示設(shè)備文件名稱。多個(gè)Linux設(shè)備文件可擁有同一個(gè)主設(shè)備號(hào),但兩個(gè)設(shè)備的主設(shè)備號(hào)和次設(shè)備號(hào)不能都一樣。在使用函數(shù)自動(dòng)分配設(shè)備號(hào)時(shí),baseminor和count參數(shù)不要設(shè)太大,否則次設(shè)備號(hào)會(huì)溢出,且主設(shè)備號(hào)會(huì)進(jìn)位,從而變成下一個(gè)主設(shè)備號(hào)。若要直接指定設(shè)備號(hào),需使用register_chrdev_region()注冊(cè)字符設(shè)備區(qū)域,該函數(shù)在《Linux內(nèi)核源代碼》/fs/char_dev.c文件中實(shí)現(xiàn),原型為:int register_chrdev_region(dev_t from,unsigned count,const char *name),from表示設(shè)備號(hào),count表示次設(shè)備號(hào)范圍,name表示設(shè)備文件名稱。一般采用分別指定主設(shè)備號(hào)和次設(shè)備號(hào)的方式指定設(shè)備號(hào),需要MKDEV宏將主設(shè)備號(hào)和次設(shè)備號(hào)組合成設(shè)備號(hào)-“int dev_number=MKDEV(major,minor);”。也可分別使用MAJOR和MINOR宏從設(shè)備號(hào)中獲取主設(shè)備號(hào)和次設(shè)備號(hào),代碼為:“int major=MAJOR(dev_number); int minor=MAJOR(dev_number);”3.cdev_add()用于將字符設(shè)備添加到probes數(shù)組中。函數(shù)在《Linux內(nèi)核源代碼》/fs/char_dev.c文件中實(shí)現(xiàn),原型為

  “int cdev_add(struct cdev *p,dev_t dev,unsigned count){

  p-》dev=dev;

  p-》count=count;

  return kobj_map(cdev_map,dev,count,NULL,exact_match,exact_lock,p);

  }”,調(diào)用該函數(shù)需指定設(shè)備文件指針p、設(shè)備號(hào)dev和設(shè)備文件數(shù)量count。在該函數(shù)還調(diào)用了一個(gè)重要的函數(shù)kobj_map,此函數(shù)負(fù)責(zé)將設(shè)備文件的相關(guān)信息添加到保存已建立的設(shè)備文件的probes數(shù)組中。kobj_map()和probes數(shù)組都在《Linux內(nèi)核源代碼》/drivers/base/map.c文件中4.struct class包含一些與設(shè)備文件有關(guān)的變量及一些回調(diào)函數(shù)指針變量,使用class_create宏創(chuàng)建struct class,代碼為

  “struct class *leds_class=NULL;

  leds_class=class_create(THIS_MODULE,“dev_name”);”,dev_name是設(shè)備文件名稱。class_create宏實(shí)際上使用了_class_create()創(chuàng)建struct class。該函數(shù)在《Linux內(nèi)核源代碼》/drivers/base/class.c文件中實(shí)現(xiàn)5.device_create()用于創(chuàng)建設(shè)備文件,該函數(shù)在《Linux內(nèi)核源代碼》/include/linux/device.h文件中定義,在《Linux內(nèi)核源代碼》/drivers/base/core.c文件中實(shí)現(xiàn)。可使用代碼“device_create(leds_class,NULL,dev_number,NULL,DEVICE_NAME);”調(diào)用device_create()創(chuàng)建設(shè)備文件,其中l(wèi)eds_class表示struct class,dev_number表示設(shè)備號(hào),DEVICE_NAME表示設(shè)備文件的名稱。編寫(xiě)leds_create_device()時(shí)應(yīng)了解:①DEVICE_COUNT表示建立設(shè)備文件的個(gè)數(shù)②alloc_chrdev_region()的第二個(gè)參數(shù)表示分配的起始次設(shè)備號(hào)。如果第三個(gè)參數(shù)的值大于1,函數(shù)會(huì)依次分配次設(shè)備號(hào)③采用自動(dòng)分配設(shè)備號(hào)的方式創(chuàng)建設(shè)備文件,建議使用MAJOR和MINOR宏獲取主設(shè)備號(hào)和次設(shè)備號(hào),并分別保存在major和minor變量中,以備之后使用到④LED驅(qū)動(dòng)的設(shè)備號(hào)保存在dev_number變量中,要將leds_cdev.dev變量的值賦給dev_number變量。leds_init()是LED驅(qū)動(dòng)的初始化函數(shù),在函數(shù)中直接調(diào)用leds_create_device()即可。若將S3C6410_LEDS_MAJOR設(shè)為0,系統(tǒng)會(huì)自動(dòng)分配一個(gè)未使用的主設(shè)備號(hào),次設(shè)備號(hào)仍是10.在每次裝載LED驅(qū)動(dòng)時(shí)主設(shè)備號(hào)可能會(huì)不一樣,但次設(shè)備號(hào)總是10。

  卸載LED驅(qū)動(dòng)的設(shè)備文件:卸載操作會(huì)稍簡(jiǎn)單一些,需依次調(diào)用device_destroy、class_destroy和unregister_chrdev_region()。leds_destroy_device()用于卸載LED驅(qū)動(dòng)的設(shè)備文件,leds_exit()是LED驅(qū)動(dòng)的卸載函數(shù),它通過(guò)調(diào)用leds_destroy_device()來(lái)完成卸載LED驅(qū)動(dòng)設(shè)備文件的工作。

  設(shè)置寄存器與初始化LED驅(qū)動(dòng):ARM處理器有多個(gè)寄存器,通過(guò)設(shè)置不同寄存器的值??梢栽O(shè)置LED引腳的狀態(tài)、打開(kāi)或禁止上拉電路以及控制LED的亮和滅。我們必須知道的有:①LED有兩個(gè)引腳:GPB0和GPB1,其中一個(gè)引腳連接到了ARM處理器的GPI0端口,另一個(gè)引腳經(jīng)過(guò)一個(gè)限流電阻連接到電源VCC3上。當(dāng)GPI0端口為低電平時(shí),LED兩端產(chǎn)生電壓差,LED有電流通過(guò)發(fā)光;反之當(dāng)GPI0端口為高電平時(shí),LED中沒(méi)有電流通過(guò),燈熄滅。高低電平之間切換非常快,LED亮滅之間有一定的延遲②控制LED需要通過(guò)3個(gè)寄存器完成,GPMCON端口配置寄存器、GPMDAT端口數(shù)據(jù)寄存器和GPMPUD端口上拉電路寄存器③每一個(gè)寄存器可以使用4個(gè)字節(jié),即一個(gè)int類型數(shù)據(jù)占用的空間④使用GPMCON寄存器的低16位將LED的兩個(gè)端口GPB0、GPB1的屬性設(shè)為Output。每4位設(shè)置一個(gè)LED,共4個(gè)LED。output的值是0001,若使用十六進(jìn)制表示,寄存器的低16位的值是0x1111⑤使用GPMDAT寄存器的低4位控制4個(gè)LED的亮、滅。每一位控制一個(gè)LED,最低位控制離電池最近的LED。0表示亮、1表示滅⑥使用GPMPUD寄存器的低8位分別打開(kāi)4個(gè)LED的上拉電路。每?jī)晌豢刂埔粋€(gè)LED的上拉電路。10為打開(kāi)上拉電路。使用十六進(jìn)制的話,GPMPUD寄存器的低8位是0xAA,才能同時(shí)打開(kāi)4個(gè)LED的上拉電路。以上3個(gè)寄存器在內(nèi)存中都有一個(gè)虛擬地址。向這些地址寫(xiě)入數(shù)據(jù)后,ARM處理器會(huì)使用一套算法將虛擬地址映射成物理地址,并根據(jù)物理地址將數(shù)據(jù)寫(xiě)入相應(yīng)的硬件端口。ARM處理器中的GPMCOM、GPMDAT和GPMPUD的虛擬地址在Linux內(nèi)核中都使用了宏定義。為了跟蹤這些宏,需再加兩個(gè)include路徑:/root/kernel/linux_kernel_2.6.36/arch/arm/mach-s3c64xx/include和/root/kernel/linux_kernel_2.6.36/arch/arm/plat-samsung/include。這三個(gè)寄存器的虛擬地址對(duì)應(yīng)的宏分別為S3C64XX_GPMCON、S3C64XX_GPMPUD、S3C64XX_GPMDAT。這三個(gè)宏涉及了4個(gè)頭文件共9個(gè)宏??赏瞥鯯3C64XX_GPM_BASE的值是0xF04500820,GPMCON、GPMDAT和GPMPUD寄存器的虛擬地址分別為0xF04500820、0xF04500824和0xF04500828,這三個(gè)虛擬地址是固定的,可向這三個(gè)地址寫(xiě)數(shù)據(jù)。更好的是使用S3C64XX_GPMCON、S3C64XX_GPMPUD、S3C64XX_GPMDAT來(lái)操作這3個(gè)地址。一般需在LED驅(qū)動(dòng)裝載時(shí)初始化上述3個(gè)寄存器。只要在leds_init()中調(diào)用leds_init_gpm()就可完成寄存器的初始化。

  控制LED:LED驅(qū)動(dòng)可使用兩種方式控制LED:通過(guò)字符串控制LED和通過(guò)I/O命令控制LED。要使用以上兩種方式控制LED,驅(qū)動(dòng)必須接收相應(yīng)的數(shù)據(jù)。若通過(guò)字符串控制LED,需使用file_operations.write(),可接收向設(shè)備文件寫(xiě)入的數(shù)據(jù)。若通過(guò)I/O命令控制,需使用file_operations.ioctl(),可接收向字符設(shè)備發(fā)送的命令和參數(shù)。s3c6410_leds_write()用于接收向LED驅(qū)動(dòng)的設(shè)備文件寫(xiě)入控制LED的數(shù)據(jù),在實(shí)現(xiàn)其功能編寫(xiě)代碼時(shí)需了解:①4個(gè)LED的亮滅用一個(gè)長(zhǎng)度為4的mem數(shù)組。1表示點(diǎn)亮LED,0表示熄滅LED。與GPMDAT寄存器的低4位表示的含義正好相反②若寫(xiě)入的字符串長(zhǎng)度小于等于4,直接寫(xiě)入這些字符串。若長(zhǎng)度大于4,則只寫(xiě)入前4個(gè)字符串。s3c6410_leds_write()要按傳入該函數(shù)的字符串長(zhǎng)度返回,否則系統(tǒng)會(huì)調(diào)用多次該函數(shù)寫(xiě)入字符串③事先mem數(shù)組已被清零,若要寫(xiě)入的字符串長(zhǎng)度小于4,則相當(dāng)于后面的字符都是④向GPMDAT寄存器寫(xiě)入數(shù)據(jù)之前最好先讀取GPMDAT寄存器的當(dāng)前值,并通過(guò)位與、或等操作保留與本次操作無(wú)關(guān)的值⑤ioread32、iowrite32用于讀寫(xiě)虛擬地址中的32位數(shù)據(jù)。使用命令

  “# adb shell ‘echo 1101 》 /dev/s3c6410_leds’

  # adb shell ‘echo 1 》 /dev/s3c6410_leds’”可通過(guò)字符串控制LED的亮、滅。I/O命令無(wú)法使用命令行方式進(jìn)行測(cè)試。

  LED驅(qū)動(dòng)的模塊參數(shù):若想在裝載LED驅(qū)動(dòng)時(shí)指定默認(rèn)狀態(tài)值,就要使用模塊參數(shù)。為L(zhǎng)inux驅(qū)動(dòng)指定一個(gè)模塊參數(shù)需使用module_param(name,type,perm)宏。name表示參數(shù)名,type表示參數(shù)類型,perm表示讀/寫(xiě)權(quán)限。module_param支持的參數(shù)類型包括byte、short、ushort、int、uint、long、charp、bool和invbool。使用module_param宏指定模塊參數(shù)時(shí),會(huì)在/sys/module目錄下生成和驅(qū)動(dòng)設(shè)備文件同名的目錄。若在裝載Linux驅(qū)動(dòng)時(shí)未指定某個(gè)參數(shù),則參數(shù)文件的內(nèi)容是該參數(shù)在Linux驅(qū)動(dòng)源代碼中指定的默認(rèn)值。通過(guò)module_param宏可指定參數(shù)文件的訪問(wèn)權(quán)限。S_IRUGO表示所有的用戶都可訪問(wèn)該參數(shù)文件中的內(nèi)容,但不能修改。S_IRUGO|S_IWUSR表示允許所有用戶讀,以及創(chuàng)建文件的用戶寫(xiě)。Linux內(nèi)核還提供了更多的定義訪問(wèn)權(quán)限的宏。S_IRWXUGO表示所有用戶可對(duì)文件讀、寫(xiě)和執(zhí)行。IWUGO表示所有用戶對(duì)文件只有寫(xiě)權(quán)限。需要修改LED驅(qū)動(dòng)的代碼,為L(zhǎng)ED驅(qū)動(dòng)添加一個(gè)模塊參數(shù),該參數(shù)存儲(chǔ)了4個(gè)LED的初始狀態(tài),參數(shù)類型為int。參數(shù)值的范圍是0到15.參數(shù)值控制LED的規(guī)則與GPMDAT寄存器低4位控制LED的規(guī)則相同。為L(zhǎng)ED驅(qū)動(dòng)添加模塊參數(shù)首先要定義一個(gè)保存模塊參數(shù)值的變量,然后使用module_param宏指定模塊參數(shù)的相關(guān)信息。最后修改leds_init()代碼,將leds_init_gpm()的參數(shù)值改成~leds_state。使用命令“# adb shell insmod /data/local/s3c6410_leds.ko leds_state=3”可測(cè)試LED驅(qū)動(dòng)的模塊參數(shù)。執(zhí)行完命令后,會(huì)在/sys/module/s3c6410_leds/parameters目錄下生成一個(gè)leds_state文件,使用命令

  “# adb shell cat /sys/module/s3c6410_leds/parameters/leds_state”可看到文件內(nèi)容為3。使用命令“# adb shell ‘echo 5 》 /sys/module/s3c6410_leds/parameters/leds_state’”可將文件內(nèi)容改為5。修改leds_state文件內(nèi)容后,在LED驅(qū)動(dòng)代碼中的leds_state變量值會(huì)變成5。Linux驅(qū)動(dòng)在裝載時(shí)會(huì)將指定的參數(shù)值寫(xiě)入?yún)?shù)文件,若未指定參數(shù)值,Linux驅(qū)動(dòng)會(huì)將參數(shù)的默認(rèn)值寫(xiě)入?yún)?shù)文件。在Linux驅(qū)動(dòng)工作的過(guò)程中,參數(shù)值會(huì)與參數(shù)文件中的內(nèi)容同步。使用module_param_array(name,type,nump,perm)宏可為L(zhǎng)inux驅(qū)動(dòng)指定數(shù)組形式的模塊參數(shù)。nump表示存儲(chǔ)數(shù)組長(zhǎng)度的變量的指針,perm表示參數(shù)文件的訪問(wèn)權(quán)限。通過(guò)命令“# adb shell insmod /data/local/s3c6410_leds.ko ‘leds_state=11 param=str1,str2,str3’”可指定params參數(shù)值。如果params參數(shù)指定的值的個(gè)數(shù)少于數(shù)組長(zhǎng)度,后面的數(shù)組元素使用默認(rèn)值。如果大于數(shù)組長(zhǎng)度,LED驅(qū)動(dòng)裝載失敗,并在日志中輸出信息。使用模塊參數(shù)要注意:①通過(guò)module_param_array宏的第3個(gè)參數(shù)指定數(shù)組長(zhǎng)度時(shí)要使用指針類型的數(shù)據(jù)②如果Linux驅(qū)動(dòng)含有多個(gè)模塊參數(shù),需將這些參數(shù)用單引號(hào)或雙引號(hào)括起來(lái)③指定數(shù)組類型的參數(shù)值時(shí),逗號(hào)前不能有空格。

  結(jié)語(yǔ)

  關(guān)于使用繼電器的發(fā)光二極管閃爍電路就介紹就到這了,如有不足之處歡迎指正。

相關(guān)閱讀推薦:數(shù)字電路控制閃爍發(fā)光二極管的電路圖

相關(guān)閱讀推薦:單只閃爍發(fā)光二極管的應(yīng)用電路

非常好我支持^.^

(0) 0%

不好我反對(duì)

(1) 100%

( 發(fā)表人:金巧 )

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?