关于 8G1K08A-36I-SOP8 的P3.2模拟软件TX发送数据,P3.2没发正常进行发送
#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++; // 增加数据索引
if (tx_index >= sizeof(tx_buffer)) // 如果索引超出数据缓冲区大小
{
tx_index = 0;// 重置索引以循环发送
}
while (busy);// 等待当前数据发送完成
}
}
那位大神帮我看看是什么问题
模拟uart感觉有点丢包。要定义最小发送字节。 有硬件UART为何没有使用,P31和P33有硬件UART的TXD
以前用15W104没有硬件串口,用例程的软件模拟串口正常 8G1K08A-36I-SOP8,
P3.2是串口的接收,P3.3是串口的发送
软件模拟 串口通信 ? 不知道在想啥
本帖最后由 Lkck8210 于 2024-8-15 11:35 编辑
横竖你都是死等busy,直接用delay来生成波特率吧
void UartSend(uchar dat)
{
uchar i=8;
DAT_tx = 0;// 起始位
Delay104us();//9600
while(i--)
{
if(dat & 0x01)
DAT_tx = 1;
else
DAT_tx = 0;
dat>>=1;
Delay104us();
}
DAT_tx = 1;// 停止位
Delay104us();
}
页:
[1]