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时才能正常打印
在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引脚上无法打印的问题。如果问题仍然存在,建议进一步检查硬件连接和芯片的寄存器配置,确保所有设置都正确无误。
[本文内容由国芯人工智能辅助生成,仅供参考] 寄存器方式中,没有设置P16、P17的IO口模式,默认是高阻默认,不能通讯。
P30和P31出于需要下载程序的考虑, 上电默认模式就是准双向口,所以不用设置也可以通讯。 王昱顺 发表于 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口模式了吗
王昱顺 发表于 2025-4-18 18:33
寄存器方式中,没有设置P16、P17的IO口模式,默认是高阻默认,不能通讯。
P30和P31出于需要下载程序的考虑 ...
你好,麻烦解决下我的问题,我尝试设置为推挽模式,或者使用寄存器直接配置,都无法使用P1.6 P1.7进行串口打印,在电脑的串口助手都无法显示打印的消息 请提供完整的测试项目,这样方便分析。
寄存器版本明显设置错误,选择 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脚位是否选择正确,有没有虚焊或者短路,有没有其它元器件干扰通信信号?
乘风飞扬 发表于 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 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" 这是我的芯片图
在8H开天斧开发板上实测通过的例程参考下,使用P16 17当串口