本文主要是关于发光二极管的相关介绍,并侧重对运用继电器的发光二极管闪耀电路进行了翔实的描绘。
如何用继电器的发光二极管闪耀电路图
原理图如图一
衔接电路前先不要接二极管D1,一会再解说二极管的效果。三极管是2n3904 NPN型三极管,基极电阻68欧姆,要把图中的5v电源vcc1和gnd1别离接到单片机的电源和地上.,
LED灯的电路由外电源供电,R2取1k欧姆,约束电流。
实物图如下,图二和图三别离是LED灯亮和灭的相片。尽管我拿个一个开发板,可是只用了其单片机的最小体系。
用示波器测三极管集电极的波形,发现有图五所示的一个尖刺,剖析往后,是因为继电器自身便是一个线圈,在电流忽然改变的瞬间会起到阻止其改变的效果,左移在继电器的两头并联一个二极管,安稳输出的效果。参加二极管后的波形如图六中最终一组波形。
操控单片机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驱动用来操控开发板上的4个LED灯,即经过向Linux驱动发送数据能够操控LED灯的开关。LED驱动供给两种交互办法:指令和读写设备文件。
测验LED驱动之前需用USB线衔接开发板,然后翻开开发板。成功发动后,履行build.sh脚本文件编译和装置LED驱动。build.sh脚本文件会主动将s3c6410_leds.ko文件上传到开发板并装置。LED驱动只能在开发板上装置,build.sh履行了build_s3c6410.sh脚本文件进行编译和装置。LED驱动会树立一个/dev/s3c6410_leds设备文件,该Linux驱动可操控4个LED,经过向设备文件发送长度为1到4的字符串能够操控这4个LED的开关。1表明开,0表明关。字符串长度缺乏4个,相当于后边补0。履行指令
“# adb shell “echo ‘1’》 /dev/s3c6410_leds” #翻开榜首个LED,其他的都封闭
# adb shell “echo ‘1010’》 /dev/s3c6410_leds” #榜首个和第三个LED翻开,第二个和第四个封闭
# adb shell “echo ‘1111’》 /dev/s3c6410_leds” #翻开一切的LED”可操控开发板上的LED。可运用指令“# sh ~/drivers/s3c6410_leds/test_leds.sh”履行test_leds.sh脚本文件测验LED。履行脚本文件后,开发板上的4个LED会依据0到15的二进制方法操控LED,榜首个为最低位。脚本文件运用的是规范的Bash Shell,假如在Ubuntu下无法成功履行,是因为其将dash作为默许的脚本解析器。可运用指令“# dpkg-reconfigure dash”将默许脚本解析器改成Bash,呈现设置界面时,挑选“否”,再回车即可。
创立LED驱动的设备文件,过程如下;1.描绘设备文件需求运用一个cdev结构体,该结构体在《Linux内核源代码》/include/linux/cdev.h文件中界说。其间的大多数成员变量只需调用cdev_init()就可被初始化,该函数在《Linux内核源代码》/fs/char_dev.c文件中。若要在一个Linux驱动中树立多个设备文件,cdev.count变量的值便是要树立的设备文件数。这些设备文件对应的cdev结构体就经过cdev.list.prev和cdev.list.next指针变量衔接,然后构成一个双向链表。cdev.owner变量未在cdev.init函数中初始化,运用句子“leds_cdev.owner=THIS_MODULE;”来初始化2.Linux设备文件的设备号分为主设备号和次设备号。用一个int类型表明,其间前12位表明主设备号,后20位表明次设备号。设备号有两种指定办法:直接在代码中指定和动态分配。榜首种办法虽比较直观,但假如主设备号和次设备号已存在,树立设备文件就会失利。以防万一,可运用alloc_chrdev_region()主动分配一个未运用的主设备号。习惯上将次设备号设为0。函数原型为int alloc_chrdev_region(dev_t*dev,unsigned baseminor,unsigned count,const char *name),其间dev表明设备号指针,函数会随机分配一个未运用的主设备号,依据baseminor参数值分配次设备号。count表明分配的次设备号规模。name表明设备文件称号。多个Linux设备文件可具有同一个主设备号,但两个设备的主设备号和次设备号不能都相同。在运用函数主动分配设备号时,baseminor和count参数不要设太大,不然次设备号会溢出,且主设备号会进位,然后变成下一个主设备号。若要直接指定设备号,需运用register_chrdev_region()注册字符设备区域,该函数在《Linux内核源代码》/fs/char_dev.c文件中完结,原型为:int register_chrdev_region(dev_t from,unsigned count,const char *name),from表明设备号,count表明次设备号规模,name表明设备文件称号。一般选用别离指定主设备号和次设备号的办法指定设备号,需求MKDEV宏将主设备号和次设备号组合成设备号-“int dev_number=MKDEV(major,minor);”。也可别离运用MAJOR和MINOR宏从设备号中获取主设备号和次设备号,代码为:“int major=MAJOR(dev_number); int minor=MAJOR(dev_number);”3.cdev_add()用于将字符设备增加到probes数组中。函数在《Linux内核源代码》/fs/char_dev.c文件中完结,原型为
“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);
}”,调用该函数需指定设备文件指针p、设备号dev和设备文件数量count。在该函数还调用了一个重要的函数kobj_map,此函数担任将设备文件的相关信息增加到保存已树立的设备文件的probes数组中。kobj_map()和probes数组都在《Linux内核源代码》/drivers/base/map.c文件中4.struct class包含一些与设备文件有关的变量及一些回调函数指针变量,运用class_create宏创立struct class,代码为
“struct class *leds_class=NULL;
leds_class=class_create(THIS_MODULE,“dev_name”);”,dev_name是设备文件称号。class_create宏实际上运用了_class_create()创立struct class。该函数在《Linux内核源代码》/drivers/base/class.c文件中完结5.device_create()用于创立设备文件,该函数在《Linux内核源代码》/include/linux/device.h文件中界说,在《Linux内核源代码》/drivers/base/core.c文件中完结。可运用代码“device_create(leds_class,NULL,dev_number,NULL,DEVICE_NAME);”调用device_create()创立设备文件,其间leds_class表明struct class,dev_number表明设备号,DEVICE_NAME表明设备文件的称号。编写leds_create_device()时应了解:①DEVICE_COUNT表明树立设备文件的个数②alloc_chrdev_region()的第二个参数表明分配的开始次设备号。假如第三个参数的值大于1,函数会顺次分配次设备号③选用主动分配设备号的办法创立设备文件,主张运用MAJOR和MINOR宏获取主设备号和次设备号,并别离保存在major和minor变量中,以备之后运用到④LED驱动的设备号保存在dev_number变量中,要将leds_cdev.dev变量的值赋给dev_number变量。leds_init()是LED驱动的初始化函数,在函数中直接调用leds_create_device()即可。若将S3C6410_LEDS_MAJOR设为0,体系会主动分配一个未运用的主设备号,次设备号仍是10.在每次装载LED驱动时主设备号可能会不相同,但次设备号总是10。
卸载LED驱动的设备文件:卸载操作会稍简略一些,需顺次调用device_destroy、class_destroy和unregister_chrdev_region()。leds_destroy_device()用于卸载LED驱动的设备文件,leds_exit()是LED驱动的卸载函数,它经过调用leds_destroy_device()来完结卸载LED驱动设备文件的作业。
设置寄存器与初始化LED驱动:ARM处理器有多个寄存器,经过设置不同寄存器的值。能够设置LED引脚的状况、翻开或制止上拉电路以及操控LED的亮和灭。咱们有必要知道的有:①LED有两个引脚:GPB0和GPB1,其间一个引脚衔接到了ARM处理器的GPI0端口,另一个引脚经过一个限流电阻衔接到电源VCC3上。当GPI0端口为低电平时,LED两头发生电压差,LED有电流经过发光;反之当GPI0端口为高电平时,LED中没有电流经过,灯平息。凹凸电平之间切换非常快,LED亮灭之间有必定的推迟②操控LED需求经过3个寄存器完结,GPMCON端口装备寄存器、GPMDAT端口数据寄存器和GPMPUD端口上拉电路寄存器③每一个寄存器能够运用4个字节,即一个int类型数据占用的空间④运用GPMCON寄存器的低16位将LED的两个端口GPB0、GPB1的特点设为Output。每4位设置一个LED,共4个LED。output的值是0001,若运用十六进制表明,寄存器的低16位的值是0x1111⑤运用GPMDAT寄存器的低4位操控4个LED的亮、灭。每一位操控一个LED,最低位操控离电池最近的LED。0表明亮、1表明灭⑥运用GPMPUD寄存器的低8位别离翻开4个LED的上拉电路。每两位操控一个LED的上拉电路。10为翻开上拉电路。运用十六进制的话,GPMPUD寄存器的低8位是0xAA,才干一起翻开4个LED的上拉电路。以上3个寄存器在内存中都有一个虚拟地址。向这些地址写入数据后,ARM处理器会运用一套算法将虚拟地址映射成物理地址,并依据物理地址将数据写入相应的硬件端口。ARM处理器中的GPMCOM、GPMDAT和GPMPUD的虚拟地址在Linux内核中都运用了宏界说。为了盯梢这些宏,需再加两个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。这三个寄存器的虚拟地址对应的宏别离为S3C64XX_GPMCON、S3C64XX_GPMPUD、S3C64XX_GPMDAT。这三个宏触及了4个头文件共9个宏。可推出S3C64XX_GPM_BASE的值是0xF04500820,GPMCON、GPMDAT和GPMPUD寄存器的虚拟地址别离为0xF04500820、0xF04500824和0xF04500828,这三个虚拟地址是固定的,可向这三个地址写数据。更好的是运用S3C64XX_GPMCON、S3C64XX_GPMPUD、S3C64XX_GPMDAT来操作这3个地址。一般需在LED驱动装载时初始化上述3个寄存器。只要在leds_init()中调用leds_init_gpm()就可完结寄存器的初始化。
操控LED:LED驱动可运用两种办法操控LED:经过字符串操控LED和经过I/O指令操控LED。要运用以上两种办法操控LED,驱动有必要接纳相应的数据。若经过字符串操控LED,需运用file_operations.write(),可接纳向设备文件写入的数据。若经过I/O指令操控,需运用file_operaTIons.ioctl(),可接纳向字符设备发送的指令和参数。s3c6410_leds_write()用于接纳向LED驱动的设备文件写入操控LED的数据,在完结其功用编写代码时需了解:①4个LED的亮灭用一个长度为4的mem数组。1表明点亮LED,0表明平息LED。与GPMDAT寄存器的低4位表明的意义正好相反②若写入的字符串长度小于等于4,直接写入这些字符串。若长度大于4,则只写入前4个字符串。s3c6410_leds_write()要按传入该函数的字符串长度回来,不然体系会调用屡次该函数写入字符串③事前mem数组已被清零,若要写入的字符串长度小于4,则相当于后边的字符都是④向GPMDAT寄存器写入数据之前最好先读取GPMDAT寄存器的当时值,并经过位与、或等操作保存与本次操作无关的值⑤ioread32、iowrite32用于读写虚拟地址中的32位数据。运用指令
“# adb shell ‘echo 1101 》 /dev/s3c6410_leds’
# adb shell ‘echo 1 》 /dev/s3c6410_leds’”可经过字符串操控LED的亮、灭。I/O指令无法运用指令行办法进行测验。
LED驱动的模块参数:若想在装载LED驱动时指定默许状况值,就要运用模块参数。为Linux驱动指定一个模块参数需运用module_param(name,type,perm)宏。name表明参数名,type表明参数类型,perm表明读/写权限。module_param支撑的参数类型包含byte、short、ushort、int、uint、long、charp、bool和invbool。运用module_param宏指定模块参数时,会在/sys/module目录下生成和驱动设备文件同名的目录。若在装载Linux驱动时未指定某个参数,则参数文件的内容是该参数在Linux驱动源代码中指定的默许值。经过module_param宏可指定参数文件的拜访权限。S_IRUGO表明一切的用户都可拜访该参数文件中的内容,但不能修正。S_IRUGO|S_IWUSR表明答应一切用户读,以及创立文件的用户写。Linux内核还供给了更多的界说拜访权限的宏。S_IRWXUGO表明一切用户可对文件读、写和履行。IWUGO表明一切用户对文件只要写权限。需求修正LED驱动的代码,为LED驱动增加一个模块参数,该参数存储了4个LED的初始状况,参数类型为int。参数值的规模是0到15.参数值操控LED的规矩与GPMDAT寄存器低4位操控LED的规矩相同。为LED驱动增加模块参数首先要界说一个保存模块参数值的变量,然后运用module_param宏指定模块参数的相关信息。最终修正leds_init()代码,将leds_init_gpm()的参数值改成~leds_state。运用指令“# adb shell insmod /data/local/s3c6410_leds.ko leds_state=3”可测验LED驱动的模块参数。履行完指令后,会在/sys/module/s3c6410_leds/parameters目录下生成一个leds_state文件,运用指令
“# adb shell cat /sys/module/s3c6410_leds/parameters/leds_state”可看到文件内容为3。运用指令“# adb shell ‘echo 5 》 /sys/module/s3c6410_leds/parameters/leds_state’”可将文件内容改为5。修正leds_state文件内容后,在LED驱动代码中的leds_state变量值会变成5。Linux驱动在装载时会将指定的参数值写入参数文件,若未指定参数值,Linux驱动会将参数的默许值写入参数文件。在Linux驱动作业的过程中,参数值会与参数文件中的内容同步。运用module_param_array(name,type,nump,perm)宏可为Linux驱动指定数组方法的模块参数。nump表明存储数组长度的变量的指针,perm表明参数文件的拜访权限。经过指令“# adb shell insmod /data/local/s3c6410_leds.ko ‘leds_state=11 param=str1,str2,str3’”可指定params参数值。假如params参数指定的值的个数少于数组长度,后边的数组元素运用默许值。假如大于数组长度,LED驱动装载失利,并在日志中输出信息。运用模块参数要注意:①经过module_param_array宏的第3个参数指定数组长度时要运用指针类型的数据②假如Linux驱动含有多个模块参数,需将这些参数用单引号或双引号括起来③指定数组类型的参数值时,逗号前不能有空格。
结语
关于运用继电器的发光二极管闪耀电路就介绍就到这了,如有缺乏之处欢迎纠正。