国芯人工智能 发表于 6 天前

【国芯人工智能官方回复】

尊敬的用户,感谢您对Ai8051U系列单片机的关注与学习。在第六集“I/O输入输出”中,我们深入讲解了GPIO(通用输入输出)的基本概念及其四种工作模式,包括准双向口、推挽输出、高阻输入和开漏模式,并结合实际代码演示了按键输入检测与控制逻辑的应用。以下是对本节内容的专业解析与补充说明:

一、GPIO基础概念
GPIO是微控制器中最基础且最重要的外设之一,用于实现与外部设备的交互。通过配置不同的引脚模式,GPIO可以灵活地支持输入、输出或双向通信功能。其核心特性在于能够根据程序指令动态调整引脚状态,从而实现对外部信号的采集或控制。

二、GPIO四种工作模式详解
1. 准双向口:适用于简单输入/输出场景,引脚可读写,但需配合外部上拉电阻使用,常用于按键检测等应用。
2. 推挽输出:具有强驱动能力,能同时输出高、低电平,适用于需要较高电流驱动的场合,如LED控制。
3. 高阻输入:引脚处于高阻态,相当于断开连接,用于防止信号干扰或作为输入引脚使用。
4. 开漏模式:输出端为开漏结构,需外接上拉电阻才能正常工作,适用于I²C等通信协议。

三、拉电流与灌电流的理解
拉电流:指从外部电路向芯片内部提供电流,通常发生在引脚输出高电平时。
灌电流:指从芯片内部向外部电路提供电流,通常发生在引脚输出低电平时。
理解这两种电流特性有助于合理设计外围电路,避免因电流过大导致器件损坏。

四、按键输入检测逻辑分析
在视频中,我们通过三个任务演示了按键控制的不同逻辑实现:

任务1:按下灯亮,松开灯灭
c
if(P32 == 0)
{
    P00 = 0; // 按键按下时点亮LED
}
else
{
    P00 = 1; // 松开后熄灭LED
}
此逻辑基于按键按下时引脚为低电平,通过直接控制LED状态实现即时响应。

任务2:松开灯亮,按下灯灭
c
if(P32 == 1)
{
    P00 = 0; // 松开按键时点亮LED
}
else
{
    P00 = 1; // 按下时熄灭LED
}
该逻辑将按键状态与LED状态反向关联,适用于某些特定应用场景。

任务3:按一下灯亮,按一下灯灭(状态翻转)
c
if(P32 == 0)
{
    state = !state; // 状态翻转
    P00 = state;   // 更新LED状态
}
此逻辑引入了一个状态变量state,实现按键一次触发一次状态切换,适用于需要双击或连续控制的场景。

五、代码对比与优化建议
任务1与任务2:仅改变了判断条件,体现了不同逻辑需求下的编程思路。
任务3:通过状态变量实现更复杂的功能,适合需要持续状态记忆的应用。

在实际开发中,建议对按键进行去抖处理,以提高系统稳定性。可通过软件延时或硬件滤波方式实现。

六、总结
第六集围绕GPIO的核心功能展开,帮助开发者掌握基本输入输出操作及常见应用场景。后续第七集将继续探讨定时器、中断等高级功能,敬请期待。

如您在学习过程中遇到任何技术问题,欢迎随时联系国芯人工智能技术支持团队,我们将竭诚为您服务。

——国芯人工智能技术团队

[本文内容由国芯人工智能辅助生成,仅供参考]

zhangguilin 发表于 6 天前

西西研究员 发表于 2025-8-28 15:35
请您后续在同一条帖子下,不同楼层回复内容哈,以便于我们审查

zhangguilin 发表于 前天 09:57

#include "config.h"                  

void main(void)
{
   
    SYS_Init();
    while (1)
    {
      
                        printf_usb("Hello World !\r\n");

      
    }
}

void SYS_Init(void)
{
    EnableAccessXFR();
    IAP_SetTimeBase();                  

    P0M0 = 0x00; P0M1 = 0x00;         
    P1M0 = 0x00; P1M1 = 0x00;         
    P2M0 = 0x00; P2M1 = 0x00;         
    P3M0 = 0x00; P3M1 = 0x00;         
    P4M0 = 0x00; P4M1 = 0x00;         
    P5M0 = 0x00; P5M1 = 0x00;         
    P6M0 = 0x00; P6M1 = 0x00;         
    P7M0 = 0x00; P7M1 = 0x00;         

    delay_ms(1);
    USBLIB_Init();                     
    delay_ms(1);
      
    EnableGlobalInt();               
}

void delay_us(uint16_t us)
{
    do
    {
      NOP(14);                     
    } while (--us);
}
void delay_ms(uint16_t ms)
{
    uint16_t i;

    do
    {
      i = MAIN_Fosc / 10000;
      while (--i);
    } while (--ms);
}


void USBLIB_Init(void)
{
    usb_init();                        
    USB_SetIntPriority(0);            
    set_usb_ispcmd("@STCISP#");         

}

void USBLIB_WaitConfiged(void)
{
    while (DeviceState != DEVSTATE_CONFIGURED)
      WDT_Clear();                  
}

void USBLIB_OUT_Done(void)
{
    if (bUsbOutReady)                  
    {
      USB_SendData(UsbOutBuffer, OutNumber);
      
      usb_OUT_done();               
    }
}实验1代码和图片


zhangguilin 发表于 前天 10:03

实验2代码和图片

#include "config.h"                  
void main(void)
{
   
    SYS_Init();

    while (1)
    {
      USBLIB_OUT_Done();            
    }
}


void SYS_Init(void)
{
    EnableAccessXFR();                  
    IAP_SetTimeBase();                  

    P0M0 = 0x00; P0M1 = 0x00;         
    P1M0 = 0x00; P1M1 = 0x00;      
    P2M0 = 0x00; P2M1 = 0x00;      
    P3M0 = 0x00; P3M1 = 0x00;      
    P4M0 = 0x00; P4M1 = 0x00;      
    P5M0 = 0x00; P5M1 = 0x00;      
    P7M0 = 0x00; P7M1 = 0x00;         

    delay_ms(1);
    USBLIB_Init();                     
    delay_ms(1);



    EnableGlobalInt();               
}

void delay_us(uint16_t us)
{
    do
    {
      NOP(14);                        
    } while (--us);
}



void delay_ms(uint16_t ms)
{
    uint16_t i;

    do
    {
      i = MAIN_Fosc / 10000;
      while (--i);
    } while (--ms);
}

void USBLIB_Init(void)
{
    usb_init();                        
    USB_SetIntPriority(0);            
    set_usb_ispcmd("@STCISP#");      

}


void USBLIB_WaitConfiged(void)
{
    while (DeviceState != DEVSTATE_CONFIGURED)
      WDT_Clear();                  
}


void USBLIB_OUT_Done(void)
{
    if (bUsbOutReady)                  
    {
      
                        if (UsbOutBuffer == 6)
                                        printf_usb("Hello World !\r\n");
                        else if (UsbOutBuffer == 7)
                                        printf_usb("China !\r\n");
      usb_OUT_done();               
    }
}

zhangguilin 发表于 前天 10:16

实验3代码和图片

#include "config.h"                     
void main(void)
{
    SYS_Init();
    while (1)
    {

    }
}


void SYS_Init(void)
{
    EnableAccessXFR();                  
    IAP_SetTimeBase();               

    P0M0 = 0x00; P0M1 = 0x00;         
    P1M0 = 0x00; P1M1 = 0x00;         
    P2M0 = 0x00; P2M1 = 0x00;         
    P3M0 = 0x00; P3M1 = 0x00;         
    P4M0 = 0x00; P4M1 = 0x00;         
    P5M0 = 0x00; P5M1 = 0x00;         
    P6M0 = 0x00; P6M1 = 0x00;         
    P7M0 = 0x00; P7M1 = 0x00;         

    delay_ms(1);
    USBLIB_Init();                     
    delay_ms(1);

    EnableGlobalInt();                  
}
void delay_us(uint16_t us)
{
    do
    {
      NOP(14);                     
    } while (--us);
}

void delay_ms(uint16_t ms)
{
    uint16_t i;

    do
    {
      i = MAIN_Fosc / 10000;
      while (--i);
    } while (--ms);
}

void USBLIB_Init(void)
{
    usb_init();                        
    USB_SetIntPriority(3);            
    set_usb_OUT_callback(USBLIB_OUT_Callback);
    set_usb_ispcmd("@STCISP#");      

}


void USBLIB_WaitConfiged(void)
{
    while (DeviceState != DEVSTATE_CONFIGURED)
      WDT_Clear();                  
}

void USBLIB_OUT_Callback(void)
{
                if (UsbOutBuffer == 6)
      printf_usb("Hello World !\r\n");      
    else if (UsbOutBuffer == 7)
      printf_usb("China !\r\n");               
}


页: 1 [2]
查看完整版本: Ai8051U第一集序言