dhtxs_82 发表于 2025-9-4 22:05:40

32G12K128串口设置成SPI

32G12K128串口1/2可以设置成SPI模式。经过测试,发现有些问题,来请专家和同行高手解答。要把该芯片设置成SPI模式,一要把SCON中串口模式设置为同步模式,如果设置成其它模式,则只能设置成普通串口(就是说这里优先级高于后面的SPI模式与功能设置)。二是把SCON中的“REN”位置1,否则无法产生中断,中断标志和中断入口地址都是在相应串口位置。三是把USARTCR1中的“SPMOD”和“SPIEN”都设为“1”,设置成SPI模式及启用SPI功能。四是设置好USARTCR4中的时钟频率。现在的问题是:一是,如果设置成主机,只有发送结束中断(TI),不会发生接收中断(RI),按理SPI在发送的同时,也接收数据;如果设置成从机,情况怎样没有测试,可能只有接收中断,这个应该没有问题。对于主机模式,产生TI中断时,实际并未发送结束(经示波器查看,还差一个SPI时钟同期),也就是说提前产生中断,这个是可以理解为提高系统运行速度,但此时如果向SBUF写入新的将要发送的数据,被自动放弃,这样如果要在TI中断周期内放新的数据,必须要延时一个SPI时钟周期,这是十分麻烦的。同样,在这个周期内读取从“从机”发来的数据,也是错误的(还差一位),如果主机能产生RI中断,那应该比较方便,也比较准确地收到从“从机”取回的数据。我参考了STC32的例程,我的设置跟例程无异,但例程里编了个串口1/2之间的SPI模式通信,因为我没有这个实验箱,无法验证,要想除非是我设置有错误,或者这个例程产生中断后,程序运行速率较慢(可能有其它无用程序造成延时,我用的是汇编,速率较快),无意中延时了一个SPI时钟同期,才把新的发送数据放到SBUF中去,所以没有表现出我说的问题。我的上述问题烦请专家或同行高手帮我分析一下,是哪里出了问题,还是芯片缺陷?我把汇编程序附上:
MOV      S2CON,#10H            ;开启串口收
MOV WR6,#WORD0(USART2CR1)      ;将串口2设置为SPI模式

      MOV      WR4,#WORD2(USART2CR1)
      MOV      A,#1BH                ;主机方式,高位在前,时钟空闲是为高,下降沿驱动,上升沿采样
      MOV      @DR4,R11
      INC      WR6,#01H
MOV      A,#00H
      MOV      @DR4,R11
      INC      WR6,#02H
      MOV      A,#02H                ;SPI时钟为系统时钟的16分之一(1.5MHZ速率)
      MOV      @DR4,R11

SETB   ES2    ;开串口2中断
SETB EA;开总中断
中断程序略



国芯人工智能 发表于 2025-9-4 22:08:00

关于STC32G12K128串口设置为SPI模式的问题,感谢您的详细描述。根据您提供的信息,我们可以从以下几个方面进行分析和探讨。

首先,STC32G12K128的串口模块具备多种工作模式,包括异步串行通信(UART)和同步串行通信(SPI)。在将串口配置为SPI模式时,需严格按照数据手册中的寄存器配置流程进行操作,以确保功能正确实现。

您提到的四个关键步骤是正确的:

1. SCON寄存器设置:将串口模式设置为同步模式(SM0=1, SM1=0),并开启接收使能位(REN=1),这是进入SPI模式的前提条件。
2. USARTCR1寄存器设置:设置SPMOD和SPIEN为1,以启用SPI模式和SPI功能。
3. USARTCR4寄存器设置:配置SPI时钟频率,确保主从设备之间的时序匹配。
4. 中断配置:确保中断标志位和中断向量地址正确设置,以便在发生发送或接收事件时触发中断服务程序。

然而,在实际使用中,您遇到了主机模式下仅产生TI中断、未产生RI中断的问题,并且TI中断提前于实际发送结束,导致数据发送和接收不准确。

对此,我们建议从以下几个方面进一步排查:

一、SPI模式下的中断机制

在SPI模式下,通常情况下,主机在发送数据的同时也会接收数据,因此理论上应同时触发TI和RI中断。但根据STC32系列芯片的特性,某些型号在SPI模式下可能仅支持单向传输(如仅发送或仅接收),或者中断机制存在一定的限制。

建议查阅STC32G12K128的数据手册,确认该芯片是否支持双向SPI通信,以及其在主机模式下是否支持RI中断的触发。如果该芯片不支持RI中断,那么您需要通过轮询方式读取接收缓冲区,而不是依赖中断。

二、TI中断提前触发的原因

您提到TI中断在发送尚未完成时就触发,这可能是由于以下原因:
时钟同步问题:SPI通信依赖于主设备的时钟信号,若时钟频率设置不当,可能导致TI中断提前触发。
寄存器配置错误:检查USARTCR4中的时钟分频设置是否合理,确保SPI时钟与主设备一致。
硬件延时不足:虽然您使用汇编语言编写代码,但由于SPI通信对时序要求较高,建议在TI中断处理后增加适当的延时,以确保数据完整发送。

三、程序逻辑优化建议

您提到参考了官方例程,但因缺乏实验环境无法验证。建议在代码中加入必要的延时逻辑,例如在TI中断处理后等待一个SPI时钟周期再写入新数据,以避免数据覆盖或丢失。

此外,可考虑使用状态机的方式管理SPI通信过程,确保每一步操作都符合时序要求。

四、可能的芯片缺陷或限制

目前没有公开资料显示STC32G12K128存在此类问题,但不排除个别批次芯片存在异常。建议您尝试更换其他同型号芯片,或联系STC官方技术支持获取更详细的帮助。

综上所述,建议您:

1. 确认SPI模式是否支持双向通信;
2. 检查USARTCR4寄存器的时钟配置;
3. 在TI中断处理中增加适当延时;
4. 考虑使用轮询方式读取接收数据;
5. 如仍存在问题,建议联系STC官方技术支持进一步排查。

希望以上分析对您有所帮助,如有更多技术细节,欢迎继续交流。

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

ercircle 发表于 2025-9-5 13:18:12

楼主麻烦上传个可复现问题的汇编工程~

Ayb_ice 发表于 2025-9-5 13:37:50

建议使用这种方式
MOV      @DR4+OFS,R11

ercircle 发表于 2025-9-6 14:57:27

简单翻译了下实验箱的C例程,TI处翻转P42测量信号,未复现少一个时钟问题,还是需要楼主的工程:





;---------------------------------------------------------------------*/
; --- STC MCU Limited ------------------------------------------------*/
; --- STC 1T Series MCU Demo Programme -------------------------------*/
; --- Mobile: (86)13922805190 ----------------------------------------*/
; --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
; --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
; --- Web: www.STCAI.com ---------------------------------------------*/
; --- BBS: www.STCAIMCU.com-----------------------------------------*/
; --- QQ:800003751 -------------------------------------------------*/
; 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序            */
;---------------------------------------------------------------------*/

;*************功能说明    **************

;本例程基于STC32G为主控芯片的实验箱进行编写测试。

;使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。

;edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

;USART1复用SPI与USART2复用SPI相互通信。

;通过P6口LED灯指示通信结果,P6=0x5a表示数据传输正确。

;下载时, 选择时钟 24MHz (用户可自行修改频率).

;******************************************/
$include (STC32G.inc)
; 系统工作频率定义
FOSC    EQU    24000000                      ;系统工作频率



; 位定义
S1SS       BIT   P2.2
S1MOSI   BIT   P2.3
S1MISO   BIT   P2.4
S1SCLK   BIT   P2.5

S2SS       BIT   P2.2
S2MOSI   BIT   P2.3
S2MISO   BIT   P2.4
S2SCLK   BIT   P2.5

; 中断向量表
ORG 0000H
    LJMP    MAIN                            ;复位向量
ORG 0023H
    LJMP    UART1_ISR                     ;UART1中断向量
ORG 0051H
    LJMP    UART2_ISR                     ;UART2中断向量
ORG 0100H

; 数据定义
rptr    DATA    20H                         ;读指针
wptr    DATA    21H                         ;写指针
over    BIT   22H.0                         ;传输完成标志

; 外部数据缓冲区
buffer1 XDATA 0000H
buffer2 XDATA 0100H

;/*************************************************
; 函数名: main (主函数)
; 功能: 主程序入口,实现SPI通信测试
; 参数: 无
; 返回: 无
; 说明: 初始化系统,配置SPI通信,测试数据传输
;*************************************************/
MAIN:
    ; 系统初始化
    LCALL   sys_init                        ;系统初始化
    LCALL   usart1_spi_init               ;USART1使能SPI主模式初始化
    LCALL   usart2_spi_init               ;USART2使能SPI从模式初始化
   

    ; 初始化缓冲区 (for i=0; i<128; i++)
    XRL   WR6, WR6                        ;i = 0
INIT_LOOP:
    MOV   R11, R7                        
    MOV   WR4, WR6
    ADD   WR4, #WORD0 buffer1
    MOV   DPL, R5                         ;设置DPTR
    MOV   DPH, R4
    MOVX    @DPTR, A                        ;buffer1 = i

    CLR   A                              
    MOV   WR4, WR6
    ADD   WR4, #WORD0 buffer2
    MOV   DPL, R5                         ;设置DPTR
    MOV   DPH, R4
    MOVX    @DPTR, A                        ;buffer2 = 0

    INC   WR6, #01H                     ;i++
    CMP   WR6, #080H
    JSL   INIT_LOOP

        SETB    EA                              ;使能总中断
    ; 执行SPI通信测试
    LCALL   test

    ; 主循环 (while(1))
MAIN_LOOP:
    SJMP    MAIN_LOOP
;       FUNCTION _m (END)

;/*************************************************
; 函数名: uart1_isr (UART1中断服务程序)
; 功能: 处理UART1中断,发送SPI数据
; 参数: 无
; 返回: 无
; 说明: UART1中断处理函数,实现数据发送
;*************************************************/
UART1_ISR:
                                                
PUSH   WR10
PUSH   WR6
PUSH   PSW1
PUSH   DPH            
PUSH   DPL            
                                                
    JNB      TI,UART1_MAIN_HANDLER
CPL P42                                                
CLR      TI
                                                
MOV      R7,rptr
CMP      R7,#080H

    JNC      UART1_SEND_DONE
                                                
MOV      R10,rptr
MOV      R11,R10         
INC      A               
MOV      rptr,R11         
MOVZ   WR6,R10
ADD      WR6,#WORD0 buffer1
MOV      DPL,R7         
MOV      DPH,R6         
MOVX   A,@DPTR         
MOV      SBUF,A         
                                                
    SJMP   UART1_MAIN_HANDLER
UART1_SEND_DONE:
                                                
SETB   over
                                                
                                                
UART1_MAIN_HANDLER:
                                                
JNB      RI,UART1_EXIT_HANDLER
                                                
CLR      RI
CLR   P21                                                
UART1_EXIT_HANDLER:
POP      DPL            
POP      DPH            
POP      PSW1
POP      WR6
POP      WR10
RETI
;       FUNCTION uart1_isr (END)

;/*************************************************
; 函数名: uart2_isr (UART2中断服务程序)
; 功能: 处理UART2中断,接收SPI数据
; 参数: 无
; 返回: 无
; 说明: UART2中断处理函数,实现数据接收
;*************************************************/
UART2_ISR:
                                                
PUSH   WR10
PUSH   WR6
PUSH   PSW1
PUSH   DPH            
PUSH   DPL            
                                                
    JNB      S2TI,UART2_S2TI_HANDLER
                                                
CLR      S2TI
                                                
UART2_S2TI_HANDLER:
                                                
JNB      S2RI,UART2__EXIT_HANDLER
                                                
CLR      S2RI
                                                
MOV      R10,S2BUF
MOV      R7,wptr
MOV      R11,R7         
INC      A               
MOV      wptr,R11         
MOVZ   WR6,R7
ADD      WR6,#WORD0 buffer2
MOV      DPL,R7         
MOV      DPH,R6         
MOV      @DR56,R10      
                                                
UART2__EXIT_HANDLER:
POP      DPL            
POP      DPH            

POP      PSW1
POP      WR6
POP      WR10
RETI
;       FUNCTION uart2_isr (END)

;/*************************************************
; 函数名: sys_init (系统初始化函数)
; 功能: 初始化系统时钟、端口模式等系统参数
; 参数: 无
; 返回: 无
; 说明: 设置WTST、EAXFR、CKCON,配置各端口模式
;*************************************************/
sys_init:
    MOV   WTST, #00H                      ;设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    SETB    EAXFR                           ;扩展寄存器(XFR)访问使能
    MOV   CKCON, #00H                     ;提高访问XRAM速度

    ; 设置端口模式
    MOV   P0M1, #030H                     ;设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
    MOV   P0M0, #030H
    MOV   P1M1, #032H                     ;设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
    MOV   P1M0, #032H
    MOV   P2M1, #03CH                     ;设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
    MOV   P2M0, #03CH
    MOV   P3M1, #050H                     ;设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
    MOV   P3M0, #050H
    MOV   P4M1, #00H                     ;设置P4准双向
    MOV   P4M0, #00H
    MOV   P5M1, #0CH                      ;设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
    MOV   P5M0, #0CH
    MOV   P6M1, #0FFH                     ;设置为漏极开路(实验箱加了上拉电阻到3.3V)
    MOV   P6M0, #0FFH
    MOV   P7M1, #00H                      ;设置为准双向口
    MOV   P7M0, #00H

    SETB    P20                           ;P2.0置1
    RET
;       FUNCTION sys_init (END)

;/*************************************************
; 函数名: usart1_spi_init (USART1 SPI主模式初始化函数)
; 功能: 配置USART1为SPI主模式,实现SPI通信
; 参数: 无
; 返回: 无
; 说明:
;   - 设置SPI引脚映射:P2.2/S1SS, P2.3/S1MOSI, P2.4/S1MISO, P2.5/S1SCLK
;   - 配置串口模式0,8位数据
;   - SPI参数配置:
;   * DORD=0 (MSB先行)
;   * 主机模式 (Master mode)
;   * CPOL=0, CPHA=0 (SPI模式0)
;   * 速度=SYSCLK/16
;   * 使能SPI功能
;   - 使能UART1中断
;*************************************************/
usart1_spi_init:
    ; 设置SPI引脚映射
    SETB    S1SPI_S0                     ;切换S1SPI到P2.2/S1SS,P2.3/S1MOSI,P2.4/S1MISO,P2.5/S1SCLK
    CLR   S1SPI_S1

    ; 配置串口模式
    MOV   SCON, #010H                  ;使能接收,必须设置为串口模式0

    ; 配置SPI参数
    MOV   A, #010H                     ;USARTCR1 = 0x10, 使能USART1的SPI模式
    MOV   WR6, #0FDC0H
    MOV   WR4, #07EH
    MOV   @DR4, R11

    MOV   R11, @DR4                      ;DORD=0 (数据顺序:MSB先行)
    ANL   A, #0BFH
    MOV   @DR4, R11

    MOV   R11, @DR4                      ;主机模式 (Master mode)
    ANL   A, #0FBH
    MOV   @DR4, R11

    MOV   R3, @DR4                     ;CPOL=0, CPHA=0 (SPI模式0)
    MOV   @DR4, R3

    MOV   A, #02H                        ;USARTCR4 = 0x02, SPI速度为SYSCLK/16
    MOV   WR2, #0FDC3H
    MOV   WR0, #07EH
    MOV   @DR0, R11

    MOV   R11, @DR4                      ;使能SPI功能
    ORL   A, #08H
    MOV   @DR4, R11

    ; 使能中断
    SETB    ES                           ;使能UART1中断
                                                
RET
;       FUNCTION usart1_spi_init (END)

;/*************************************************
; 函数名: usart2_spi_init (USART2 SPI从模式初始化函数)
; 功能: 配置USART2为SPI从模式,实现SPI通信
; 参数: 无
; 返回: 无
; 说明:
;   - 设置SPI引脚映射:P2.2/S2SS, P2.3/S2MOSI, P2.4/S2MISO, P2.5/S2SCLK
;   - 配置串口模式0,8位数据
;   - SPI参数配置:
;   * DORD=0 (MSB先行)
;   * 从机模式 (Slave mode)
;   * CPOL=0, CPHA=0 (SPI模式0)
;   * 速度=SYSCLK/16 (由主机控制)
;   * 使能SPI功能
;   - 使能UART2中断
;*************************************************/
usart2_spi_init:
    ; 设置SPI引脚映射
    SETB    S2SPI_S0                     ;切换S2SPI到P2.2/S2SS,P2.3/S2MOSI,P2.4/S2MISO,P2.5/S2SCLK
    CLR   S2SPI_S1

    ; 配置串口模式
    MOV   S2CON, #010H                   ;使能接收,必须设置为串口模式0

    ; 配置SPI参数
    MOV   A, #010H                     ;USART2CR1 = 0x10, 使能USART2的SPI模式
    MOV   WR6, #0FDC8H
    MOV   WR4, #07EH
    MOV   @DR4, R11         
                                                
    MOV   R11, @DR4                      ;DORD=0 (数据顺序:MSB先行)
    ANL   A, #0BFH
    MOV   @DR4, R11         
                                                
    MOV   R11, @DR4                      ;从机模式 (Slave mode)
    ORL   A, #04H
    MOV   @DR4, R11         

    MOV   R3, @DR4                     ;CPOL=0, CPHA=0 (SPI模式0)
    MOV   @DR4, R3

    MOV   A, #02H                        ;USART2CR4 = 0x02, SPI速度为SYSCLK/16         
    MOV   WR2, #0FDCBH
    MOV   WR0, #07EH
    MOV   @DR0, R11

    MOV   R11, @DR4                      ;使能SPI功能
    ORL   A, #08H
    MOV   @DR4, R11

    ; 使能中断
    SETB    ES2                            ;使能UART2中断

    RET
;       FUNCTION usart2_spi_init (END)

;/*************************************************
; 函数名: test (SPI通信测试函数)
; 功能: 执行SPI通信测试,验证数据传输正确性
; 参数: 无
; 返回: 无
; 说明: 发送数据并校验接收,控制LED指示结果
;*************************************************/
test:
                                                
                                                
                                                
    CLR   A                              
    MOV   wptr, R11                     ;wptr = 0
                                                
                                                
    CLR   over                            ;over = 0
                                                

CLR      S1SS
                                                
MOV      A,#01H         
MOV      rptr,R11         
MOV      DPTR,#WORD0 buffer1
MOVX   A,@DPTR         
MOV      SBUF,A         
                                                
TEST_WAIT_LOOP:
    JNB      over,TEST_WAIT_LOOP
                                                
SETB   S1SS
                                                
MOV      R10,#05AH
;---- Variable 'ret' assigned to Register 'R10' ----
                                                
XRL      R7,R7
;---- Variable 'i' assigned to Register 'R7' ----
TEST_CHECK_LOOP:
                                                
    ; 数据校验:比较buffer1和buffer2
    MOVZ    WR4, R7
    ADD   WR4, #WORD0 buffer2
    MOV   DPL, R5                        ;设置DPTR指向buffer2
    MOV   DPH, R4
    MOV   R6, @DR56                      ;读取buffer2

    MOVZ    WR4, R7
    ADD   WR4, #WORD0 buffer1
    MOV   DPL, R5                        ;设置DPTR指向buffer1
    MOV   DPH, R4
    MOVX    A, @DPTR                     ;读取buffer1
    CMP   R11, R6                        ;比较数据
JE       TEST_DATA_MATCH
                                                
MOV      R10,#0FEH
                                                
SJMP   TEST_LOOP_END
                                                
TEST_DATA_MATCH:
INC      R7,#01H
CMP      R7,#080H
JC       TEST_CHECK_LOOP
TEST_LOOP_END:
                                                
    ; 检查测试结果
    CMP   R10, #05AH                      ;ret == 0x5a?
    JNE   NO_LED                        ;如果不等于,跳过点亮LED
    CLR   P20                           ;点亮LED指示成功
NO_LED:
RET
;       FUNCTION test (END)

END

dhtxs_82 发表于 2025-9-11 22:50:33

首先感谢各位的热心指导!关于二楼的建议,一是延时是可以实现,但这是没有办法的办法,是弥补硬件的缺陷。二是,串口设置成SPI后,其时钟是系统时间的分频,所以同步是不容置疑的。三是轮询也好,状态机也罢,中断提前且没有FIFO的前提下,除了加入延时外别无它法,否则总要出现错误。关于三楼的建议,因为串口缓冲都是特殊功能寄存器,其寻址方式只能是直接,所以您建议的间接寻址方式是行不通的。关于二、四楼的建议,我下面上传工程及S2_SPI中断与时钟示波器图附上,请指导!您在实验箱中的例程,可能是SPI时钟接近系统时钟,所以中断提前被指令延时掩盖。

;这是串口2设置成SPI模式测量程序,系统时钟为内置24MHz
;包含本头文件后,不用另外再包含"REG51.H"
#include <STC32Ghb.H>

        DACO        EQU        P1.3        ;SPI2_DAC的出
        DACC        EQU        P1.5        ;SPI2_DAC的时钟
        TSDN        EQU        P5.4        ;调试灯
       
        ORG        0000H
        JMP        SDFW
       
        ORG        000BH
        JMP        TMR0_VECTOR
        RETI                        ;定时0中断

        ORG        0043H
        JMP        S2_SPI
        RETI                        ;串口2中断

        ORG        0280H
       
;串口2SPI中断(3区)
S2_SPI:        JBC        S2TI,S2_SP1
        CLR        S2RI                ;是接收中断,清除标志,也不读取数据
        RETI
S2_SP1:        CPL        TSDN                ;是发送中断,测试灯反向(灭与亮轮换)
        RETI

;定时0中断,1.25ms
TMR0_VECTOR:
        MOV        S2BUF,#5AH
        RETI

SDFW:        MOV        P1,#0E3H        ;P1.7~0OIOOOOOO,11100011
        MOV        P1M1,#00H        ;P1.3为S2MOSI引脚,P1.5为SD2CLK
        MOV        P1M0,#0AEH
        MOV        P5,#00H                ;P5.4为测试灯
        MOV        P5M1,#00H
        MOV        P5M0,#0FFH        ;除.4外,其它都元引脚
        MOV        P_SW1,#8CH        ;串口1在1.6~7中,SPI在3.2~4中
        MOV        P_SW2,#80H        ;串口3/4选在P0上,扩展特殊功能寄存器可以改写
        MOV        P_SW3,#00H        ;串口2(SPI)选在P1.3~5
        MOV        WTST,#00H        ;系统速率最快
        MOV   CKCON,#0x00        ;提高访问XRAM速度
        MOV        SPH,#0FH
        MOV        SP,#00H                ;堆栈设在4K内存的最后一页
        MOV        DR60,#0F00H
        MOV        PSW,#00H
        MOV        TH0,#73H        ;不分频,1.25ms
        MOV        TL0,#60H
        MOV        AUXR,#097H        ;定时0/2不分频,1分频,2用于串口1/3/4,允许片外RAM
        CLR        A
        MOV        WR6,#WORD0(TM0PS)        ;定时0预分频为
        MOV        WR4,#WORD2(TM0PS)
        MOV        @DR4,R11        ; A=R11
        MOV        S2CON,#10H        ;串口2用作SPI(异步串口模式设置为0__同步方式),接收使能
        MOV        WR6,#WORD0(USART2CR1)        ;将串口2设置为SPI模式
        MOV        WR4,#WORD2(USART2CR1)
        MOV        A,#1BH                ;主机方式,高位在前,时钟空闲是为高,下降沿驱动,上升沿采样
        MOV        @DR4,R11
        INC        WR6,#01H        ;清除USART2CR2内容
        MOV        A,#00H
        MOV        @DR4,R11
        INC        WR6,#02H        ;设置USART2CR4
        MOV        A,#02H                ;SPI时钟为系统时钟的16分之一(系统时钟选为24MHz,SPI时钟为1.5MHZ速率)
        MOV        @DR4,R11
        MOV        WR6,#WORD0(S2CFG)        ;按说明书要求必须设置为1,不然可能会出现意想不到的情况
        MOV        WR4,#WORD2(S2CFG)
        MOV        A,#01H
        MOV        @DR4,R11
        MOV        TMOD,#00H        ;定时0\1为16位自动重装定时器
        MOV        TCON,#50H        ;外中断0\1上下降沿触发
        MOV        IE,#082H        ;开总中断,定时1
        MOV        IE2,#01H        ;开串口2中断
        JMP        $

        END

dhtxs_82 发表于 2025-9-13 20:49:42

ercircle 发表于 2025-9-6 14:57
简单翻译了下实验箱的C例程,TI处翻转P42测量信号,未复现少一个时钟问题,还是需要楼主的工程:




你好:非常感谢您的指导.按您的要求,我已经回复了!如果方便的话,麻烦您看一下,看来是芯片的缺陷啦

dhtxs_82 发表于 2025-9-13 20:50:24

国芯人工智能 发表于 2025-9-4 22:08
关于STC32G12K128串口设置为SPI模式的问题,感谢您的详细描述。根据您提供的信息,我们可以从以下几个方面 ...

你好:非常感谢您的指导.按您的要求,我已经回复了!如果方便的话,麻烦您看一下,看来是芯片的缺陷啦

ercircle 发表于 2025-9-13 21:59:05

dhtxs_82 发表于 2025-9-13 20:50
你好:非常感谢您的指导.按您的要求,我已经回复了!如果方便的话,麻烦您看一下,看来是芯片的缺陷啦 ...
可复现,调换下中断设置顺序,开总中断放在最后,正常,楼主试试:

;这是串口2设置成SPI模式测量程序,系统时钟为内置24MHz
;包含本头文件后,不用另外再包含"REG51.H"
$include (STC32G.inc)

        DACO        EQU        P1.3        ;SPI2_DAC的出
        DACC        EQU        P1.5        ;SPI2_DAC的时钟
        TSDN        EQU        P5.4        ;调试灯
       
        ORG        0000H
        JMP        SDFW
       
        ORG        000BH
        JMP        TMR0_VECTOR
        RETI                        ;定时0中断

        ORG        0043H
        JMP        S2_SPI
        RETI                        ;串口2中断

        ORG        0280H
       
;串口2SPI中断(3区)
S2_SPI:        JBC        S2TI,S2_SP1
        CLR        S2RI                ;是接收中断,清除标志,也不读取数据
        RETI
S2_SP1:        CPL        TSDN                ;是发送中断,测试灯反向(灭与亮轮换)
        RETI

;定时0中断,1.25ms
TMR0_VECTOR:
        MOV        S2BUF,#5AH
        RETI

SDFW:       
        MOV        P_SW2,#80H        ;串口3/4选在P0上,扩展特殊功能寄存器可以改写
        MOV        WTST,#00H        ;系统速率最快
        MOV CKCON,#0x00        ;提高访问XRAM速度
        MOV        SPH,#0FH
        MOV        SP,#00H                ;堆栈设在4K内存的最后一页
        MOV        DR60,#0F00H
        MOV        PSW,#00H
       
       
        MOV        P1,#0E3H        ;P1.7~0OIOOOOOO,11100011
        MOV        P1M1,#00H        ;P1.3为S2MOSI引脚,P1.5为SD2CLK
        MOV        P1M0,#0AEH

       
        MOV        P5,#00H                ;P5.4为测试灯
        MOV        P5M1,#00H
        MOV        P5M0,#0FFH        ;除.4外,其它都元引脚
        MOV        P_SW1,#8CH        ;串口1在1.6~7中,SPI在3.2~4中
       
        MOV        P_SW3,#00H        ;串口2(SPI)选在P1.3~5
       

        MOV        TH0,#73H        ;不分频,1.25ms
        MOV        TL0,#60H
        MOV        AUXR,#097H        ;定时0/2不分频,1分频,2用于串口1/3/4,允许片外RAM
        CLR        A
        MOV        WR6,#WORD0(TM0PS)        ;定时0预分频为
        MOV        WR4,#WORD2(TM0PS)
        MOV        @DR4,R11        ; A=R11
        MOV        S2CON,#10H        ;串口2用作SPI(异步串口模式设置为0__同步方式),接收使能
        MOV        WR6,#WORD0(USART2CR1)        ;将串口2设置为SPI模式
        MOV        WR4,#WORD2(USART2CR1)
        MOV        A,#1BH                ;主机方式,高位在前,时钟空闲是为高,下降沿驱动,上升沿采样
        MOV        @DR4,R11
        INC        WR6,#01H        ;清除USART2CR2内容
        MOV        A,#00H
        MOV        @DR4,R11
        INC        WR6,#02H        ;设置USART2CR4
        MOV        A,#02H                ;SPI时钟为系统时钟的16分之一(系统时钟选为24MHz,SPI时钟为1.5MHZ速率)
        MOV        @DR4,R11
        MOV        WR6,#WORD0(S2CFG)        ;按说明书要求必须设置为1,不然可能会出现意想不到的情况
        MOV        WR4,#WORD2(S2CFG)
        MOV        A,#01H
        MOV        @DR4,R11
        MOV        TMOD,#00H        ;定时0\1为16位自动重装定时器
        MOV        TCON,#50H        ;外中断0\1上下降沿触发
        MOV        IE2,#01H        ;开串口2中断
        MOV        IE,#02H          ;开定时1
        SETB EA         ;开总中断
        JMP        $

        END

dhtxs_82 发表于 2025-9-22 19:48:46

ercircle 发表于 2025-9-13 21:59
可复现,调换下中断设置顺序,开总中断放在最后,正常,楼主试试:




老师:晚上好!按你的提示,我做了测试,并没有出现你所示的那样的图,还是老样子。我在想开总中断,先后应该不会有影响吧。我献上图,请检阅!
页: [1] 2
查看完整版本: 32G12K128串口设置成SPI