战术吃瓜 发表于 7 天前

新手,isp串口助手接收不到数据 | 已给串口1的参考程序,波特率公式用新的

芯片型号IAP15F2K61S2,程序见下,
按下s1,计数功能正常,
按下s2发送数据,串口接收缓存区无显示,
重新按下s1,计数功能不工作,请问如何解决


ORG 0000H
LJMP MAIN

ORG 0100H
MAIN:
    MOV SP, #70H       ; 设置堆栈指针
    ACALL INIT_UART    ; 初始化串口
    MOV R5, #0         ; 初始化计数器
    ACALL DISPLAY      ; 初始显示00

MAIN_LOOP:
    ACALL KEY_SCAN   ; 扫描按键
    SJMP MAIN_LOOP   ; 主循环


INIT_UART:
    ANL PCON, #7FH   ; 波特率不倍速 (SMOD=0)
    MOV TMOD, #20H   ; 定时器1模式2 (自动重装)
    MOV TH1, #0FDH   ; 波特率9600 (11.0592MHz晶振)
    MOV TL1, #0FDH
    SETB TR1         ; 启动定时器1
    MOV SCON, #50H   ; 串口模式1,允许接收
    CLR TI             ; 清除发送中断标志
    RET

; 数码管显示
DISPLAY:
    MOV A, R5          ; 读取计数值
    MOV B, #10         ; 除以10分离十位和个位
    DIV AB
    MOV R6, A         
    MOV R7, B         
   
    ; P0显示十位
    MOV DPTR, #TABA
    MOV A, R6
    MOVC A, @A+DPTR
    MOV P0, A
   
    ; P2显示个位
    MOV DPTR, #TAB
    MOV A, R7
    MOVC A, @A+DPTR
    MOV P2, A
    RET

; 按键扫描
KEY_SCAN:
    ; 检测S1按键 (P3.2)
    JNB P3.2, KEY_S1_PRESSED
    ; 检测S2按键 (P3.3)
    JNB P3.3, KEY_S2_PRESSED
    RET

KEY_S1_PRESSED:
    ACALL DELAY_10MS   ; 延时消抖
    JB P3.2, EXIT_S1   ; 确认按键按下
   
    ; 等待按键释放
WAIT_S1_RELEASE:
    ACALL DISPLAY      ; 保持显示更新
    JNB P3.2, WAIT_S1_RELEASE
   
    ; 计数器加1 (00-99循环)
    INC R5
    MOV A, R5
    CJNE A, #100, UPDATE_DISPLAY
    MOV R5, #0         ; 达到100则归零
   
UPDATE_DISPLAY:
    ACALL DISPLAY      ; 更新显示
EXIT_S1:
    RET

KEY_S2_PRESSED:
    ACALL DELAY_10MS   ; 延时消抖
    JB P3.3, EXIT_S2   ; 确认按键按下
   
    ; 等待按键释放
WAIT_S2_RELEASE:
    ACALL DISPLAY      ; 保持显示更新
    JNB P3.3, WAIT_S2_RELEASE
   
    ; 发送当前计数值 (ASCII格式)
    MOV A, R5
    MOV B, #10
    DIV AB             ; A=十位, B=个位
    ADD A, #30H      ; 十位转ASCII
    ACALL SEND_CHAR    ; 发送十位
    MOV A, B
    ADD A, #30H      ; 个位转ASCII
    ACALL SEND_CHAR    ; 发送个位
   
    ; 发送换行符便于查看
    MOV A, #0DH      ; 回车
    ACALL SEND_CHAR
    MOV A, #0AH      ; 换行
    ACALL SEND_CHAR
EXIT_S2:
    RET

; 串口发送函数
SEND_CHAR:
    MOV SBUF, A      ; 发送字符
    JNB TI, $          ; 等待发送完成
    CLR TI             ; 清除发送标志
    RET

; 10ms延时消抖
DELAY_10MS:
    MOV R0, #20
DL1:
    MOV R1, #250
DL2:
    DJNZ R1, DL2
    DJNZ R0, DL1
    RET

; 数码管段码表
; P2段码表 (用于个位显示)
TAB:   DB 88H,0EBH,4CH,49H,2BH,19H,18H,0CBH,08H,09H
; P0段码表 (用于十位显示)
TABA:DB 11H,0D7H,32H,92H,0D4H,98H,18H,0D3H,10H,90H

END

战术吃瓜 发表于 7 天前

尝试将串口助手接收缓存区更换为hex模式,仍有此问题,附件为hex程序

神农鼎 发表于 7 天前




//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz


#include "reg51.h"
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;

#define FOSC 11059200L          //系统频率
#define BAUD 115200             //串口波特率

#define NONE_PARITY   0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY   2       //偶校验
#define MARK_PARITY   3       //标记校验
#define SPACE_PARITY    4       //空白校验

#define PARITYBIT NONE_PARITY   //定义校验位

sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

sfr AUXR= 0x8e;               //辅助寄存器

sfr P_SW1   = 0xA2;             //外设功能切换寄存器1

#define S1_S0 0x40            //P_SW1.6
#define S1_S1 0x80            //P_SW1.7

sbit P22 = P2^2;

bit busy;

void SendData(BYTE dat);
void SendString(char *s);

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;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;

    ACC = P_SW1;
    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
    P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)
   
//ACC = P_SW1;
//ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0
//ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)
//P_SW1 = ACC;
//
//ACC = P_SW1;
//ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=1
//ACC |= S1_S1;               //(P1.6/RxD_3, P1.7/TxD_3)
//P_SW1 = ACC;

#if (PARITYBIT == NONE_PARITY)
    SCON = 0x50;                //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
    SCON = 0xda;                //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
    SCON = 0xd2;                //9位可变波特率,校验位初始为0
#endif

    AUXR = 0x40;                //定时器1为1T模式
    TMOD = 0x00;                //定时器1为模式0(16位自动重载)
    TL1 = (65536 - (FOSC/4/BAUD));   //设置波特率重装值
    TH1 = (65536 - (FOSC/4/BAUD))>>8;
    TR1 = 1;                  //定时器1开始启动
    ES = 1;                     //使能串口中断
    EA = 1;

    SendString("STC15F2K60S2\r\nUart Test !\r\n");
    while(1);
}

/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4
{
    if (RI)
    {
      RI = 0;               //清除RI位
      P0 = SBUF;            //P0显示串口数据
      P22 = RB8;            //P2.2显示校验位
    }
    if (TI)
    {
      TI = 0;               //清除TI位
      busy = 0;               //清忙标志
    }
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
    while (busy);               //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    if (P)                      //根据P来设置校验位
    {
#if (PARITYBIT == ODD_PARITY)
      TB8 = 0;                //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
      TB8 = 1;                //设置校验位为1
#endif
    }
    else
    {
#if (PARITYBIT == ODD_PARITY)
      TB8 = 1;                //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
      TB8 = 0;                //设置校验位为0
#endif
    }
    busy = 1;
    SBUF = ACC;               //写数据到UART数据寄存器
}

/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
      SendData(*s++);         //发送当前字符
    }
}


神农鼎 发表于 7 天前




//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz


#define NONE_PARITY   0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY   2       //偶校验
#define MARK_PARITY   3       //标记校验
#define SPACE_PARITY    4       //空白校验

#define PARITYBIT NONE_PARITY   //定义校验位

//-----------------------------------------

AUXR      EQU   08EH      //辅助寄存器

P_SW1       EQU   0A2H      //外设功能切换寄存器1
S1_S0       EQU   40H         //P_SW1.6
S1_S1       EQU   80H         //P_SW1.7

BUSY      BIT   20H.0       //忙标志位

P0M1    DATA    0x93            ; P0M1.n,P0M0.n   =00--->Standard,    01--->push-pull
P0M0    DATA    0x94            ;                   =10--->pure input,11--->open drain
P1M1    DATA    0x91            ; P1M1.n,P1M0.n   =00--->Standard,    01--->push-pull
P1M0    DATA    0x92            ;                   =10--->pure input,11--->open drain
P2M1    DATA    0x95            ; P2M1.n,P2M0.n   =00--->Standard,    01--->push-pull
P2M0    DATA    0x96            ;                   =10--->pure input,11--->open drain
P3M1    DATA    0xB1            ; P3M1.n,P3M0.n   =00--->Standard,    01--->push-pull
P3M0    DATA    0xB2            ;                   =10--->pure input,11--->open drain
P4M1    DATA    0xB3            ; P4M1.n,P4M0.n   =00--->Standard,    01--->push-pull
P4M0    DATA    0xB4            ;                   =10--->pure input,11--->open drain
P5M1    DATA    0xC9            ; P5M1.n,P5M0.n   =00--->Standard,    01--->push-pull
P5M0    DATA    0xCA            ;                   =10--->pure input,11--->open drain
P6M1    DATA    0xCB            ; P6M1.n,P6M0.n   =00--->Standard,    01--->push-pull
P6M0    DATA    0xCC            ;                   =10--->pure input,11--->open drain
P7M1    DATA    0xE1            ;
P7M0    DATA    0xE2            ;

//-----------------------------------------
    ORG   0000H
    LJMPMAIN

    ORG   0023H
    LJMPUART_ISR
//-----------------------------------------
    ORG   0100H
MAIN:
    CLR   A
    MOV   P0M1, A   ;设置为准双向口
    MOV   P0M0, A
    MOV   P1M1, A   ;设置为准双向口
    MOV   P1M0, A
    MOV   P2M1, A   ;设置为准双向口
    MOV   P2M0, A
    MOV   P3M1, A   ;设置为准双向口
    MOV   P3M0, A
    MOV   P4M1, A   ;设置为准双向口
    MOV   P4M0, A
    MOV   P5M1, A   ;设置为准双向口
    MOV   P5M0, A
    MOV   P6M1, A   ;设置为准双向口
    MOV   P6M0, A
    MOV   P7M1, A   ;设置为准双向口
    MOV   P7M0, A

    CLR   BUSY
    CLR   EA
    MOV   SP,#3FH
   
    MOV   A,P_SW1
    ANL   A,#03FH               //S1_S0=0 S1_S1=0
    MOV   P_SW1,A               //(P3.0/RxD, P3.1/TxD)
   
//MOV   A,P_SW1
//ANL   A,#03FH               //S1_S0=1 S1_S1=0
//ORL   A,#S1_S0            //(P3.6/RxD_2, P3.7/TxD_2)
//MOV   P_SW1,A
//
//MOV   A,P_SW1
//ANL   A,#03FH               //S1_S0=0 S1_S1=1
//ORL   A,#S1_S1            //(P1.6/RxD_3, P1.7/TxD_3)
//MOV   P_SW1,A

#if (PARITYBIT == NONE_PARITY)
    MOV   SCON,#50H             //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
    MOV   SCON,#0DAH            //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
    MOV   SCON,#0D2H            //9位可变波特率,校验位初始为0
#endif

//-------------------------------
    MOV   AUXR,#40H             //定时器1为1T模式
    MOV   TMOD,#00H             //定时器1为模式0(16位自动重载)
    MOV   TL1,#0E8H             //设置波特率重装值(65536-11059200/4/115200)
    MOV   TH1,#0FFH
    SETBTR1                   //定时器1开始运行
    SETBES                  //使能串口中断
    SETBEA

    MOV   DPTR,#TESTSTR         //发送测试字符串
    LCALL SENDSTRING

    SJMP$
;-----------------------------------------
TESTSTR:
    DB"STC15F2K60S2 Uart1 Test !",0DH,0AH,0

;/*----------------------------
;UART 中断服务程序
;----------------------------*/
UART_ISR:
    PUSHACC
    PUSHPSW
    JNB   RI,CHECKTI            //检测RI位
    CLR   RI                  //清除RI位
    MOV   P0,SBUF               //P0显示串口数据
    MOV   C,RB8
    MOV   P2.2,C                //P2.2显示校验位
CHECKTI:
    JNB   TI,ISR_EXIT         //检测TI位
    CLR   TI                  //清除TI位
    CLR   BUSY                  //清忙标志
ISR_EXIT:
    POP   PSW
    POP   ACC
    RETI

;/*----------------------------
;发送串口数据
;----------------------------*/
SENDDATA:
    JB    BUSY,$                //等待前面的数据发送完成
    MOV   ACC,A               //获取校验位P (PSW.0)
    JNB   P,EVEN1INACC          //根据P来设置校验位
ODD1INACC:
#if (PARITYBIT == ODD_PARITY)
    CLR   TB8                   //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
    SETBTB8                   //设置校验位为1
#endif
    SJMPPARITYBITOK
EVEN1INACC:
#if (PARITYBIT == ODD_PARITY)
    SETBTB8                   //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
    CLR   TB8                   //设置校验位为0
#endif
PARITYBITOK:                  //校验位设置完成
    SETBBUSY
    MOV   SBUF,A                //写数据到UART数据寄存器
    RET

;/*----------------------------
;发送字符串
//----------------------------*/
SENDSTRING:
    CLR   A
    MOVCA,@A+DPTR             //读取字符
    JZ    STRINGEND             //检测字符串结束标志
    INC   DPTR                  //字符串地址+1
    LCALL SENDDATA            //发送当前字符
    SJMPSENDSTRING
STRINGEND:
    RET
//-----------------------------------------
    END


神农鼎 发表于 7 天前




void Uart1_Isr(void) interrupt 4
{
        if (TI)                                //检测串口1发送中断
        {
                TI = 0;                        //清除串口1发送中断请求位
        }
        if (RI)                                //检测串口1接收中断
        {
                RI = 0;                        //清除串口1接收中断请求位
        }
}

void Uart1_Init(void)        //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x40;                //定时器时钟1T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设置定时器模式
        TL1 = 0xE0;                        //设置定时初始值
        TH1 = 0xFE;                        //设置定时初始值
        ET1 = 0;                        //禁止定时器中断
        TR1 = 1;                        //定时器1开始计时
        ES = 1;                                //使能串口1中断
}



神农鼎 发表于 7 天前




        ORG                0023H
UART1_ISR:
        JNB                TI,CHKUART1RI        ;检测串口1发送中断
        CLR                TI                                ;清除串口1发送中断请求位
CHKUART1RI:
        JNB                RI,UART1ISREXIT        ;检测串口1接收中断
        CLR                RI                                ;清除串口1接收中断请求位
UART1ISREXIT:
        RETI

UART1_INIT:                                        ;9600bps@11.0592MHz
        MOV                SCON,#50H                ;8位数据,可变波特率
        ORL                AUXR,#40H                ;定时器时钟1T模式
        ANL                AUXR,#0FEH                ;串口1选择定时器1为波特率发生器
        ANL                TMOD,#0FH                ;设置定时器模式
        MOV                TL1,#0E0H                ;设置定时初始值
        MOV                TH1,#0FEH                ;设置定时初始值
        CLR                ET1                                ;禁止定时器中断
        SETB        TR1                                ;定时器1开始计时
        SETB        ES                                ;使能串口1中断
        RET


神农鼎 发表于 7 天前

https://www.stcaimcu.com/data/download/Datasheet/STC15-CN.pdf

最新 数据手册

神农鼎 发表于 7 天前





战术吃瓜 发表于 3 天前

神农鼎 发表于 2025-6-22 17:45


感谢大佬{:baoquan:}
页: [1]
查看完整版本: 新手,isp串口助手接收不到数据 | 已给串口1的参考程序,波特率公式用新的