数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 96|回复: 7

[C51] 求教,为什么串口不通?单片机是STC8H8K64U,使用串口2连接HLW8110

[复制链接]
发表于 昨天 22:04 | 显示全部楼层 |阅读模式
单片机是STC8H8K64U,使用串口2连接HLW8110,波特率9600,偶校验,将串口2的tx连到usb转串口模块能正确收到数据,用串口模块发送数据8110也能返回数据,但单片机发出的数据8110没有返回,串口2代码
uart2.h
  1. #ifndef __UART2_H__
  2. #define __UART2_H__

  3. #include <STC8H.H>
  4. #include "config.h"

  5. #define BAUDRATE         9600                                     // 波特率
  6. #define BRT2             (65536 - (MAIN_FOSC / BAUDRATE + 2) / 4) // 加 2 操作是为了让Keil编译器//自动实现四舍五入运算

  7. // #define UART2_BUF_LENGTH 4 // 缓冲数组长度为4

  8. // extern bit uart2_receive_flag; // 串口1接收完成标志
  9. // extern  u8  TX2_Cnt;    //发送计数
  10. // extern  u8  RX2_Cnt;    //接收计数
  11. // extern bit B_TX2_Busy; //发送忙标志
  12. // extern u8 RX2_Buffer[UART2_BUF_LENGTH]; // 接收缓冲
  13. extern u8 B_Tx_Finish;
  14. extern u8 B_Rx_Finish;
  15. extern u8 B_Rx_Data_ING; // 接收数据标志位        ,                < 1:接收数据中,0:未接收到数据 >
  16. extern u8 B_Read_Error;  // UART读取出据校验和出错,< 1:数据读错,0:数据读取正确 >
  17. extern u8 u8_TxBuf[10];
  18. extern u8 u8_RxBuf[10];
  19. extern u8 u8_TX_Length;
  20. extern u8 u8_RX_Length;
  21. extern u8 u8_RX_Index;

  22. void UART2_Init(u8 brt);     // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  23. void UART2SendStr(u8 *puts); // 发送字符串
  24. void UART2Send(u8 dat);      // 发送单个字符
  25. void Clear_RxBuf(void);
  26. #endif
复制代码


uart2.c
  1. #include "uart2.h"

  2. u8 TX2_Cnt     = 0; // 发送计数
  3. u8 RX2_Cnt     = 0; // 接收计数
  4. bit B_TX2_Busy = 0; // 发送忙标志
  5. // bit uart2_receive_flag          = 0;      // 串口2接收完成标志
  6. // u8 RX2_Buffer[UART2_BUF_LENGTH] = {0xFF}; // 接收缓冲
  7. /*---------------------------------------------------------*/
  8. // u8 B_ReadReg_Time_EN; // 串口读取寄存器数据,时间计数器标志位,1--开启计数,0--关闭计数
  9. u8 B_Tx_Finish   = 0;
  10. u8 B_Rx_Finish   = 0;
  11. u8 B_Rx_Data_ING = 0; // 接收数据标志位        ,                < 1:接收数据中,0:未接收到数据 >
  12. u8 B_Read_Error  = 0; // UART读取出据校验和出错,< 1:数据读错,0:数据读取正确 >
  13. u8 u8_TxBuf[10]  = {0};
  14. u8 u8_RxBuf[10]  = {0};
  15. u8 u8_TX_Length  = 0;
  16. u8 u8_RX_Length  = 0;
  17. u8 u8_RX_Index   = 0;
  18. // u8 u8_ReadReg_Index;
  19. // u8 u8_ReadReg_Time; // 串口读取寄存器数据的时间

  20. /*==========================================================
  21. * Function : void Clear_RxBuf(void)
  22. * Describe : 在准备接收串口数据前,清空接收缓存器的数据
  23. * Input    : none
  24. * Output   : none
  25. * Return   : none
  26. * Record   : 2019/04/03
  27. ===========================================================*/
  28. void Clear_RxBuf(void)
  29. {
  30.     u8 i;
  31.     for (i = 0; i < 10; i++) {
  32.         u8_RxBuf[i] = 0x00;
  33.     }

  34.     B_Rx_Data_ING = 0;
  35.     B_Rx_Finish   = 0;
  36.     u8_RX_Index   = 0;
  37. }
  38. //========================================================================
  39. // 函数: void UART2_SendStr(u8 *puts)
  40. // 描述: 串口2发送字符串函数。
  41. // 参数: puts:  字符串指针.
  42. // 返回: none.
  43. // 版本: VER1.0
  44. // 日期: 2014-11-28
  45. // 备注:
  46. //========================================================================
  47. void UART2SendStr(u8 *puts)
  48. {
  49.     for (; *puts != 0; puts++) // 遇到停止符0结束
  50.     {
  51.         UART2Send(*puts);
  52.     }
  53. }
  54. //========================================================================
  55. // 函数: void UART2_Send(u8 dat)
  56. // 描述: 串口2发送字符串函数。
  57. // 参数: dat:  字符.
  58. // 返回: none.
  59. // 版本: VER1.0
  60. // 日期: 2014-11-28
  61. // 备注:
  62. //========================================================================
  63. void UART2Send(u8 dat)
  64. {
  65.     while (B_TX2_Busy);
  66.     B_TX2_Busy = 1;
  67.     S2BUF = dat;
  68. }
  69. //========================================================================
  70. // 函数: SetTimer2Baudraye2(u16 dat)
  71. // 描述: 设置Timer2做波特率发生器。
  72. // 参数: dat: Timer2的重装值.
  73. // 返回: none.
  74. // 版本: VER1.0
  75. // 日期: 2014-11-28
  76. // 备注:
  77. //========================================================================
  78. void SetTimer2Baudraye2(u16 dat) // 使用Timer2做波特率.
  79. {
  80.     AUXR &= ~(1 << 4); // Timer stop
  81.     AUXR &= ~(1 << 3); // Timer2 set As Timer
  82.     AUXR |= (1 << 2);  // Timer2 set as 1T mode
  83.     T2H = dat / 256;
  84.     T2L = dat % 256;
  85.     IE2 &= ~(1 << 2); // 禁止定时器中断
  86.     AUXR |= (1 << 4); // Timer run enable
  87. }

  88. //========================================================================
  89. // 函数: void UART2_Init(u8 brt)
  90. // 描述: UART2初始化函数。
  91. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  92. // 返回: none.
  93. // 版本: VER1.0
  94. // 日期: 2014-11-28
  95. // 备注:
  96. //========================================================================
  97. void UART2_Init(u8 brt) // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  98. {
  99.     /*********** 波特率固定使用定时器2 *****************/
  100.     if (brt == 2) {
  101.         SetTimer2Baudraye2(BRT2);
  102.         P_SW2 &= ~0x01;
  103.         P_SW2 |= 0;       // UART2 switch to: 0: P1.0 P1.1,  1: P4.6 P4.7
  104.         S2CON     = 0x90; // 8位数据, 1位起始位, 1位停止位, 1校验,允许接收
  105.         USART2CR2 = 0x04; // 硬件自动产生偶校验位
  106.         // IP2 |= 0x01;    //提高串口2中断优先级,防止数据丢失
  107.         IE2 |= 0x01; // 允许中断
  108.         B_TX2_Busy = 0;
  109.         TX2_Cnt    = 0;
  110.         RX2_Cnt    = 0;
  111.     }
  112. }

  113. //========================================================================
  114. // 函数: void UART2_int (void) interrupt UART2_VECTOR
  115. // 描述: UART2中断函数。
  116. // 参数: nine.
  117. // 返回: none.
  118. // 版本: VER1.0
  119. // 日期: 2014-11-28
  120. // 备注:
  121. //========================================================================
  122. void UART2_int(void) interrupt 8
  123. {
  124.     if (S2CON & 1) // 收到数据
  125.     {
  126.         S2CON &= ~1;                   // Clear Rx flag
  127.         u8_RxBuf[u8_RX_Index] = S2BUF; // 数据接收中
  128.         if (++u8_RX_Index >= u8_RX_Length) {
  129.             u8_RX_Index = 0;
  130.             B_Rx_Finish = 1;
  131.         }
  132.     }

  133.     if (S2CON & 2) // 发送数据
  134.     {
  135.         S2CON &= ~2; // Clear Tx flag
  136.         B_TX2_Busy = 0;
  137.     }
  138. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
 楼主| 发表于 昨天 22:09 | 显示全部楼层
第一张图是单片机发出的数据,A5 70之后就应该返回数据。第二张图是串口模块发送给8110的数据,能正常返回
回复 支持 反对

使用道具 举报

发表于 昨天 22:31 | 显示全部楼层
坐等 高手解答。
回复 支持 反对

使用道具 举报

发表于 昨天 22:47 来自手机浏览器 | 显示全部楼层
你得代码是移植官方stm32的代码吗?
我折腾过,给你个建议用串口1吧,硬件偶校验用acc寄存器p,获取后赋值给tb8,组成8数据➕偶检验模式。
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 23:42 来自手机浏览器 | 显示全部楼层
nokia5320 发表于 2025-8-25 22:47
你得代码是移植官方stm32的代码吗?
我折腾过,给你个建议用串口1吧,硬件偶校验用acc寄存器p,获取后赋值 ...

8110驱动是移植stm32的,但串口2的代码是官方例程的,你这个方法我试了,还是一样
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
串口波特率误差一般要求小于±4%,你这种情况有可能是波特率误差导致的,比如USB转串口和8110是3%的误差,SB转串口和单片机串口2是-3%的误差,则8110和单片机串口2之间的误差就达到6%了。

玩儿串口,最好还是买个十几块的逻辑分析仪吧。
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
一般是stc的串口初始化代码有点差别
下面帖子2楼有类似代码 去研究吧

STC-BL0942内阻仪打板(附代码)
https://www.mydigit.cn/forum.php ... &fromuid=768940

回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层
除了楼上说的波特率误差外检查一下线序接的对吗?有示波器或逻辑分析仪的话看看波形
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-8-26 11:11 , Processed in 0.109200 second(s), 8 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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