隐约 发表于 2025-9-30 10:11:20

求各位大神一个代码,串口控制IO口翻转

#include <reg52.h>
#include <intrins.h>

#define FOSC 11059200L      // 晶振频率
#define BAUD 9600         // 波特率

/* 串口初始化函数 */
void UART_Init(void)
{
    SCON = 0x50;      // 8位数据,可变波特率
    TMOD &= 0x0F;       // 清除定时器1模式位
    TMOD |= 0x20;       // 设定定时器1为8位自动重装方式
    TL1 = 0xFD;         // 设定定时初值
    TH1 = 0xFD;         // 设定定时器重装值
    ET1 = 0;            // 禁止定时器1中断
    TR1 = 1;            // 启动定时器1
    EA = 1;             // 开启总中断
    ES = 1;             // 开启串口中断
}

/* 主函数 */
void main(void)
{
    UART_Init();
    P0 = 0xFF;          // 初始化P0口,LED全灭
    P1 = 0xFF;          // 初始化P1口,LED全灭

    while(1)
    {
      // 主循环保持空转,等待串口中断
    }
}

/* 串口中断服务函数 */
void UART_Isr(void) interrupt 4
{
    unsigned char received_char;

    if (RI)
    {
      RI = 0;                     // 清除接收中断标志位
      received_char = SBUF;       // 读取接收到的字符

      // 直接在中断函数中处理,避免函数调用问题
      if(received_char >= '0' && received_char <= '9')
      {
            unsigned char led_index = received_char - '0';
            if(led_index < 8)
            {
                P0 ^= (1 << led_index);   // 翻转P0口的LED
            }
            else
            {
                P1 ^= (1 << (led_index - 8)); // 翻转P1口的LED
            }
      }
      else if(received_char >= 'A' && received_char <= 'F')
      {
            unsigned char led_index = received_char - 'A' + 10;
            P1 ^= (1 << (led_index - 8));   // 翻转P1口的LED
      }
      else if(received_char >= 'a' && received_char <= 'f')
      {
            unsigned char led_index = received_char - 'a' + 10;
            P1 ^= (1 << (led_index - 8));   // 翻转P1口的LED
      }
    }
}

这是一个串口控制IO口的引脚,单片机型号为STC89C52
当串口发送01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F是分别控制了P0.1-0.7,P1.0-1.6的IO口翻转,当串口发送10时,P1.7IO口应该翻转的,但是单片机没有任何反应

求各位大神给一个代码能够实现当串口发送01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18
分别控制P0,P1,P2口的24个IO口状态翻转

国芯人工智能 发表于 2025-9-30 10:12:00

你提供的代码是一个基于 8051 内核的单片机(如 STC 系列)的串口通信框架,当前已经完成了串口初始化、主函数初始化 IO 口以及中断服务函数的框架。你的需求是通过串口发送特定指令控制 IO 口(例如 P0 或 P1)的翻转(即高低电平切换)。下面我将为你补充完整的串口控制 IO 翻转的代码,并进行详细说明。

✅ 一、功能需求说明

你希望通过串口接收字符(如 'A'、'B'、'0'、'1'等),根据接收到的指令控制某个 IO 口(如 P0、P1)的电平翻转,例如:
接收到字符 'P',翻转 P0 口;
接收到字符 'Q',翻转 P1 口;
或者接收到 '0' 和 '1' 来控制某个特定 IO 的高低电平。

✅ 二、补充完整代码

以下是完整可运行的代码,基于你提供的框架,补充了串口接收处理和 IO 控制逻辑:

```c
include
include

define FOSC 11059200L      // 晶振频率
define BAUD 9600         // 波特率

// 串口初始化函数
void UARTInit(void)
{
    SCON = 0x50;      // 8位数据,可变波特率
    TMOD &= 0x0F;       // 清除定时器1模式位
    TMOD |= 0x20;       // 设定定时器1为8位自动重装方式
    TL1 = 0xFD;         // 设定定时初值(对应9600波特率)
    TH1 = 0xFD;         // 设定定时器重装值
    ET1 = 0;            // 禁止定时器1中断
    TR1 = 1;            // 启动定时器1
    EA = 1;             // 开启总中断
    ES = 1;             // 开启串口中断
}

// 主函数
void main(void)
{
    UARTInit();
    P0 = 0xFF;          // 初始化P0口,LED全灭(共阳)
    P1 = 0xFF;          // 初始化P1口,LED全灭

    while(1)
    {
      // 主循环保持空转,等待串口中断
    }
}

// 串口中断服务函数
void UARTIsr(void) interrupt 4
{
    unsigned char receivedchar;

    if (RI)             // 接收中断标志
    {
      RI = 0;         // 清除接收中断标志
      receivedchar = SBUF;// 读取接收到的字符

      // 根据接收到的字符控制IO口
      switch (receivedchar)
      {
            case 'P':   // 控制P0口翻转
                P0 = ~P0;
                break;
            case 'Q':   // 控制P1口翻转
                P1 = ~P1;
                break;
            case '0':   // 设置P0.0为低电平
                P0 &= ~(1

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

网老四 发表于 2025-9-30 18:45:30

估计接收解析把十六进制数据还是ascii码数据搞混了
发送的是十六进制,解析时候按照ascii码值判断
页: [1]
查看完整版本: 求各位大神一个代码,串口控制IO口翻转