当前位置: 首页 > 工具软件 > i51 > 使用案例 >

51单片机第一讲(I/O口)

南宫俊喆
2023-12-01

1.LED基本操作
当LED端口置低电平时LED点亮(有的单片机是置高电平点亮,根据单片机原理图进行判断)
点亮8个LED(接单片机P1口)

void bsp_LedOn(void)
{
    P1 = 0X00;
}

熄灭8个LED

void bsp_LedOff(void)
{
    P1 = 0xff;
}

流水灯操作

unsigned char i = 0;
unsigned char temp = 0;
void bsp_LedBlink(unsigned char dir, unsigned char speed)//第一个参数控制方向,第二个参数控制速度
{
    if(i == 0)
    {
        if(dir == 0)
        {
            temp = 0x7f;
        }
        else
        {
            temp = 0xfe;
        }
    }

    if(i > 0)
    {
        if(dir == 0)
        {
            temp = temp>>1 | 0x80;
        }
        else
        {
            temp = temp<<1 | 0x01;
        }
    }
    LEDPORT = temp;
    delay_ms(speed * 5);
    i++;
    if(i == 8)
    {
        i = 0;
    }   
}

2.独立键盘基本操作
当按键被按下,即给I/O口赋一个低电平,独立按键即被按下。

sbit K1 = P0^0;
sbit K2 = P0^1;

unsigned char keyvalue = 0;

void bsp_KeyScan(void)
{
    if(K1 == 0)//K1按键被按下
    {
        keyvalue = 1;
    } 

    if(K2 == 0)//K2按键被按下
    {
        keyvalue = 2;
    }
}

//按键的消抖
void bsp_KeyScan(void)
{
    if(K1 == 0)//K1按键被按下
    {
        delay_ms(10);    //按键消抖
        if(K1 == 0)//确认按键被按下
        {
            keyvalue = 1;
            while(!K1);//只有当按键K1被松掉时才退出
        }
    } 

    if(K2 == 0)
    {
        delay_ms(10);
        if(K2 == 0)
        {
            keyvalue = 2;
            while(!K2);
        }
    }
}

用按键控制流水灯的方向:

void main()
{
    unsigned int time  = 0;
    bsp_init();
    while(1)
    {
        bsp_KeyScan();
        if(time == 10000)
        {
            if(keyvalue == 1)
            {
                bsp_LedBlink(0, 1);
            }
            if(keyvalue == 2)
            {
                bsp_LedBlink(1, 1);
            }
            time = 0;
        }
        time++;
    }
}

3.数码管的基本操作
数码管,根据内部结构,可分为共阴极数码管和共阳极数码管。七段发光管加上一个小数点,共计8段。因此我们对它编码时,刚好是用一个字节。
共阳数码管:

unsigned char code TableCA[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳数码管段选码表,无小数点
unsigned char code TableCA[16]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};//共阳数码管段选码表,有小数点
void ShowSegCA(unsigned char t)
{
    P1 = TableCA[t];    
}

void main()
{
    unsigned char i = 0;
    unsigned char j = 0;
    unsigned char status = 0;
    unsigned char flag = 0;
    bsp_init();
    while(1)
    {
         bsp_KeyScan();
         ShowSegCA(i);
         if(keyvalue == 1)
         {
            flag = 1;
            status = !status;
            keyvalue = 0;
         }
         if(flag == 1)
         {
             if(status == 0)
             {
                delay_ms(200);
                delay_ms(200);
                i++;
                if(i == 16)
                {
                    i = 0;
                }
             } 

             if(status == 1)
             {
                j = i;
                ShowSegCA(j);   
             }
        }

        if(keyvalue == 2)
        {
            i = i + 1;
            if(i == 16)
            {
                i = 0;
            }
            ShowSegCA(i);
            keyvalue = 0;
        }
    }
}

共阴数码管:

unsigned char code distab[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴数码管段选码表,无小数点
unsigned char code distab[16]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};//共阴数码管段选码表,有小数点
unsigned char code TableSel[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//共阴数码管位选码表

在使用数码管时需要先定义位选端口和段选端口,位选控制哪一个数码管是通的,段选控制数码管显示哪一个字符。
数码管的动态扫描:利用人眼的视觉停效应,当时间足够短,人眼分辨不出数码管在移动

void ShowSegCC(void)
    static unsigned char i = 0;

    WEI = 1;
    SEGPORT = TableSel[i];
    WEI = 0;

    DUAN = 1;
    SEGPORT = TableCC[i];
    DUAN = 0;

    i++;
    if(i == 8)
    {
        i = 0;
    }
    delay_ms(2);//通过改变延时来逼近人眼分辨不出的时刻
}
 类似资料: