3
9
65
注册会员
#include <STC8H.H> // ==================== 环形缓冲区通用定义 ==================== #define BUFFER_SIZE 20 // 模拟串口(UART3)缓冲区 unsigned char rx_buffer3[BUFFER_SIZE]; unsigned char rx_in3 = 0; unsigned char rx_out3 = 0; unsigned char rx_count3 = 0; // 接收状态机 unsigned char soft_rx_state = 0; // 0:空闲, 1:起始位, 2:数据位, 3:停止位 unsigned char soft_rx_byte = 0; // 接收到的字节暂存 unsigned char soft_rx_bit_cnt = 0; // 数据位计数 unsigned char soft_rx_stop_bit = 0; // 停止位标志 // ==================== 模拟串口相关变量 ==================== sbit SOFT_TXD = P3^6; // 发送引脚 sbit SOFT_RXD = P3^7; // 接收引脚 #define BIT_TIME_RELOAD_H 0xF1 // 示例值,需根据实际调试微调 #define BIT_TIME_RELOAD_L 0x9A // ==================== 模拟串口初始化(P3.6 TXD, P3.7 RXD) ==================== void SoftUart_Init(void) { // 引脚配置 P3M0 &= ~0xC0; P3M1 &= ~0xC0; P3M0 |= 0x40; // P3.6 推挽输出 (TXD) P3M1 |= 0x80; // P3.7 高阻输入 (RXD) SOFT_TXD = 1; // 定时器0配置 (16-bit自动重载,3倍采样) TMOD &= 0xF0; // 清除T0模式位 TMOD |= 0x01; // T0模式1: 16位(不可自动重载,在ISR中手动重载) TL0 = BIT_TIME_RELOAD_L; TH0 = BIT_TIME_RELOAD_H; ET0 = 1; // 使能定时器0中断 TR0 = 1; // 启动定时器0 EA = 1; // 确保总中断开通 soft_rx_state = 0; } // 重写SoftUart_SendByte使用BitDelay void SoftUart_SendByte(unsigned char dat) { unsigned char i; // 关闭定时器3中断,避免发送过程被接收中断干扰 IE2 &= ~0x20; // 起始位 SOFT_TXD = 0; BitDelay(); // 发送8个数据位(LSB first) for (i = 0; i < 8; i++) { if (dat & 0x01) SOFT_TXD = 1; else SOFT_TXD = 0; BitDelay(); dat >>= 1; } // 停止位 SOFT_TXD = 1; BitDelay(); // 恢复定时器3中断 IE2 |= 0x20; } void Timer0_Isr(void) interrupt 1 { // 手动重载定时器0(提升时序准确性) TL0 = BIT_TIME_RELOAD_L; TH0 = BIT_TIME_RELOAD_H; switch (soft_rx_state) { case 0: // 空闲,检测起始位 if (SOFT_RXD == 0) { soft_rx_state = 1; soft_rx_bit_cnt = 0; soft_rx_byte = 0; } break; case 1: // 起始位确认(延迟半位中心) soft_rx_state = 2; break; case 2: // 接收数据位(每次中断采集一位) soft_rx_byte >>= 1; if (SOFT_RXD) soft_rx_byte |= 0x80; if (++soft_rx_bit_cnt >= 8) { soft_rx_state = 3; } break; case 3: // 停止位校验 if (SOFT_RXD == 1) { P12 = ~P12; if (rx_count3 < BUFFER_SIZE) { rx_buffer3[rx_in3] = soft_rx_byte; rx_in3 = (rx_in3 + 1) % BUFFER_SIZE; rx_count3++; } } soft_rx_state = 0; break; default: soft_rx_state = 0; } } void main() { P_SW2 |= 0x80; SoftUart_Init(); // 初始化模拟串口 P1M0 = 0x00; P1M1 = 0x00; while(1) { if (rx_count3 > 0) { unsigned char data3 = rx_buffer3[rx_out3]; SBUF = data3; while(!TI); TI = 0; rx_out3 = (rx_out3 + 1) % BUFFER_SIZE; rx_count3--; //P12 = 1; //Delay10ms(); } } } 复制代码
使用道具 举报 送花
850
1万
2万
管理员
神*** 发表于 2026-5-4 13:43
神*** 发表于 2026-5-4 13:45 https://www.stcaimcu.com/data/download/Datasheet/STC32G.pdf
14
239
2922
金牌会员
24
108
926
高级会员
tlx*** 发表于 2026-5-4 14:18 我是STC8H
//////////////////////////////////////// // 重写printf字符发送重定向函数 // 入口参数: dat (printf函数待打印的字符) // 函数返回: 需要返回入口参数的数据 //////////////////////////////////////// char putchar (char dat) //将串口1和printf函数绑定 { unsigned int xdata t; P_SW1 &= ~0xc0; //UART1/USART1: RxD(P3.0), TxD(P3.1) TI=0; SBUF=dat; t=65535; while (!TI && (t--)!=0); TI=0; P_SW1 = (P_SW1 & ~0xc0) | 0x40; //UART1/USART1: RxD(P3.6), TxD(P3.7) return dat; } 复制代码
C_w*** 发表于 2026-5-4 14:37 新手就换芯片吧,别折磨自己了。 不要过度依赖AI,看看官方例程。
zh*** 发表于 2026-5-4 14:42 你可以让一个串口,在不同的管脚上切换,比如读传感器数据,这个读的时刻你能掌握,就可以切换引脚,发读命令, ...
本版积分规则 发表回复 回帖后跳转到最后一页
|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )
GMT+8, 2026-5-9 05:41 , Processed in 0.148430 second(s), 102 queries .
Powered by Discuz! X3.5
© 2001-2026 Discuz! Team.