oqxeahdm 发表于 2025-4-18 17:33:28

8H系列,串口1打印问题。

更改串口1的连接引脚为1.6和1.7后,不能进行打印。3.0 3.1能够正常打印。
芯片是8H1K08T芯片
代码如下
使用库函数的

#include      "config.h"
#include      "STC8G_H_GPIO.h"
#include      "STC8G_H_UART.h"
#include      "STC8G_H_Delay.h"
#include      "STC8G_H_NVIC.h"
#include      "STC8G_H_Switch.h"

/*************      功能说明      **************

本例程基于STC8H8K64U为主控芯片的实验箱8进行编写测试,STC8G、STC8H系列芯片可通用参考.

双串口全双工中断方式收发通讯程序。

通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回, 默认波特率:115200,N,8,1.

通过开启 STC8G_H_UART.h 头文件里面的 UART1~UART4 定义,启动不同通道的串口通信。

用定时器做波特率发生器,建议使用1T模式(除非低波特率用12T),并选择可被波特率整除的时钟频率,以提高精度。

下载时, 选择时钟 22.1184MHz (用户可在"config.h"修改频率).

******************************************/

/*************      本地常量声明      **************/


/*************      本地变量声明      **************/


/*************      本地函数声明      **************/


/*************外部函数和变量声明 *****************/


/******************* IO配置函数 *******************/
void      GPIO_config(void)
{
      GPIO_InitTypeDef      GPIO_InitStructure;                //结构定义

      GPIO_InitStructure.Pin= GPIO_Pin_6 | GPIO_Pin_7;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
      GPIO_InitStructure.Mode = GPIO_PullUp;      //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
      GPIO_Inilize(GPIO_P1,&GPIO_InitStructure);      //初始化
}

/***************串口初始化函数 *****************/
void      UART_config(void)
{
      COMx_InitDefine                COMx_InitStructure;                                        //结构定义

      COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;      //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
      COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;                        //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
      COMx_InitStructure.UART_BaudRate= 115200ul;                        //波特率, 一般 110 ~ 115200
      COMx_InitStructure.UART_RxEnable= ENABLE;                              //接收允许,   ENABLE或DISABLE
      COMx_InitStructure.BaudRateDouble = DISABLE;                        //波特率加倍, ENABLE或DISABLE
      UART_Configuration(UART1, &COMx_InitStructure);                //初始化串口1 UART1,UART2,UART3,UART4
      NVIC_UART1_Init(ENABLE,Priority_1);                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

      UART1_SW(UART1_SW_P16_P17);                //UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}


/**********************************************/
void main(void)
{
      u8      i;

      EAXSFR();                /* 扩展寄存器访问使能 */
      GPIO_config();
      UART_config();
      EA = 1;

      printf("STC8H8K64U UART1 Test Programme!\r\n");      //UART1发送一个字符串
//      PrintString1("STC8H8K64U UART1 Test Programme!\r\n");      //UART1发送一个字符串

      while (1)
      {
                delay_ms(1);
                if(COM1.RX_TimeOut > 0)                //超时计数
                {
                        if(--COM1.RX_TimeOut == 0)
                        {
                              if(COM1.RX_Cnt > 0)
                              {
                                        for(i=0; i<COM1.RX_Cnt; i++)      TX1_write2buff(RX1_Buffer);      //收到的数据原样返回
                              }
                              COM1.RX_Cnt = 0;
                        }
                }
      }
}





使用寄存器的



/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/
/* --- Web: www.stcmcudata.com -------------------------------------*/
/* --- Web: www.stcai.com ------------------------------------------*/
/* --- BBS: www.stcaimcu.com ---------------------------------------*/
/* If you want to use the program or the program referenced in the*/
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/


/*********************************************************/

#define MAIN_Fosc                11059200L      //定义主时钟

#include      "..\..\STC8Hxxx.h"


/*************      功能说明      **************

请先别修改程序, 直接下载"07-串口1中断收发-多机通信-C语言"里的"UART1.hex"测试, 主频选择11.0592MHZ. 测试正常后再修改移植.

串口1全双工中断方式收发通讯程序, 地址匹配多机通信方式.

通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回.

默认参数:
串口1设置均为 1位起始位, 8位数据位, 1位校验位, 1位停止位.
串口1(P3.0 P3.1): 115200bps.

通讯原理解释:

用户宏定义从机地址SLAVE_ADDR(本例为0xaa), 初始化串口1为9位数据位,将匹配地址写入SADDR, 并将SM2至1.
然后程序等待地址匹配. 发送端将TB8置1并发送地址.
当地址匹配, 则自动进入接收中断, 将SM2置0, 准备接收数据.
发送端将TB8置0, 发送数据.
接收数据并保存, 并且设置超时, 用于判断接收完成.
检测到超时, 则接收完成, 数据处理(本例为将数据原样返回).
将SM2置1, 重复上述过程.

使用PC机的串口助手测试, 串口助手必须能支持9位数据. 发送例子:
校验位为1, 发送地址0xaa.
校验位为0, 发送数据(本例不超过128字节).
串口助手将看到MCU返回的数据, 跟发送的数据一致.

******************************************/

/*************      本地常量声明      **************/

#define      SLAVE_ADDR      0xaa      //匹配地址

#define      RX1_Length      128                /* 接收缓冲长度 */


/*************      本地变量声明      **************/
u8      xdata      RX1_Buffer;      //接收缓冲

u8      RX1_TimerOut;      //接收超时
u8      RX1_cnt;                //接收字节计数
bit      B_TX1_Busy;                // 发送忙标志


/*************      本地函数声明      **************/
void      UART1_config(u32 brt, u8 timer, u8 io);      // brt: 通信波特率,timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.
void         UART1_PrintString(u8 *puts);
void      delay_ms(u8 ms);




//========================================================================
// 函数: void main(void)
// 描述: 主函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void main(void)
{
      u8      i;

      EAXRAM();

      UART1_config(115200UL, 1, 3);      // brt: 通信波特率,timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.

      EA = 1;

      for(i=0; i<RX1_Length; i++)                RX1_Buffer = 0;
      B_TX1_Busy= 0;
      RX1_TimerOut = 0;
      RX1_cnt = 0;

      UART1_PrintString("STC8H 8C serial UART1 Test Prgramme!\r\n");

      while (1)
      {
                delay_ms(1);
               
                if(RX1_TimerOut != 0)
                {
                        if(--RX1_TimerOut == 0)      //超时, 则接收结束, 数据处理(本例子仅仅是将数据原样返回)
                        {
                              if(RX1_cnt != 0)      //收到有数据
                              {
                                        TB8 = 0;
                                        for(i=0; i<RX1_cnt; i++)
                                        {
                                                B_TX1_Busy = 1;                //标志发送忙
                                                SBUF = RX1_Buffer;                //发一个字节
                                                while(B_TX1_Busy);      //等待发送完成
                                        }
                                        RX1_cnt = 0;
                                        SM2 = 1;      //允许地址匹配
                              }
                        }
                }
      }
}


//========================================================================
// 函数: voiddelay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-1
// 备注:
//========================================================================
voiddelay_ms(u8 ms)
{
      u16 i;
      do
      {
                i = MAIN_Fosc / 10000;
                while(--i)      ;
      }while(--ms);
}

//========================================================================
// 函数: SetTimer2Baudraye(u16 dat)
// 描述: 设置Timer2做波特率发生器。
// 参数: dat: Timer2的重装值.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void      SetTimer2Baudraye(u16 dat)      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{
      AUXR &= ~(1<<4);      //Timer stop
      AUXR &= ~(1<<3);      //Timer2 set As Timer
      AUXR |=(1<<2);      //Timer2 set as 1T mode
      TH2 = (u8)(dat >> 8);
      TL2 = (u8)dat;
      IE2&= ~(1<<2);      //禁止中断
      AUXR |=(1<<4);      //Timer run enable
}


//========================================================================
// 函数: void      UART1_config(u32 brt, u8 timer, u8 io)
// 描述: UART1初始化函数。
// 参数:   brt: 通信波特率.
//       timer: 波特率使用的定时器, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率.
//          io: 串口1切换到的IO,io=1: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void      UART1_config(u32 brt, u8 timer, u8 io)      // brt: 通信波特率,timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.
{
      brt = 65536UL - (MAIN_Fosc / 4) / brt;
      if(timer == 2)      //波特率使用定时器2
      {
                AUXR |= 0x01;                //S1 BRT Use Timer2;
                SetTimer2Baudraye((u16)brt);
      }

      else                //波特率使用定时器1
      {
                TR1 = 0;
                AUXR &= ~0x01;                //S1 BRT Use Timer1;
                AUXR |=(1<<6);      //Timer1 set as 1T mode
                TMOD &= ~(1<<6);      //Timer1 set As Timer
                TMOD &= ~0x30;                //Timer1_16bitAutoReload;
                TH1 = (u8)(brt >> 8);
                TL1 = (u8)brt;
                ET1 = 0;                        // 禁止Timer1中断
                INT_CLKO &= ~0x02;      // Timer1不输出高速时钟
                TR1= 1;                        // 运行Timer1
      }

               if(io == 1)      {S1_USE_P36P37();      P3n_standard(0xc0);}      //切换到 P3.6 P3.7
      else if(io == 2)      {S1_USE_P16P17();      P1n_standard(0xc0);}      //切换到 P1.6 P1.7
      else if(io == 3)      {S1_USE_P43P44();      P4n_standard(0x18);}      //切换到 P4.3 P4.4
      else                              {S1_USE_P30P31();      P3n_standard(0x03);}      //切换到 P3.0 P3.1

      SCON = (SCON & 0x3f) | (3<<6);      // 8位数据, 1位校验位, 1位起始位, 1位停止位
//      PS= 1;      //高优先级中断
      SADDR = SLAVE_ADDR;                //匹配地址
      SADEN = 0xff;                        //地址屏蔽
      SM2 = 1;      //允许地址匹配
      ES= 1;      //允许中断
      REN = 1;      //允许接收
}


//========================================================================
// 函数: void UART1_PrintString(u8 *puts)
// 描述: 串口1字符串打印函数
// 参数: puts: 字符串指针.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_PrintString(u8 *puts)
{
    for (; *puts != 0;      puts++)
      {
                B_TX1_Busy = 1;                //标志发送忙
                TB8 = 0;
                SBUF = *puts;                //发一个字节
                while(B_TX1_Busy);      //等待发送完成
      }
}


//========================================================================
// 函数: void UART1_int (void) interrupt UART1_VECTOR
// 描述: 串口1中断函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_int (void) interrupt UART1_VECTOR
{
      if(RI)
      {
                RI = 0;
                if(RB8)                              //为地址信息, 地址匹配
                {
                //      if(SBUF == SLAVE_ADDR)                //这句可以不用, 能收到则为地址匹配了
                        {
                              SM2 = 0;                //允许接收数据
                              RX1_cnt = 0;      //接收计数归0
                        }
                }
                else                //接收到数据
                {
                        RX1_Buffer = SBUF;      //保存一个数据
                        if(++RX1_cnt > RX1_Length)      RX1_cnt = 0;
                        RX1_TimerOut = 5;                              //接收数据超时时间
                }
      }

      if(TI)
      {
                TI = 0;
                B_TX1_Busy = 0;
      }
}

UART1_config(115200UL, 1, 3); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1, =1: 切换到P3.6 P3.7, =2: 切换到P1.6 P1.7, =3: 切换到P4.3 P4.4.,已经换成了3,但是仍然打印不了。



我想使用P1.6,P1.7作为串口1的引脚,现在无法通过电脑的串口助手进行打印,只有当串口1引脚为3.0 3.1时才能正常打印


国芯人工智能 发表于 2025-4-18 17:38:00

在STC8H1K08T芯片中,串口1的默认引脚是P3.0(RXD)和P3.1(TXD)。当您将串口1的连接引脚更改为P1.6和P1.7后,无法进行打印,而使用默认引脚P3.0和P3.1时能够正常打印。这个问题可能与以下几个因素有关:

1. 引脚配置问题
首先,确保您已经正确配置了P1.6和P1.7为串口1的RXD和TXD引脚。在STC8H系列芯片中,串口引脚可以通过寄存器进行重映射。您需要检查并确认以下几点:
P1.6和P1.7的复用功能:确保P1.6和P1.7已经配置为串口1的RXD和TXD功能。可以通过设置相关的寄存器来实现这一点。
GPIO模式配置:确保P1.6和P1.7的GPIO模式已经配置为正确的模式(通常为推挽输出或开漏输出)。

2. 串口初始化代码
在您的代码中,串口1的初始化部分需要正确配置波特率、数据位、停止位等参数。请确保以下代码段已经正确配置:

c
void UART1Init(void)
{
    UARTInitTypeDef UARTInitStructure;

    UARTInitStructure.UARTMode = UARTMode8Bit; // 8位数据位
    UARTInitStructure.UARTBaudRate = 115200;   // 波特率115200
    UARTInitStructure.UARTStopBits = UARTStopBits1; // 1位停止位
    UARTInitStructure.UARTParity = UARTParityNo;    // 无校验位
    UARTInitStructure.UARTRX = GPIOPin6;            // RXD引脚为P1.6
    UARTInitStructure.UARTTX = GPIOPin7;            // TXD引脚为P1.7

    UARTInit(UART1, &UARTInitStructure);
}

3. 引脚重映射
在STC8H系列芯片中,串口引脚可以通过寄存器进行重映射。您需要检查并确认以下几点:
PSW1寄存器:在STC8H系列芯片中,PSW1寄存器用于配置串口1的引脚重映射。您需要将PSW1寄存器的相应位设置为1,以将串口1的RXD和TXD引脚重映射到P1.6和P1.7。

c
PSW1 |= 0x40; // 将串口1的RXD和TXD引脚重映射到P1.6和P1.7

4. 硬件连接
确保硬件连接正确,P1.6和P1.7已经正确连接到串口通信的接收和发送线路上。如果硬件连接不正确,串口通信将无法正常工作。

5. 调试建议
如果以上配置都正确,但仍然无法进行打印,建议您进行以下调试步骤:
检查波特率:确保波特率设置正确,且与PC端的波特率一致。
检查时钟频率:确保芯片的时钟频率与波特率设置匹配,避免因时钟频率不匹配导致的通信问题。
使用示波器或逻辑分析仪:通过示波器或逻辑分析仪观察P1.6和P1.7的信号,确认是否有数据发送和接收。

6. 代码示例
以下是一个完整的代码示例,展示了如何将串口1的引脚重映射到P1.6和P1.7,并进行串口通信:

c
include "config.h"
include "STC8GHGPIO.h"
include "STC8GHUART.h"
include "STC8GHDelay.h"
include "STC8GHNVIC.h"
include "STC8GHSwitch.h"

void GPIOconfig(void)
{
    GPIOInitTypeDef GPIOInitStructure;

    GPIOInitStructure.Pin = GPIOPin6 | GPIOPin7; // P1.6和P1.7
    GPIOInitStructure.Mode = GPIOModeOutPP;       // 推挽输出
    GPIOInitStructure.Speed = GPIOSpeed50MHz;      // 50MHz
    GPIOInit(GPIOP1, &GPIOInitStructure);
}

void UART1Init(void)
{
    UARTInitTypeDef UARTInitStructure;

    UARTInitStructure.UARTMode = UARTMode8Bit; // 8位数据位
    UARTInitStructure.UARTBaudRate = 115200;   // 波特率115200
    UARTInitStructure.UARTStopBits = UARTStopBits1; // 1位停止位
    UARTInitStructure.UARTParity = UARTParityNo;    // 无校验位
    UARTInitStructure.UARTRX = GPIOPin6;            // RXD引脚为P1.6
    UARTInitStructure.UARTTX = GPIOPin7;            // TXD引脚为P1.7

    UARTInit(UART1, &UARTInitStructure);
}

void main(void)
{
    GPIOconfig();
    PSW1 |= 0x40; // 将串口1的RXD和TXD引脚重映射到P1.6和P1.7
    UART1Init();

    while (1)
    {
      if (UARTGetFlagStatus(UART1, UARTFLAGRX))
      {
            uint8t data = UARTReceiveData(UART1);
            UARTSendData(UART1, data);
      }
    }
}

7. 总结
通过以上步骤,您应该能够解决串口1在P1.6和P1.7引脚上无法打印的问题。如果问题仍然存在,建议进一步检查硬件连接和芯片的寄存器配置,确保所有设置都正确无误。

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

王昱顺 发表于 2025-4-18 18:33:17

寄存器方式中,没有设置P16、P17的IO口模式,默认是高阻默认,不能通讯。
P30和P31出于需要下载程序的考虑, 上电默认模式就是准双向口,所以不用设置也可以通讯。

oqxeahdm 发表于 2025-4-18 21:37:49

王昱顺 发表于 2025-4-18 18:33
寄存器方式中,没有设置P16、P17的IO口模式,默认是高阻默认,不能通讯。
P30和P31出于需要下载程序的考虑 ...

void GPIOconfig(void)
{
    GPIOInitTypeDef GPIOInitStructure;
    GPIOInitStructure.Pin = GPIOPin6 | GPIOPin7; // P1.6和P1.7
    GPIOInitStructure.Mode = GPIOModeOutPP;       // 推挽输出
    GPIOInitStructure.Speed = GPIOSpeed50MHz;      // 50MHz
    GPIOInit(GPIOP1, &GPIOInitStructure);
}
这个不是设置了引脚的IO口模式了吗

oqxeahdm 发表于 2025-4-19 09:31:58

王昱顺 发表于 2025-4-18 18:33
寄存器方式中,没有设置P16、P17的IO口模式,默认是高阻默认,不能通讯。
P30和P31出于需要下载程序的考虑 ...

你好,麻烦解决下我的问题,我尝试设置为推挽模式,或者使用寄存器直接配置,都无法使用P1.6 P1.7进行串口打印,在电脑的串口助手都无法显示打印的消息

乘风飞扬 发表于 2025-4-21 09:18:05

请提供完整的测试项目,这样方便分析。
寄存器版本明显设置错误,选择 2 才是切换到P1.6,P1.7
io=1: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.


此外检查一下硬件连接,P1.6,P1.7脚位是否选择正确,有没有虚焊或者短路,有没有其它元器件干扰通信信号?


oqxeahdm 发表于 2025-4-21 14:43:19

乘风飞扬 发表于 2025-4-21 09:18
请提供完整的测试项目,这样方便分析。
寄存器版本明显设置错误,选择 2 才是切换到P1.6,P1.7
io=1: 串口1 ...

“. io=0: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4”注释上显示是这样,io=3我是用来测试其它引脚连接串口1是否可以成功,只有串口1切换到P3.0 P3.1才能打印,其它的都不行
/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/
/* --- Web: www.stcmcudata.com -------------------------------------*/
/* --- Web: www.stcai.com ------------------------------------------*/
/* --- BBS: www.stcaimcu.com ---------------------------------------*/
/* If you want to use the program or the program referenced in the*/
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/


/*********************************************************/

#define MAIN_Fosc                11059200L        //定义主时钟

#include        "..\..\STC8Hxxx.h"


/*************        功能说明        **************

请先别修改程序, 直接下载"07-串口1中断收发-多机通信-C语言"里的"UART1.hex"测试, 主频选择11.0592MHZ. 测试正常后再修改移植.

串口1全双工中断方式收发通讯程序, 地址匹配多机通信方式.

通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回.

默认参数:
串口1设置均为 1位起始位, 8位数据位, 1位校验位, 1位停止位.
串口1(P3.0 P3.1): 115200bps.

通讯原理解释:

用户宏定义从机地址SLAVE_ADDR(本例为0xaa), 初始化串口1为9位数据位,将匹配地址写入SADDR, 并将SM2至1.
然后程序等待地址匹配. 发送端将TB8置1并发送地址.
当地址匹配, 则自动进入接收中断, 将SM2置0, 准备接收数据.
发送端将TB8置0, 发送数据.
接收数据并保存, 并且设置超时, 用于判断接收完成.
检测到超时, 则接收完成, 数据处理(本例为将数据原样返回).
将SM2置1, 重复上述过程.

使用PC机的串口助手测试, 串口助手必须能支持9位数据. 发送例子:
校验位为1, 发送地址0xaa.
校验位为0, 发送数据(本例不超过128字节).
串口助手将看到MCU返回的数据, 跟发送的数据一致.

******************************************/

/*************        本地常量声明        **************/

#define        SLAVE_ADDR        0xaa        //匹配地址

#define        RX1_Length        128                /* 接收缓冲长度 */


/*************        本地变量声明        **************/
u8        xdata        RX1_Buffer;        //接收缓冲

u8        RX1_TimerOut;        //接收超时
u8        RX1_cnt;                //接收字节计数
bit        B_TX1_Busy;                // 发送忙标志


/*************        本地函数声明        **************/
void        UART1_config(u32 brt, u8 timer, u8 io);        // brt: 通信波特率,timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.
void         UART1_PrintString(u8 *puts);
void        delay_ms(u8 ms);




//========================================================================
// 函数: void main(void)
// 描述: 主函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void main(void)
{
        u8        i;

        EAXRAM();
    P1M0 &= ~0xc0; P1M1 &= ~0xc0;

        UART1_config(115200UL, 1, 3);        // brt: 通信波特率,timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.
    P1M0 &= ~0xc0; P1M1 &= ~0xc0;

        EA = 1;

        for(i=0; i<RX1_Length; i++)                RX1_Buffer = 0;
        B_TX1_Busy= 0;
        RX1_TimerOut = 0;
        RX1_cnt = 0;

        UART1_PrintString("STC8H 8C serial UART1 Test Prgramme!\r\n");

        while (1)
        {
                delay_ms(1);
               
                if(RX1_TimerOut != 0)
                {
                        if(--RX1_TimerOut == 0)        //超时, 则接收结束, 数据处理(本例子仅仅是将数据原样返回)
                        {
                                if(RX1_cnt != 0)        //收到有数据
                                {
                                        TB8 = 0;
                                        for(i=0; i<RX1_cnt; i++)
                                        {
                                                B_TX1_Busy = 1;                //标志发送忙
                                                SBUF = RX1_Buffer;                //发一个字节
                                                while(B_TX1_Busy);        //等待发送完成
                                        }
                                        RX1_cnt = 0;
                                        SM2 = 1;        //允许地址匹配
                                }
                        }
                }
        }
}


//========================================================================
// 函数: voiddelay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-1
// 备注:
//========================================================================
voiddelay_ms(u8 ms)
{
        u16 i;
        do
        {
                i = MAIN_Fosc / 10000;
                while(--i)        ;
        }while(--ms);
}

//========================================================================
// 函数: SetTimer2Baudraye(u16 dat)
// 描述: 设置Timer2做波特率发生器。
// 参数: dat: Timer2的重装值.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void        SetTimer2Baudraye(u16 dat)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{
        AUXR &= ~(1<<4);        //Timer stop
        AUXR &= ~(1<<3);        //Timer2 set As Timer
        AUXR |=(1<<2);        //Timer2 set as 1T mode
        TH2 = (u8)(dat >> 8);
        TL2 = (u8)dat;
        IE2&= ~(1<<2);        //禁止中断
        AUXR |=(1<<4);        //Timer run enable
}


//========================================================================
// 函数: void        UART1_config(u32 brt, u8 timer, u8 io)
// 描述: UART1初始化函数。
// 参数:   brt: 通信波特率.
//       timer: 波特率使用的定时器, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率.
//          io: 串口1切换到的IO,io=1: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void        UART1_config(u32 brt, u8 timer, u8 io)        // brt: 通信波特率,timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4.
{
        brt = 65536UL - (MAIN_Fosc / 4) / brt;
        if(timer == 2)        //波特率使用定时器2
        {
                AUXR |= 0x01;                //S1 BRT Use Timer2;
                SetTimer2Baudraye((u16)brt);
        }

        else                //波特率使用定时器1
        {
                TR1 = 0;
                AUXR &= ~0x01;                //S1 BRT Use Timer1;
                AUXR |=(1<<6);        //Timer1 set as 1T mode
                TMOD &= ~(1<<6);        //Timer1 set As Timer
                TMOD &= ~0x30;                //Timer1_16bitAutoReload;
                TH1 = (u8)(brt >> 8);
                TL1 = (u8)brt;
                ET1 = 0;                        // 禁止Timer1中断
                INT_CLKO &= ~0x02;        // Timer1不输出高速时钟
                TR1= 1;                        // 运行Timer1
        }

               if(io == 1)        {S1_USE_P36P37();        P3n_standard(0xc0);}        //切换到 P3.6 P3.7
        else if(io == 2)        {S1_USE_P16P17();        P1n_standard(0xc0);}        //切换到 P1.6 P1.7
        else if(io == 3)        {S1_USE_P43P44();        P4n_standard(0x18);}        //切换到 P4.3 P4.4
        else                                {S1_USE_P30P31();        P3n_standard(0x03);}        //切换到 P3.0 P3.1

        SCON = (SCON & 0x3f) | (3<<6);        // 8位数据, 1位校验位, 1位起始位, 1位停止位
//        PS= 1;        //高优先级中断
        SADDR = SLAVE_ADDR;                //匹配地址
        SADEN = 0xff;                        //地址屏蔽
        SM2 = 1;        //允许地址匹配
        ES= 1;        //允许中断
        REN = 1;        //允许接收
}


//========================================================================
// 函数: void UART1_PrintString(u8 *puts)
// 描述: 串口1字符串打印函数
// 参数: puts: 字符串指针.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_PrintString(u8 *puts)
{
    for (; *puts != 0;        puts++)
        {
                B_TX1_Busy = 1;                //标志发送忙
                TB8 = 0;
                SBUF = *puts;                //发一个字节
                while(B_TX1_Busy);        //等待发送完成
        }
}


//========================================================================
// 函数: void UART1_int (void) interrupt UART1_VECTOR
// 描述: 串口1中断函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_int (void) interrupt UART1_VECTOR
{
        if(RI)
        {
                RI = 0;
                if(RB8)                                //为地址信息, 地址匹配
                {
                //        if(SBUF == SLAVE_ADDR)                //这句可以不用, 能收到则为地址匹配了
                        {
                                SM2 = 0;                //允许接收数据
                                RX1_cnt = 0;        //接收计数归0
                        }
                }
                else                //接收到数据
                {
                        RX1_Buffer = SBUF;        //保存一个数据
                        if(++RX1_cnt > RX1_Length)        RX1_cnt = 0;
                        RX1_TimerOut = 5;                                //接收数据超时时间
                }
        }

        if(TI)
        {
                TI = 0;
                B_TX1_Busy = 0;
        }
}



是完整的项目代码

oqxeahdm 发表于 2025-4-21 15:48:36

oqxeahdm 发表于 2025-4-21 14:43
“. io=0: 串口1切换到P3.0 P3.1,=1: 切换到P3.6 P3.7,=2: 切换到P1.6 P1.7,=3: 切换到P4.3 P4.4” ...

"C:\Users\86156\Pictures\Screenshots\屏幕截图 2025-04-05 091339.png"

oqxeahdm 发表于 2025-4-21 15:50:19

这是我的芯片图

ercircle 发表于 2025-4-21 16:24:44


在8H开天斧开发板上实测通过的例程参考下,使用P16 17当串口

页: [1] 2 3
查看完整版本: 8H系列,串口1打印问题。