qn1512443998

qn1512443998

0个粉丝

4

问答

0

专栏

1

资料

qn1512443998  发布于  2017-12-12 22:48:38
采纳率 0%
4个问答
2449

红外发送的驱动代码

 
谁有红外发送的驱动代码 可以买的,项目急,感谢!
我来回答
回答10个
时间排序
认可量排序

qn1512443998

0个粉丝

4

问答

0

专栏

1

资料

qn1512443998 2017-12-12 22:49:54
认可0
因为海思没有提供红外发送的驱动代码,我现在没有思路,谁有代码可以提供下

qn1512443998

0个粉丝

4

问答

0

专栏

1

资料

qn1512443998 2017-12-13 14:56:08
认可0
自己顶一下:hug:

goodman

4个粉丝

30

问答

18

专栏

17

资料

goodman 2017-12-13 18:35:37
认可0
海思SDK里面带红外的驱动代码的,你可以找下

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2017-12-14 08:41:05
认可0
本帖最后由 ngswfx 于 2017-12-14 09:12 编辑

你是想通过3516去控制别的设备还是接受控制,如果是接受控制,这个海斯应该有,如果想控制别的设备,估计要自己想办法了

也就是说,如果你弄个IPC吸顶,顺便还想开空调或者电视的话,估计要自己弄个程序写个驱动让红外管子按照你的指令发控制码,这有点像小米的手机这种应用

不过这种c代码,网上应该很多,到CSDN找吧,只要是C的,应该都可以借鉴,你需要做的就是怎么让海斯芯片的GPIO口去输出相应的指令

我估计海斯没考虑这种发射应用,要是接收,应该有例子

我看了一下3516的SDK,里面的驱动,发现发射的接口在,但没实现,估计应该可以直接改一下就可以了

static int hiir_write(struct file* filp, const char __user* buf, size_t count, loff_t* f_pos)
{
    return 0;
}

//我从网上下载了一个,说是linux用的,也没看太懂,你研究一下,看能不能借鉴,记得弄好,共享一下,这种功能有时候可能可以用上
//里面有个static ssize_t IR_Transmit(struct file *filp, const char *buf, size_t count, loff_t *f_pos),看怎么衔接海斯驱动里面的hirr_write,估计流程应该可以借鉴



[code]



1.硬件测试程序


#include "..\Inc\2410addr.h"
#include "..\Inc\2410lib.h"
#include "..\Inc\option.h"
#define  IR_Addr    (*(volatile unsigned char *)0x080000c8)
#define  IR_NUM_MAX  68  
//红外脉冲的最大输入个数,正常:2(Lead code)+32(16bit custom*2)+32(16bit data*2)+1(end)=67  
#define  IR_NUM_MIN  30   
unsigned char gSending;          //红外发射标志,1 为发射
unsigned char gLearning;   
//红外学习标志,0:未学习状态,1:表示进入红外学习,正等待红外信号输入 2:红外学习过程中
unsigned short gCount;
//红外学习过程中,对红外数据进行计数(定时器溢出时递增,输入脉冲跳沿中断是也递增)
unsigned short gLearnTime;        //红外学习时间,即输入脉冲高你电平的总个数
unsigned char gState;





unsigned short gIRData[100]; //红外学习时,数据缓冲区,用于存放红外脉冲的高低电平时间,第 1
个数据为低电平时间
unsigned short *pIRData;     //红外发送时,指向数据缓冲区
unsigned char gTimeoutCount; //用于红外学习时的定时器溢出计数器
unsigned char gState_Study;

unsigned char gPWMEn;
unsigned short gLen;
void LearnOK(void);

//38KHz 载波输出使能,1 为开定时器 1 输入输出载波信号,0 为停止
//要发送红外的数据长度

void __irq Int_IRStudy(void);
void __irq Int_Timer0(void);
void __irq Int_Timer1(void);
/*********************************************************************************
函数原形:void Init_IR(void)                                            
功        能:初始化红外相关的 I/O,中断及定时器等                                                   
*********************************************************************************/
void Init_IR(void){
    rGPFCON = rGPFCON & ~(0x3 << 0) | (0x2 << 0);  //EINT0=GPF0
rGPFUP = rGPFUP | ~(0x1 << 0);                 //disable
rGPBCON = rGPBCON & ~(0x3 << 2) | (0x2 << 2);  //TOUT1
    rEXTINT0 = rEXTINT0 & ~(0x7 << 0) | (0x6 << 0);//EINT0:Both edge triggered
    pISR_EINT0 = (int)Int_IRStudy;
    ClearPending(BIT_EINT0);
    pISR_TIMER0 = (int)Int_Timer0;
    rTCFG0 = rTCFG0 & ~(0xff << 0) | (0x01 << 0);  //prescale value = 1
    rTCFG1 = rTCFG1 & ~(0xf << 0)        | (0x2 << 0);    //divider value = 8
    rTCNTB0 = 0xffff;
    rTCFG1 = rTCFG1 & ~(0xf << 4) | (0x2 << 4);//divider value = 8,50MHz/(1+1)/8=3.125MHz

    rTCNTB1 = 0x52;                          

//3.125MHz/38K=82=0x52;  

    rTCMPB1 = 0x29;                                      //0x52/2=0x29
    rTCON = rTCON & ~(0xf<<8)|(0xa<<8);//Timer1:auto reload; Update TCNTB1,TCMPB1; Stop
    pISR_TIMER1 = (int)Int_Timer1;

    rINTMSK &= ~(BIT_EINT0);               
gState = 1;
    gLearning = 0;
}

//打开外部中断 0 开始红外学习

/*********************************************************************************
函数原形:void __irq Eint3Isr(void)
功        能:IR 输入脉冲双边沿中断,记录电平时间宽度                                                            
*********************************************************************************/
void __irq Int_IRStudy(void){
    rGPFCON = rGPFCON & ~(0x3 << 0) | (0x0 << 0);        //GPF0=IN
    if (gLearning == 0){
        if (!(rGPFDAT & 0x1)){                          //确认是否为低电平
            gLearning = 1;





            rTCON = rTCON & ~(0x1f << 0) | 0x2;          //Updata TCNTB0
  rTCON = rTCON & ~(0x1f << 0) | 0x1;          //start for timer0

  rINTMSK &= ~(BIT_TIMER0);        

//打开定时器中断




        }
    }

  gState = 0;                                  //保存当前脉冲电平值   
  pIRData = gIRData;                          //初始化红外数据缓冲区            

    else if (gLearning == 1){                      //确认红外引导码
        *pIRData = rTCNTO0;
        if ((rGPFDAT & 0x1) && (gState        == 0) && (*pIRData < 45535) && (*pIRData > 25535)){
//Lead Code 9ms, > 6.4ms, < 12.8ms

            rTCON = rTCON & ~(0x1f << 0) | 0x2;

//Updata TCNTB0







        }

  rTCON = rTCON & ~(0x1f << 0) | 0x1;          //start for timer0
  gLearning = 2;
  gState = 1;
  pIRData++;

        else{  
            rINTMSK |= BIT_TIMER0;         

//Lead Code check fail
//关定时器中断

            rTCON = rTCON & ~(0x1f << 0) | 0x2;          //stop for timer0
            gLearning = 0;
        }
    }
    else{
        if (((rGPFDAT & 0x1) && gState == 0) || ((!(rGPFDAT & 0x1)) && gState == 1)){
            *pIRData++ = rTCNTO0;//记录计数器值,第 1 个数据为低电平时间,第 2 为高电平时间。。。
            gState = gState ? 0 : 1;                //乒乓开关用于状态翻转判定
            if (gLearning > IR_NUM_MAX){
                LearnOK();
            }
            else{
                rTCON = rTCON & ~(0x1f << 0) | 0x2;
                rTCON = rTCON & ~(0x1f << 0) | 0x1;
                gLearning++;
            }
}
    }   
    rGPFCON = rGPFCON & ~(0x3 << 0) | (0x2 << 0);        //GPF0=EINT0
    ClearPending(BIT_EINT0);
}
/***************************************************************************************
函数原形:void __irq Timer0Done(void)                              
功        能:红外学习定时器溢出中断处理,根据红外学习脉冲数来确定学习是否成功结束      
***************************************************************************************/





void __irq Int_Timer0(void){
    if (gSending == 1){
        if(gCount >= gLen){
            gSending = 0;
            gPWMEn = 0;
    rTCON = rTCON & 0xffff000;   









//发送结束


//stop for timer0 timer1

    rINTMSK |= BIT_TIMER1 | BIT_TIMER0;            //关定时器中断
}
     else{
            if (gPWMEn == 0) {                      //上一个数据为低电平,则该数据为高电平
                gPWMEn = 1;

                rTCNTB0 = 0xffff        - *pIRData;
      rTCON = (rTCON&0xffffff0) | 0x2;
      rTCON = (rTCON&0xffffff0) | 0x1;
      rTCON = (rTCON&0xffff0ff) | 0xa00;

//高电平时间

      rTCON = (rTCON&0xffff0ff) | 0x900;        //重新启动 38K 载波输出
     }
         else{
                gPWMEn = 0;

                rTCNTB0 = 0xffff - *pIRData;
                rTCON = (rTCON & 0xffffff0) | 0x2;
      rTCON = (rTCON & 0xffffff0) | 0x1;
            }
            pIRData++;
            gCount++;
        }
    }
    else if (gLearning > IR_NUM_MIN) {
  LearnOK();
    }
    else{
        rINTMSK |= BIT_TIMER0;

//低电平时间










//红外学习时间溢出结束





//关定时器中断

        rTCON = rTCON & ~(0x1f << 0) | 0x0;         //stop for timer0
        gLearning = 0;
    }
    ClearPending(BIT_TIMER0);
}
/*********************************************************************************
函数原形:void __irq Timer1Done(void)                                            
功        能:产生红外的 38KHz 载波         
参    数:gPWMEn -- 1 为输出 38K 载波,0 为停止输出                                
********************************************************************************/
void __irq Int_Timer1(void){
if (!gPWMEn){





         rTCON = rTCON & 0xffff0ff;
}  
ClearPending(BIT_TIMER1);
}




//stop for Timer 1



/*********************************************************************************
函数原形:void        LearnOK(void)                                                      
功        能:红外学习成功                                                                          
*********************************************************************************/
void LearnOK(void){
    rTCON = rTCON & ~(0x1f << 0) | 0x2;        //stop timer0  
    rINTMSK |=        BIT_EINT0 | BIT_TIMER0;  
    gLen =        gLearning - 1;                      //保存红外学习的数据个数
    gLearning = 0xff;
}
/*********************************************************************************
函数原形:void SendIR(void)                                                      
功        能:启动红外发送                                                            
*********************************************************************************/
void SendIR(void){
    pIRData = gIRData;
    gSending = 1;
    gCount = 0;
    gPWMEn = 1;                                     //发送高电平, 与红外学习时电平相反
    rTCNTB0 = 0xffff - *pIRData;
    pIRData++;
    gCount++;
    rTCON = (rTCON & 0xffffff0) | 0x2;         //Update TCNTB0, TCMPB0
    rTCON = (rTCON & 0xffffff0) | 0x1;         //Start for Timer 0
    rTCON = (rTCON & 0xffff0ff) | 0xa00;//Timer1:auto reload;Update TCNTB1,TCMPB1; Stop
    rTCON = (rTCON & 0xffff0ff) |        0x900;       //Start for Timer 1
    rINTMSK &= ~(BIT_TIMER0 |        BIT_TIMER1);  
}
/*********************************************************************************
函数原形:void LearnIR(unsigned char which)                                            
功        能:置 IR 学习开始条件,即进入红外学习                                                                  
*********************************************************************************/
void LearnIR(void){
    unsigned char i = 0;  
    IR_Addr = 0x0f;                            //使能所有 IR 通道输出
while (1){
        Init_IR();
        while (gLearning != 0xff);             //等待红外学习完成
        SendIR();





        while (gSending);
    }
}



2.Linux 驱动程序


#define DEVICE_NAME    "PGM_IR"
#define BUZZ_MAJOR      236
#define IRQ_IRInput     IRQ_EINT0




//等待红外发射完成

#define        IR_NUM_MAX      68   //2(Lead code)+32(16bit custom*2)+32(16bit data*2)+1(end)=67
#define IR_NUM_MIN      30  
#define Wait_Time       1800 //IR study wait times 18s
#define pIR_ADDR        0x080000c8
void * vIR_ADDR;

unsigned char Learning, IO_State;  
unsigned char PWMEn, Transmit_flag, TLen, Transmit_Index;
static DECLARE_WAIT_QUEUE_HEAD(Wait_Study);
static DECLARE_WAIT_QUEUE_HEAD(Wait_Transmit);

//IR study use
//IR Transmits

static void pwm_irq_handle(int irq, void *dev_id, struct pt_regs *regs) {//38K
    if(!PWMEn){
        TCON = TCON & (~(0xf << 8)) | (0xa << 8);
//Timer1:auto reload;Inverter off;Update TCNTB1,TCMPB1;stop
    }
}
static void timer0_Transmit_irq_handle(int irq, void *dev_id, struct pt_regs *regs){
    unsigned short *pIRData = dev_id;
    if (Transmit_flag == 1) {                       //IR Transmit
        if(Transmit_Index >= TLen){
            Transmit_flag = 0;
            PWMEn = 0;
            TCON = TCON & 0xffff000;                      //stop for timer0 timer1
            wake_up_interruptible(&Wait_Transmit);
        }
        else{
            if (PWMEn == 0){
                PWMEn = 1;
                TCNTB0 = 0xffff - *(pIRData + Transmit_Index);
                TCON = (TCON & 0xffffff0) | 0x2;
                TCON = (TCON & 0xffffff0) | 0x1;
                TCON = (TCON & 0xffff0ff) | 0xa00;
                TCON = (TCON & 0xffff0ff) | 0x900;
            }
            else{





                PWMEn = 0;
         TCNTB0 = 0xffff - *(pIRData + Transmit_Index);
                TCON = (TCON & 0xffffff0) | 0x2;
TCON = (TCON & 0xffffff0) | 0x1;
            }
            Transmit_Index++;
        }
    }
}
static void timer0_Study_irq_handle(int irq, void *dev_id, struct pt_regs *regs){
    TCON = TCON & ~(0x1f << 0);                     //stop for timer0
    if (Learning > IR_NUM_MIN){
        wake_up_interruptible(&Wait_Study);
    }
    else{
        Learning = 0;
    }
}
static void IRInput_irq_handle(int irq, void *dev_id, struct pt_regs *regs){
    unsigned short *pIRData = dev_id;
set_gpio_ctrl(GPIO_F0 | GPIO_PULLUP_DIS | GPIO_MODE_IN); //INPUT
    if (Learning == 0){

        if (!read_gpio_bit(GPIO_F0)) {
            Learning =        1;

//check Lead code      

            TCON = TCON        & ~(0x1f << 0) | 0x2;        //Updata TCNTB0
            TCON = TCON & ~(0x1f << 0) | 0x1;  //start for timer0         
            IO_State = 0;  
        }
    }
    else if (Learning == 1){                   //affirm Lead code  
        *(pIRData) = TCNTO0;
        if (read_gpio_bit(GPIO_F0) && (IO_State == 0) && (*pIRData < 45535) && (*pIRData >
25535)) {                                              //Lead Code 9ms, > 6.4ms, < 12.8ms
            TCON = TCON & ~(0x1f << 0) | 0x2;        //Updata TCNTB0
            TCON = TCON & ~(0x1f << 0) | 0x1;        //start for timer0
            Learning = 2;
            IO_State = 1;
        }

        else {  
            TCON = TCON & ~(0x1f <<        0);
     Learning = 0;
     }
    }
    else{

//Lead Code check fail         
//stop for timer0





        if((read_gpio_bit(GPIO_F0) && IO_State == 0) || ((!read_gpio_bit(GPIO_F0)) &&
IO_State == 1)) {
            *(pIRData+Learning-1) = TCNTO0;            
        IO_State=IO_State?0:1;
            if (Learning > IR_NUM_MAX){
                wake_up_interruptible(&Wait_Study);
            }
            else{
                TCON = TCON & ~(0x1f << 0) | 0x2;
                TCON = TCON & ~(0x1f << 0) | 0x1;
                Learning++;
            }
   }
    }   
    set_gpio_ctrl(GPIO_F0 | GPIO_PULLUP_DIS | GPIO_MODE_EINT); //EINT0
}
static ssize_t IR_Study(struct file *filp, char *buf, size_t count, loff_t *f_pos){
    int ret, i;
    unsigned short * Study_Buf;
    if ((count < IR_NUM_MIN*2) || (count > 256)){
        printk("<1> buf size invalidation\n");
        return -EINVAL;
    }
if (!(Study_Buf = kmalloc(count, GFP_KERNEL))){
        printk("<1> kmalloc fail\n");
        return -EINVAL;
    }

ret

=

request_irq(IRQ_IRInput,

IRInput_irq_handle,

SA_INTERRUPT,

DEVICE_NAME"IRQ_EINT0", Study_Buf);
    if (ret != 0){
        printk("<1> IR busy\n");
        kfree(Study_Buf);
        return -EBUSY;
    }
    ret        =        request_irq(IRQ_TIMER0,
DEVICE_NAME"IRQ_TIMER0_Study", NULL);
    if (ret != 0){
        printk("<1> IR busy\n");
        kfree(Study_Buf);
        free_irq(IRQ_IRInput, Study_Buf);
    }
    Learning = 0;










timer0_Study_irq_handle,










SA_INTERRUPT,

    set_gpio_ctrl(GPIO_F0 | GPIO_PULLUP_DIS | GPIO_MODE_EINT);
    interruptible_sleep_on_timeout(&Wait_Study, Wait_Time);





    free_irq(IRQ_IRInput, Study_Buf);
    free_irq(IRQ_TIMER0, NULL);
    if (Learning > IR_NUM_MIN){
/*               for (i = 0; i < Learning - 1; i++)
        {
            if (!(i%10)) printk("\n<1>");
            printk("%04x,", *(Study_Buf+i));
        }
        printk("\nLearning is %d\n", Learning);*/
        copy_to_user(buf, Study_Buf, (ret = (Learning - 1) * 2));  
    }
    else{
        ret = 0;
    }
    kfree(Study_Buf);
//    free_irq(IRQ_IRInput, Study_Buf);
//    free_irq(IRQ_TIMER0, NULL);
    return ret;
}
static ssize_t IR_Transmit(struct file *filp, const char *buf, size_t count, loff_t *f_pos){
    int ret;
    unsigned short * Transmit_Buf;
    if ((count < IR_NUM_MIN*2) || (count > 256)){
        printk("<1> buf size invalidation\n");
        return -EINVAL;
    }
    if (!(Transmit_Buf = kmalloc(count, GFP_KERNEL))){
        printk("<1> kmalloc fail\n");
        return -EINVAL;  
    }
    copy_from_user(Transmit_Buf, buf, count);

    ret        =        request_irq(IRQ_TIMER0,        timer0_Transmit_irq_handle,
DEVICE_NAME"IRQ_TIMER0", Transmit_Buf);
    if (ret != 0){
      printk("<1> IR busy\n");
        kfree(Transmit_Buf);  
        return -EBUSY;
    }

SA_INTERRUPT,

    ret = request_irq(IRQ_TIMER1, pwm_irq_handle, SA_INTERRUPT, DEVICE_NAME"IRQ_TIMER1",
NULL);
    if        (ret != 0){
         printk("<1> IR busy\n");
        kfree(Transmit_Buf);
     free_irq(IRQ_TIMER0, Transmit_Buf);





        return -EBUSY;
    }
    Transmit_flag = 1;
    PWMEn = 1;
    TLen = count/2;
    TCNTB0 = 0xffff - *Transmit_Buf;
    Transmit_Index = 1;
    TCON = (TCON & 0xffffff0) | 0x2;         //Update TCNTB0, TCMPB0
    TCON = (TCON & 0xffffff0) | 0x1;         //Start for Timer 0
    TCON = (TCON & 0xffff0ff) | 0xa00;   
//Timer1:auto reload; Inverter off; Update TCNTB1,TCMPB1; Stop
    TCON = (TCON & 0xffff0ff) | 0x900;       //Start for Timer 1
    interruptible_sleep_on_timeout(&Wait_Transmit,20);//9+4.5+2.24*32+0.56=85.74
    TCON &= 0xffff000;
    free_irq(IRQ_TIMER0, Transmit_Buf);
    free_irq(IRQ_TIMER1, NULL);
    kfree(Transmit_Buf);
    return count;
}
static int IR_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long
arg){
    static unsigned char channel = 0;
    if (arg < 4){
        switch (cmd){
            case 0:   
channel &= ~(0x1 << arg);
                    break;
            case 1:
   channel |= (0x1 << arg);
                    break;
case 2:  
  channel = 0;
         break;
            case 3:
   channel = 0xf;
                    break;
            default:
                    break;        
        }
        writeb(channel, vIR_ADDR);
    }
}
static struct file_operations IR_fops = {
    owner:THIS_MODULE,




    write:IR_Transmit,
    read: IR_Study,
    ioctl:IR_ioctl,
};
static devfs_handle_t devfs_handle;
static int __init IR_init(void){
    devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, BUZZ_MAJOR, 0,
S_IFCHR | S_IRUSR | S_IWUSR, &IR_fops, NULL);
    set_gpio_ctrl(GPIO_B1 | GPIO_PULLUP_DIS | GPIO_MODE_TOUT);//TOUT1
    set_external_irq(IRQ_IRInput, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);
    TCFG0 |= TCFG0_PRE0(1);                    //Timer0,1 prescale value = 1
    TCFG1 = TCFG1 & (~(0xff << 0)) | (0x2 << 0) | (0x2 << 4);
//Timer0,1 divider value = 8, 50MHz/(1+1)/8=3.125MHz
TCNTB0 = 0xffff;                           //21ms
    TCNTB1 = 0x52;                             //3.125MHz/38K=82=0x52;  
    TCMPB1 = 0x29;                                    //0x52/2=0x29
    TCON &=  ~(0xfff << 0);                    //Timer0,1 Stop
    Learning = 0;
    Transmit_flag = 0;
    PWMEn = 0;
    vIR_ADDR = ioremap(pIR_ADDR, 1);
    printk(KER        F        DEVICE_NAME ": init        OK\n");
    return(0);  
}
static void __exit IR_cleanup(void){
    iounmap(vIR_ADDR);
    devfs_unregister(devfs_handle);
}
module_init(IR_init);
module_exit(IR_cleanup);
MODULE_LICENSE("GPL");


3.驱动测试程序


#include
#include
#include
#include
#include
int main(int argc,char *argv[]){
    int fd, IR_fd;
    int ret, i;
    unsigned short buf[100], TBuf[100];
    fd = open("/dev/PGM_IR", O_RDWR);




    if (fd < 0){
        perror("open PGM_IR fail");
        exit(1);
    }
    ioctl(fd, 3, 0);
    if (argc == 2){
        IR_fd = open("/tmp/IR_fd0", O_RDONLY);
        if (IR_fd < 0){
            perror("open IR_fd0");
        }
        else{
            ret = read(IR_fd, TBuf, sizeof(TBuf));
            if (ret > 0){
                for (i = 0; i < ret/2; i++){
  if (!(i%10)) printf("\n");
                    printf("%04x,", TBuf);
                }
            }
            write(fd,        TBuf, ret);
        }
    }
    ret = read(fd, buf, sizeof(buf)) / 2;
    if (ret > 0){
        for (i = 0; i < ret; i++){
          if (!(i%10)){
                printf("\n");
            }
            printf("%04x,", buf);
        }
        IR_fd = creat("/tmp/IR_fd0", O_RDWR);
        if (IR_fd > 0){
            printf("creat IR_fd sucess\n");
            write(IR_fd, buf, sizeof(short) * ret);
        }
      else{
            perror("IR_fd");
        }
    }
    else{
        perror("read PGM_IR");
    }
    close(fd);
    return 0;
}




测试方法:
1> 测试红外学习时直接运行可执行文件即可,然后按住红外遥控,学习完后,将打印出红外学习数据,
然后创建"IR_fd0"文件,将数据保存。
2> 测试红外发射,在执行文件时,需给传送任一参数,如"# ./IR_test 1"。它将 IR_fd0 中的红外
数据发射出去。


4.出现的问题







"



request_irq(IRQ_TIMER0,



timer0_Transmit_irq_handle,



SA_INTERRUPT,

DEVICE_NAME"IRQ_TIMER0", Transmit_Buf);"申请中断时,但用"free_irq(IRQ_TIMER0, NULL);"不能
释放中断(可用"#cat /proc/interrupts"命令观察)。
必须使 free_irq 中的 dev_id 参数与 request_irq 中的该参数保持一至,即:free_irq(IRQ_TIMER0,
Transmit_Buf);


5.总结


此驱动与上面几个驱动有几点不同,主要表现在对中断的处理
1> 申请中断和释放中断都直接在 read(红外学习)、write(红外发射)系统函数里完成。原因主要考虑
到红外学习与发射都需要阻塞等待(sleep_on 的系列函数),但在阻塞的过程中又不允许其它进程也对红外
进行操作(因为它们都占用了相同的硬件资源,如定时器 0 等)。所以为了实现红外驱动的互斥,当进行应
用用户调用红外学习或发射时才申请中断,如果中断申请失败,说明已被占用,则出错退出。
2>  同 一 中 断 有 两 个 不 同 的 中 断 处 理 程 序 。 红 外 学 习 时 , 调 用 request_irq(IRQ_TIMER0,
timer0_Study_irq_handle, SA_INTERRUPT, DEVICE_NAME"IRQ_TIMER0_Study", NULL); 红 外 发 射 时 调 用
request_irq(IRQ_TIMER0, timer0_Transmit_irq_handle, SA_INTERRUPT, DEVICE_NAME"IRQ_TIMER0",
Transmit_Buf);这样比共用一个处理程序的可读性和效率更高。
3> 在申请中断时 request_irq 中的 void *dev_id 参数作为私有数据(红外数据指针)传递给中断处
理程序的该参数,参考上面各中断处理程序。




[/code]

qn1512443998

0个粉丝

4

问答

0

专栏

1

资料

qn1512443998 2017-12-17 10:10:57
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=82097&ptid=38438]ngswfx 发表于 2017-12-14 08:41[/url]
你是想通过3516去控制别的设备还是接受控制,如果是接受控制,这个海斯应该有,如果想控制别的设备,估计要 ...[/quote]

您好,感谢您的回复,海思里面的驱动是有write但是他的定时器都是毫秒级别的 红外i发送数据需要至少微妙级别的,不太够用,现在还在弄,如果成功了我会分享出来,同时看看大家有没有可以参考的实现了的,共同学习

qn1512443998

0个粉丝

4

问答

0

专栏

1

资料

qn1512443998 2017-12-17 12:35:14
认可0
今天参考了别人的代码暂时搞好了 高精度定时器的方案没搞定,用的是内核的延迟函数 忙等 ,大家有更好的实现方法可以发出来共同学习,参考的链接地址http://blog.csdn.net/zhangkun_share/article/details/47101929

qn1512443998

0个粉丝

4

问答

0

专栏

1

资料

qn1512443998 2017-12-12 22:50:38
认可0
顶一下:time:

hero

0个粉丝

1

问答

0

专栏

0

资料

hero 2017-12-13 08:19:11
认可0
:o:o:o:o:o:o:o

hero

0个粉丝

1

问答

0

专栏

0

资料

hero 2017-12-18 08:29:58
认可0
:victory::victory::victory::victory:学习下

anlmb

0个粉丝

1

问答

0

专栏

0

资料

anlmb 2017-12-18 09:30:06
认可0
支持,mark:)
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区