[PIC®/AVR®/dsPIC®产品] Microchip PIC16F877A MCU在按键控制LED和UART通信中的应用

[复制链接]
 楼主| Uriah 发表于 2024-10-11 13:33 | 显示全部楼层 |阅读模式

Microchip的MCU以其稳定性和多功能性在嵌入式开发领域享有很高的声誉,PIC16F877A作为其经典的8位MCU,广泛应用于家电控制、工业自动化和物联网等领域。本文将介绍PIC16F877A MCU在按键控制LED和UART通信中的应用,并提供相关代码实现。

PIC16F877A简介PIC16F877A是Microchip公司推出的一款高性能8位微控制器,基于RISC架构,指令执行速度快,内置多个外设,如ADC、串口、I2C、SPI等,具有较大的RAM和EEPROM存储空间。该MCU主要适用于低功耗控制系统,支持多个中断源,适合需要实时响应的嵌入式应用。

硬件设计本应用场景包括以下硬件模块:
  • MCU型号:Microchip PIC16F877A
  • 功能模块:按键控制LED、串口通信
  • 开发环境:MPLAB X IDE + XC8编译器
应用目标是实现通过按键控制LED的亮灭,并通过UART将LED的状态信息发送至上位机进行调试。

代码实现以下代码展示了如何通过PIC16F877A控制GPIO口实现按键控制LED,以及通过UART发送状态信息。
  1. #include <xc.h>

  2. // 配置位设置
  3. #pragma config FOSC = HS   // 晶体振荡器
  4. #pragma config WDTE = OFF  // 关闭看门狗定时器
  5. #pragma config PWRTE = OFF // 关闭上电延时定时器
  6. #pragma config BOREN = ON  // 使能掉电复位
  7. #pragma config LVP = OFF   // 禁用低电压编程
  8. #pragma config CPD = OFF   // 关闭数据EEPROM的代码保护
  9. #pragma config WRT = OFF   // 禁用闪存写保护
  10. #pragma config CP = OFF    // 关闭程序存储器的代码保护

  11. #define _XTAL_FREQ 20000000  // 定义系统频率

  12. // 定义引脚
  13. #define LED_PIN PORTBbits.RB0   // LED连接到RB0引脚
  14. #define BUTTON_PIN PORTBbits.RB1 // 按键连接到RB1引脚

  15. // 函数声明
  16. void System_Init(void);
  17. void GPIO_Init(void);
  18. void UART_Init(void);
  19. void LED_Toggle(void);
  20. void UART_Write(char data);
  21. void UART_Write_String(char *str);

  22. void main(void)
  23. {
  24.     // 初始化系统
  25.     System_Init();
  26.     // 初始化GPIO
  27.     GPIO_Init();
  28.     // 初始化UART
  29.     UART_Init();
  30.    
  31.     // 主循环
  32.     while (1)
  33.     {
  34.         // 检测按键状态
  35.         if (BUTTON_PIN == 0) // 按键按下
  36.         {
  37.             __delay_ms(50); // 防抖延时
  38.             if (BUTTON_PIN == 0)
  39.             {
  40.                 // 切换LED状态
  41.                 LED_Toggle();
  42.                 // 通过串口发送LED状态信息
  43.                 UART_Write_String("LED Toggled!\r\n");
  44.                 // 等待按键释放
  45.                 while (BUTTON_PIN == 0);
  46.             }
  47.         }
  48.     }
  49. }

  50. // 系统初始化
  51. void System_Init(void)
  52. {
  53.     // 配置系统时钟
  54.     OSCCON = 0x71;  // 设置内部振荡器频率为8MHz
  55. }

  56. // GPIO初始化
  57. void GPIO_Init(void)
  58. {
  59.     TRISBbits.TRISB0 = 0;  // 配置RB0为输出引脚
  60.     TRISBbits.TRISB1 = 1;  // 配置RB1为输入引脚
  61.     LED_PIN = 0;           // 初始化LED状态为灭
  62. }

  63. // UART初始化
  64. void UART_Init(void)
  65. {
  66.     TRISCbits.TRISC6 = 0;  // 配置RC6为TX输出引脚
  67.     TRISCbits.TRISC7 = 1;  // 配置RC7为RX输入引脚
  68.    
  69.     // 配置波特率
  70.     SPBRG = 31;            // 设置波特率为9600(20MHz晶振)
  71.     TXSTAbits.BRGH = 1;    // 高波特率
  72.     RCSTAbits.SPEN = 1;    // 使能串口
  73.     TXSTAbits.TXEN = 1;    // 使能发送
  74.     RCSTAbits.CREN = 1;    // 使能接收
  75. }

  76. // LED状态切换
  77. void LED_Toggle(void)
  78. {
  79.     LED_PIN = ~LED_PIN;    // 切换LED状态
  80. }

  81. // 串口发送单字节
  82. void UART_Write(char data)
  83. {
  84.     while (!TXSTAbits.TRMT);  // 等待发送缓冲区空
  85.     TXREG = data;             // 发送数据
  86. }

  87. // 串口发送字符串
  88. void UART_Write_String(char *str)
  89. {
  90.     while (*str)
  91.     {
  92.         UART_Write(*str++);
  93.     }
  94. }
复制代码

代码说明
  • 系统初始化:通过System_Init()函数配置系统时钟,使MCU工作在合适的频率下。在本例中,我们使用20MHz的外部晶振。
  • GPIO初始化:通过GPIO_Init()函数,将RB0引脚配置为输出,用于控制LED的状态;RB1引脚配置为输入,用于检测按键状态。
  • 串口初始化:UART_Init()函数设置波特率为9600,串口使用RC6引脚作为发送(TX),RC7引脚作为接收(RX)。
  • 按键控制LED:在主循环中,检测按键按下时,调用LED_Toggle()函数切换LED的亮灭状态,并通过串口发送“LED Toggled!”的状态信息。
  • 防抖处理:在按键检测中,我们使用了一个简单的延时防抖,避免按键抖动引起误操作。
  • 串口通信:通过UART_Write()和UART_Write_String()函数,向上位机发送LED状态的文本信息,方便调试和状态反馈。


扩展功能
  • ADC应用:PIC16F877A带有10位ADC模块,可以通过ADC读取传感器数据,并通过UART发送至上位机进行监控。
  • PWM控制:可以通过配置CCP模块输出PWM信号,用于控制电机或调节LED的亮度。
  • 定时器中断:利用定时器中断来处理一些实时任务,例如定时采集数据或控制定时闪烁。
  • I2C通信:PIC16F877A支持I2C通信,可以扩展I2C设备,如EEPROM、温湿度传感器等。


总结Microchip的PIC16F877A MCU在嵌入式系统中应用广泛,其丰富的外设资源和较高的性价比,使其成为许多中小型嵌入式项目的首选。本篇文章通过按键控制LED和串口通信的代码示例,展示了如何使用该MCU进行简单的控制与通信。随着项目的复杂度提升,可以进一步利用PIC16F877A的其他功能模块实现更多的应用场景。

 楼主| Uriah 发表于 2024-10-11 13:33 | 显示全部楼层
我刚好手头有个PIC16F877A的开发板,可以直接跟着你这个代码做实验了。
周半梅 发表于 2024-10-11 13:34 | 显示全部楼层
串口通信这一块解释得挺清楚,学到了不少。
公羊子丹 发表于 2024-10-11 13:34 | 显示全部楼层
你这防抖处理虽然简单,但对很多项目来说已经够用了。
帛灿灿 发表于 2024-10-11 13:34 | 显示全部楼层
我之前没用过Microchip的MCU,看完感觉挺容易上手的。
童雨竹 发表于 2024-10-11 13:34 | 显示全部楼层
我觉得用这个PIC16F877A来做家电控制是个不错的选择。
Wordsworth 发表于 2024-10-11 13:35 | 显示全部楼层
PWM调光可以再试一下,毕竟现在很多地方都用到这个。
Pulitzer 发表于 2024-10-11 13:35 | 显示全部楼层
你提到的定时器中断功能很实用,我可以试着加到我的项目中。
Bblythe 发表于 2024-10-11 13:35 | 显示全部楼层
这个代码挺简洁的,没想到可以实现这么多功能。
Clyde011 发表于 2024-10-11 13:35 | 显示全部楼层
能不能再加个I2C通信的例子?我项目里用到这块比较多。
Bblythe 发表于 2024-10-11 13:36 | 显示全部楼层
这篇文章对我帮助很大,特别是串口调试那部分!
antusheng 发表于 2024-11-24 19:25 | 显示全部楼层
这寄存器操作的技术一流。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

139

主题

5850

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部