找回密码
 立即注册
查看: 455|回复: 4

关于 8G1K08A-36I-SOP8 的P3.2模拟软件TX发送数据,P3.2没发正常进行发送

[复制链接]

2

主题

1

回帖

14

积分

新手上路

积分
14
发表于 2024-8-14 17:59:33 | 显示全部楼层 |阅读模式
#include <STC8G.H>  // 包含 STC8 系列单片机的头文件

// 定义引脚
sbit DAT_tx = P3^2;  // 定义引脚 P3.2 为模拟数据线

// 定义协议常量
#define FOSC        11059200UL  // 系统时钟频率
#define BAUD_RATE    115200     // 期望的波特率
#define BIT_TIME    (FOSC / (BAUD_RATE * 16)) // 每位的时间周期(16倍速)

#define TX_IDLE    0   // 空闲状态
#define TX_START   1   // 发送起始位状态
#define TX_DATA    2   // 发送数据位状态
#define TX_STOP    3   // 发送停止位状态

// 定义状态和缓冲区
bit busy;             // 发送状态标志
char tx_state;        // 当前发送状态
char tx_bit_count;    // 发送数据位计数
char tx_data;         // 待发送数据

// 定义需要发送的数据
const char tx_buffer[] = {0x55, 0x01, 0x01, 0xFF}; // 循环发送的数据
char tx_index = 0;    // 当前数据索引

// 定时器0中断服务程序
void Timer0_ISR() interrupt 1
{
    static unsigned char bit_time_count = 0;  // 位时间计数器

    bit_time_count++;  // 增加计数

    if (bit_time_count >= (BIT_TIME / 2))  // 每位时间的一半
    {
        bit_time_count = 0;  // 重置计数器

        switch (tx_state)
        {
            case TX_IDLE:
                if (busy)
                {
                    DAT_tx = 1;  // 空闲状态,TX线为高电平
                }
                break;

            case TX_START:
                DAT_tx = 0;  // 起始位,TX线为低电平
                tx_state = TX_DATA;  // 切换到数据位状态
                tx_bit_count = 8;    // 数据位计数器设置为8位
                break;

            case TX_DATA:
                DAT_tx = (tx_data & 0x01) ? 1 : 0;  // 发送数据位(最低有效位)
                tx_data >>= 1;  // 右移数据,准备发送下一个位
                tx_bit_count--;  // 数据位计数器递减
                if (tx_bit_count == 0)
                {
                    tx_state = TX_STOP;  // 数据位发送完毕,切换到停止位状态
                }
                break;

            case TX_STOP:
                DAT_tx = 1;  // 停止位,TX线为高电平
                tx_state = TX_IDLE;  // 切换到空闲状态
                busy = 0;  // 发送完成
                break;
        }
    }
}

void UartInit()
{
    // 配置定时器0为模式1(16位定时器)
    TMOD &= 0xF0;       // 清除定时器0的配置位
    TMOD |= 0x01;       // 设置定时器0为模式1
    TH0 = (65536 - (FOSC / (BAUD_RATE * 16))); // 计算定时器初值
    TL0 = TH0;          // 设置定时器低字节
    ET0 = 1;            // 使能定时器0中断
    TR0 = 1;            // 启动定时器0
    EA = 1;             // 开启全局中断

    tx_state = TX_IDLE; // 初始化状态为空闲状态
    busy = 0;           // 初始化为不忙碌
}

void UartSend(char dat)
{
    while (busy);  // 等待发送完成
    busy = 1;      // 设置为忙碌状态
    tx_data = dat; // 设置待发送数据
    tx_state = TX_START; // 开始发送数据
}

void main()
{
    // 配置所有端口为标准模式
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;

    UartInit(); // 初始化UART

    while (1)
    {
        UartSend(tx_buffer[tx_index]); // 发送当前数据
        tx_index++; // 增加数据索引
        if (tx_index >= sizeof(tx_buffer)) // 如果索引超出数据缓冲区大小
        {
            tx_index = 0;  // 重置索引以循环发送
        }
        while (busy);  // 等待当前数据发送完成
    }
}


那位大神帮我看看是什么问题

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:422
  • 最近打卡:2025-05-01 09:54:52
已绑定手机

19

主题

3190

回帖

4866

积分

论坛元老

积分
4866
发表于 2024-8-14 18:09:46 来自手机 | 显示全部楼层
模拟uart感觉有点丢包。要定义最小发送字节。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-8-14 18:55:17 | 显示全部楼层
有硬件UART为何没有使用,P31和P33有硬件UART的TXD
以前用15W104没有硬件串口,用例程的软件模拟串口正常
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15613
发表于 2024-8-14 21:35:40 | 显示全部楼层
8G1K08A-36I-SOP8,
P3.2是串口的接收,P3.3是串口的发送
软件模拟 串口通信 ? 不知道在想啥

截图202408142135356617.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:294
  • 最近打卡:2025-03-06 09:25:41

8

主题

318

回帖

1835

积分

金牌会员

积分
1835
发表于 2024-8-15 11:31:04 | 显示全部楼层
本帖最后由 Lkck8210 于 2024-8-15 11:35 编辑

横竖你都是死等busy,直接用delay来生成波特率吧
  1. void UartSend(uchar dat)
  2. {
  3.         uchar i=8;
  4.         DAT_tx = 0;// 起始位
  5.         Delay104us();//9600
  6.         while(i--)
  7.         {
  8.                 if(dat & 0x01)
  9.                         DAT_tx = 1;
  10.                 else
  11.                         DAT_tx = 0;
  12.                 dat>>=1;
  13.                 Delay104us();
  14.         }
  15.         DAT_tx = 1;// 停止位
  16.         Delay104us();
  17. }
复制代码
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 06:31 , Processed in 0.193738 second(s), 75 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表