51单片机IO口能做实参传递吗

比如我是否能写一个模拟pwm功能的函数,
void pwm_io(形参port,形参bit)
{
xxxxxxxxxxxx /*PWM操作*/
}
然后把想需要启动pwm功能的IO口直接调用pwm_io函数,把io口直接传递进去?
例如:
pwm_io(P1,3);这样是否能正确操作P13口启动PWM?如果可以,我上面定义函数
的port跟bit的类型又应该是什么?

可以的,但是一般性不这么用,不是所有的编译器都支持sfr(本质是地址)的传递。

你可以使用这样的东西:(这是我写的AVR类库)

void SETB(PORT port,unsigned char bit);//其他的源代码举一反三吧

记得定义:

#define PORT enum PORT
//方便输入
#define setb SETB
#define clrb CLRB
#define getb GETB
    PORT{
        PA,
        PB,
        PC,
        PD
    };

Port和bit的本质都是寄存器,一个是byte寻址一个是bit寻址而已,千万不要以为bit寻址就一定快,往往是byte要快一些。

附上源代码:

gpio.h

#ifndef AVR_GPIO_H
#define AVR_GPIO_H
#define PORT enum PORT
//方便输入
#define setb SETB
#define clrb CLRB
#define getb GETB
    PORT{
        //PA,
        PB,
        PC,
        PD
    };
    extern void SETB(PORT port,unsigned char bit);
    //相应端口置1,并设置为输出
    extern void CLRB(PORT port,unsigned char bit);
    //相应端口置0,并设置为输出
    extern unsigned char GETB(PORT port,unsigned char bit);
    //相应端口设置为输入并读取,返回0xff(1)与0x00(0),异常返回0xf0
    extern void SETD(PORT port,unsigned char bit);
    //相应端口设置为输出
    extern void CLRD(PORT port,unsigned char bit);
    //相应端口设置为输入
#endif

gpio.c

#include"inc.h"

void SETB(PORT port,unsigned char bit){
    if(bit<=7){
        switch(port){
            //case PA:
            //DDRA|=(1<<bit);
            //PORTA|=(1<<bit);
            //break;
            //use in Mega16
            case PB:
                DDRB|=(1<<bit);
                PORTB|=(1<<bit);
                break;
            case PC:
                DDRC|=(1<<bit);
                PORTC|=(1<<bit);
                break;
            case PD:
                DDRD|=(1<<bit);
                PORTD|=(1<<bit);
                break;
        }
    }
}

void CLRB(PORT port,unsigned char bit){
    if(bit<=7){
        switch(port){
            //case PA:
            //DDRA&=(1<<bit);
            //PORTA&=(0xff-(1<<bit));
            //break;
            //use in Mega16
            case PB:
                DDRB|=(1<<bit);
                PORTB&=(0xff-(1<<bit));
                break;
            case PC:
                DDRC|=(1<<bit);
                PORTC&=(0xff-(1<<bit));
                break;
            case PD:
                DDRD|=(1<<bit);
                PORTD&=(0xff-(1<<bit));
                break;
        }
    }
}

unsigned char GETB(PORT port,unsigned char bit){
    unsigned return_value=0;
    if(bit<=7){
        switch(port){
            //case PA:
            //DDRA|=(0xff-(1<<bit));
            //return_value=PINA&(1<<bit);
            //break;
            //use in Mega16
            case PB:
                DDRB|=(0xff-(1<<bit));
                return_value=PINB&(1<<bit);
                break;
            case PC:
                DDRC|=(0xff-(1<<bit));
                return_value=PINC&(1<<bit);
                break;
            case PD:
                DDRD|=(0xff-(1<<bit));
                return_value=PIND&(1<<bit);
                break;
        }
        if(return_value==0){
            return(0x00);
        }else{
            return(0xff);
        }
    }
    return(0xf0);
}

void SETD(PORT port,unsigned char bit){
    if(bit<=7){
        switch(port){
            //case PA:
                //DDRA|=(1<<bit);
                //break;
            //use in Mega16
            case PB:
                DDRB|=(1<<bit);
                break;
            case PC:
                DDRC|=(1<<bit);
                break;
            case PD:
                DDRD|=(1<<bit);
                break;
        }
    }
}

void CLRD(PORT port,unsigned char bit){
    if(bit<=7){
        switch(port){
            //case PA:
            //DDRA|=(0xff-(1<<bit));
            //break;
            //use in Mega16
            case PB:
                DDRB|=(0xff-(1<<bit));
                break;
            case PC:
                DDRC|=(0xff-(1<<bit));
                break;
            case PD:
                DDRD|=(0xff-(1<<bit));
                break;
        }
    }
}

温馨提示:内容为网友见解,仅供参考
第1个回答  2014-01-24
IO口当然可以,只是IO口输入/输出设定及一些PULL HIGH电阻..等相关寄存器也要一并处理。
PWM的周期控制也要处理好。
pwm_io(P1,3),这个函数的内容要先写好,P1 (unsigned char) 3 (unsigned char)
函数内在根据第二个参数,对应到相关的bit即可。
第2个回答  2014-01-24
对于io口的操作可以用宏的,函数调用太慢影响实时性

51单片机IO口能做实参传递吗
可以的,但是一般性不这么用,不是所有的编译器都支持sfr(本质是地址)的传递。你可以使用这样的东西:(这是我写的AVR类库)void SETB(PORT port,unsigned char bit);\/\/其他的源代码举一反三吧记得定义:define PORT enum PORT\/\/方便输入#define setb SETB#define clrb CLRB#define getb GETB ...

51单片机端口能否作为实参传递给函数。 比如: 定义函数: void dnl(b...
define LED1_ON P1_1=0;#define LED1_OFF P1_1=1;void main(){ LED1_ON;}

51单片机在使用键盘时(比如独立键盘)怎么设置“清除”键
先根据你要显示数字的个数定义一个unsigned char型的字符数组,调用扫描键盘函数,扫描到哪个键被按下的同时将键值存进对应的数组元素中,再调用液晶显示程序显示,液晶显示程序中显示的位数可变,可以定义一个变量来记录已按下的位数,显示的程序中实参为已按下按键的个数,这样就能实时显示数字了。

dvb-s 芯片有哪些?其优点和缺点?
当装配到笔记本电脑或多媒体计算机中时,新型 TFDU7100 可实现多个功能,包括遥控视频或音乐播放,以及图片、MP3 及其它文件格式的无线共享。通过将所有这些功能整合到一个封装中,TFDU7100 可使 PC 机架设计人员限制日光过滤窗口的数目,从而避免遥控器与 IrDA 功能之间的权衡。TFDU7100 的 8 引脚封装整合...

相似回答