哎呀哎呀哎呀~,我爱上了事件

哎呀哎呀哎呀~,我爱上了事件

左直拳

事件对我来说很神秘,不容易理解和掌握。

可是慢慢的用了几次后,认为很好用。我发觉我已经喜欢上它了。

让我们立即开始这段感情吧。

一、为什么要用事件?

第一个反应当然是想获得一个通知。就是说,我希望某个东西执行到某个步骤,就通知我,我好做点什么事情;最初VC里的事件给我的印象就是这样子的。当然C#里也有这样的功能。

第二个,预留一个空间让调用方来执行自己的东西。我目前做得最多的就是在写用户控件的时候,提供事件来让调用这些控件的程序在事件激发时处理自己特定的代码,这些代码是怎么样的,对控件本身来说完全不知情。

二、如何使用事件?

(一)ASP.NET应用

结合写控件来说明。

在用户控件里:

1、先声明一个委托

public delegate void ClickEventHandler(object sender, EventArgs e);

C#里,事件本质是一个委托。委托的作用是可以将函数或方法当作参数来使用。

2、再用这个委托声明一个事件E

public event ClickEventHandler MyClick;

3、然后在控件本身的事件中(例如某个按扭被点击)检查事件E是否有被引用,有就执行

protected void btnTest_Click(object sender, EventArgs e)

{

……

if (MyClick != null) MyClick(this, e);

}

这个执行,就是触发调用方的代码。

4、在调用方

页面代码:

<uc4:myCtrl ID="MyCtrl1" runat="server" OnMyClick="MyCtrl1_MyClick" />

注意这里是OnMyClick,多了一个”On”

服务器代码:

protected void MyCtrl1_MyClick(object sender, EventArgs e)

{

//HELLO WORLD

}

(二)WINFORM等常规程序应用

我搞了个东西使用了多线程,现在想所有的线程都执行完了以后,返回一个消息,好作些抹屁股的工作。

用事件。

public class PThreadInvoke

{

public PThreadInvoke()

{

……

//加入事件

CThreadDo.ThreadFinished += new CThreadDo.FinishEventHandler(CThreadDo_ThreadFinished);

}

//调用该事件的函数

void CThreadDo_ThreadFinished()

{

//HELLO WORLD

}

//类中类

class CThreadDo

{

public delegate void FinishEventHandler();

public static event FinishEventHandler ThreadFinished;

//所有线程执行完

public void ThreadIsOver()

{

……

//触发事件

if ( ThreadFinished != null)

{

ThreadFinished();

}

}

经过测试,事件跟全局静态变量差不多,比如说,就本例子来讲,这个线程不管是用户手工激发,还是用定时器每隔一段时间激发,都能收到ThreadFinish事件。比方说,这个程序一直在后台运行,定时器激发了线程;然后用户打开了界面,很显然,用户使用的实例PThreadInvoke 和定时器使用的PThreadInvoke 并非同一个,可是定时器开辟的线程完成之后,触发的ThreadFinished 事件,在用户使用的实例PThreadInvoke 里同样能收到。只要 if ( ThreadFinished != null) 都可以。

总结:

事件本质是一个委托。由调用方引用(+=),由被调用方触发。

好多东西我都没搞懂,写出来也不知道对不对。谨作总结备忘。

阅读更多

哎呀,ds18b20 驱动失败

02-21

程序网上参考的,也看了datasheet没有问题啊。rnrn可是到这里rnrn while(Read_DS()==0)rn rn printk(DEVICE_NAME " Convert....\n");rn msdelay(50);rn err++;rn if(err==10)rn rn printk(DEVICE_NAME " Convert fail\n");rn return -1;rn rnrn rn就过不去了。rnrn老是转换失败。rnrnrn#include rn#include rn#include rn#include rn#include rn#include rn#include rn#include rn#include rn#include rnrn#define DEVICE_NAME "DS18B20"rn#define DS18B20_MAJOR 250 //这里要确定自己的这个主设备号 mknod /dev/DS18B20 c 250 0rn#define DS_PIN S3C2410_GPB1 //这可以找一个自己方便的管脚,只要是引出的GPIO都可以rn#define OUT S3C2410_GPB1_OUTP //设置成输出端口rn#define IN S3C2410_GPB1_INP //设置成输入端口rn#define DIS_UP 1rn#define EN_UP 0rn#define Search 0x00F0 //好型没怎么用啊!!rn#define Read_ROM 0x0033 //just for onern#define Skip_ROM 0x00CC //跳rom的时序rn#define Convert 0x0044 //ds18b20的固定时序,管脚识别到该信号开始对测到的温度进行转换rn#define Write 0x004E //TH---TL---Configrn#define Read 0x00BE //ds18b20的固定时序,管脚识别到该信号时开始从外界获取温度rnrn#define bit_9 0x001Frn#define bit_10 0x003Frn#define bit_11 0x005Frn#define bit_12 0x007Frnrn#define uint16 unsigned intrnrn//unsigned int ROM_DATA[8];rnrnvoid usdelay(unsigned int i) //延时 i us 对于不同系统可能会有所差别,请适当修改rnrn unsigned int j;rn for(i=i;i>0;i--)rn for(j=90;j>0;j--);rnrnrnvoid msdelay(unsigned int i) //延时 i usrnrn for(i=i;i>0;i--)rn usdelay(1000);rnrnrnvoid SetL(void)rnrn s3c2410_gpio_cfgpin(DS_PIN,OUT);rn s3c2410_gpio_setpin(DS_PIN,0);rnrnrnvoid SetH(void)rnrn s3c2410_gpio_cfgpin(DS_PIN,OUT);rn s3c2410_gpio_setpin(DS_PIN,1);rnrnrnunsigned int Read_DS(void)rnrn unsigned int i;rn s3c2410_gpio_cfgpin(DS_PIN,IN);rn s3c2410_gpio_pullup(DS_PIN,EN_UP);rn __asm("nop");rn __asm("nop");rn __asm("nop");rn i=s3c2410_gpio_getpin(DS_PIN);rn if(i!=0)rn i=1;rn return i;rnrnrnrnunsigned int ds_start(void) //初始化ds18b20rnrn unsigned int flag=1;rn int err=0;rn /*rn During the initialization sequence the bus master transmits (TX) the reset pulse by pulling the 1-Wire bus low for a minimum of 480us.rn The bus master then releases the bus and goes into receive mode (RX). rn When the bus is released, the 5k pullup resistor pulls the 1-Wire bus high.rn When the DS18B20 detects this rising edge, it waits 15us to 60us and then transmits a presence pulse by pulling the 1-Wire bus low for 60us to 240us.rn */rnrn SetH();rn usdelay(2);rn SetL();rn usdelay(600); //560延时要大于480urn SetH();rn usdelay(1); //稍作延时rnrn while(Read_DS()!=0) //ds18B20初始化成功会返回一个低电平,此时跳出循环,执行下面的操作rn rn printk(DEVICE_NAME " Wait....\n");rn usdelay(5);rn err++; //扫描最多次数.rn if(err==20)rn rn printk(DEVICE_NAME " Start fail\n");rn return -1;rn rn rnrn printk(DEVICE_NAME " Start sucess\n");rn flag=0;rn SetH(); //初始化成功后赋为高电平准备从外界读入温度rn usdelay(400);rn return flag;rnrnrnvoid ds_send(unsigned int uidata) //发送一个字节数据rnrn unsigned int i;rn printk("The send data is %d\n",uidata);rn for(i=0;i<8;i++)rn rn /*rn Both types of write time slots are initiated by the master pulling the 1-Wire bus low.rn To generate a Write 1 time slot, after pulling the 1-Wire bus low,rn the bus master must release the 1-Wire bus within 15us. When the bus is released, the 5k pullup resistor will pull the bus high. rn To generate a Write 0 time slot, after pulling the 1-Wire bus low,rn the bus master must continue to hold the bus low for the duration of the time slot (at least 60us).rn */rn SetL();rn usdelay(3);rn if((uidata&1)!=0) //写1rn rn SetH();rn usdelay(80); //保持高电平60usrn rn elsern rn usdelay(80); //写低电平直接保持rn SetH();rn rn uidata>>=1;rn rnrnrnrnunsigned int ds_read(void) //接收一个字节数据rnrn unsigned int uidata=0;rn unsigned int i;rn for(i=0;i<8;i++)rn rn SetL();rn /*rn A read time slot is initiated by the master device pulling the 1-Wire bus low for a minimum of 1us and then releasing the busrn */rn usdelay(2); //2 3 保持至少1usrn// s3c2410_gpio_setpin(DS_PIN,1); //放1rn// s3c2410_gpio_cfgpin(DS_PIN,IN); //设置为输入rn SetH();rn /*rn Output data from the DS18B20 is valid for 15us after the falling edge that initiated the read time slot.rn */rn usdelay(7); //1 2 3 4 5(e)rn if(Read_DS()==1)rn uidata+=0x0100; rn uidata>>=1; rn /*rn All read time slots must be a minimum of 60us in duration with a minimum of a 1us recovery time between slots.rn */rn usdelay(65); //延时60us,满足读时隙的时间长度要求rn SetH(); //释放总线rn rn printk("--- The recieve data is %d\n",uidata);rn return uidata;rnrnrnvoid ds_init(unsigned int TH,unsigned int TL,unsigned int bit_nmb)rnrnrn SetH();rn usdelay(80);rn if(ds_start()==0) //初始化成功rn rn ds_send(Skip_ROM); //复位rn ds_send(Write); //跳过ROM匹配,报警设定rn ds_send(TH); //THrn ds_send(TL); //TLrn ds_send(bit_nmb); //转换位数rn rnrnrnunsigned int read_tem(void)rnrn unsigned int th,tl;rn int err=0;rn ds_init(100,0,bit_12);rn th=tl=0;rn if(ds_start() != 0)rn rn return -1;rn rn ds_send(Skip_ROM);rn ds_send(Convert);rn msdelay(50);rnrn while(Read_DS()==0)rn rn printk(DEVICE_NAME " Convert....\n");rn msdelay(50);rn err++;rn if(err==10)rn rn printk(DEVICE_NAME " Convert fail\n");rn return -1;rn rnrn rnrn if(ds_start() != 0)rn rn return -1;rn rn ds_send(Skip_ROM);rn ds_send(Read);rn tl=ds_read();rn th=ds_read();rn rn th<<=8;rn tl|=th;rnrn printk("the th data is %d\n",th);rn printk("the tl data is %d\n",tl);rn printk("read_tmp success\n");rn return tl;rnrnrnstatic int ds18b20_ioctl(rn struct inode *inode,rn struct file *file,rn unsigned int cmd,unsigned long arg)rnrn return 0;rnrnrnstatic ssize_t ds18b20_read(struct file *pFile, uint16 __user *pData, size_t count, loff_t *off )rnrn uint16 tmp,ret;rn tmp =read_tem();rn ret=copy_to_user(pData, &tmp, sizeof(tmp)); //将读取得的DS18B20数值复制到用户区rn if(ret>0)rn rn printk("copy data failed\n");rn return -1;rn rn return 0;rnrnrnstatic struct file_operations ds18b20_fops = rnrn .owner = THIS_MODULE,rn .ioctl = ds18b20_ioctl,rn .read = ds18b20_read,rnrn;rnrnstatic int __init ds18b20_init(void)rnrnrn int ret;rn ret = register_chrdev(DS18B20_MAJOR, DEVICE_NAME, &ds18b20_fops);rn if (ret < 0) rn printk(DEVICE_NAME " can't register major number\n");rn return ret;rn rnrn s3c2410_gpio_cfgpin(DS_PIN, OUT);rn s3c2410_gpio_setpin(DS_PIN, 1);rn printk(DEVICE_NAME " initialized\n");rn printk("<0>""initialized\n");rnrn return 0;rnrnrnstatic void __exit ds18b20_exit(void)rnrn unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME);rn printk(DEVICE_NAME " rmmodule\n");rnrnrnmodule_init(ds18b20_init);rnmodule_exit(ds18b20_exit);rnMODULE_AUTHOR("benjamin_xc@163.com"); // 驱动程序的作者rnMODULE_DESCRIPTION("DS18B20 Driver"); // 一些描述信息rnMODULE_LICENSE("GPL");

没有更多推荐了,返回首页