我正在使用 MPLAB X IDE V6,20 和 XC32 V4.35 编译器开发 PIC32MM056GPM048。
我使用MCC生成代码,仅使用UART2引脚,并且没有对时钟进行修改。
我遇到了时钟初始化函数的第一个问题,该问题卡住了一段时间。
void CLK_Initialize( void )
{
/* unlock system for clock configuration */
SYSKEY = 0x00000000U;
SYSKEY = 0xAA996655U;
SYSKEY = 0x556699AAU;
/* Even though SPLL is selected in FNOSC, Harmony generates #pragma code as FRCDIV, not as SPLL, in "initilization.c".
* Switching to SPLL is done here after appropriate setting of SPLLCON register.
* This is done to ensure we don't end-up changing PLL setting when it is ON. */
/* Configure SPLL */
/* DIV_1, MUL_3, PLLSRC= FRC */
SPLLCON = 0x10080;
/* Now switch to the PLL source */
OSCCON = OSCCON | 0x00000101U; //NOSC = SPLL, initiate clock switch (OSWEN = 1)
/* Wait for PLL to be ready and clock switching operation to complete */
uint32_t status = CLKSTATbits.SPLLRDY;
status |= CLKSTATbits.SPDIVRDY;
while((OSCCONbits.OSWEN != 0U) || (status == 0U))
{
status = CLKSTATbits.SPLLRDY;
status |= CLKSTATbits.SPDIVRDY;
}
/* Peripheral Module Disable Configuration */
PMD1 = 0x101001U;
PMD2 = 0xf000007U;
PMD3 = 0x1ff00U;
PMD4 = 0x7U;
PMD5 = 0x1070705U;
PMD6 = 0x1U;
PMD7 = 0x0U;
/* Lock system since done with clock configuration */
SYSKEY = 0x33333333U;}
对于这个问题,我像这样修复了initialization.c中的
CLKSTATbits.SPDIVRDY = 1;
,这似乎有效,但看起来很垃圾。
void SYS_Initialize ( void* data )
{
/* MISRAC 2012 deviation block start */
/* MISRA C-2012 Rule 2.2 deviated in this file. Deviation record ID - H3_MISRAC_2012_R_2_2_DR_1 */
/* Start out with interrupts disabled before configuring any modules */
(void)__builtin_disable_interrupts();
CLKSTATbits.SPDIVRDY = 1;
CLK_Initialize();
GPIO_Initialize();
UART2_Initialize();
/* MISRAC 2012 deviation block start */
/* Following MISRA-C rules deviated in this block */
/* MISRA C-2012 Rule 11.3 - Deviation record ID - H3_MISRAC_2012_R_11_3_DR_1 */
/* MISRA C-2012 Rule 11.8 - Deviation record ID - H3_MISRAC_2012_R_11_8_DR_1 */
/* MISRAC 2012 deviation block end */
EVIC_Initialize();
/* Enable global interrupts */
(void)__builtin_enable_interrupts();
/* MISRAC 2012 deviation block end */}
在我的 main.c 上添加一些行后,我遇到了第二个问题:
#include <stddef.h> // Defines NULL
#include <stdbool.h> // Defines true
#include <stdlib.h> // Defines EXIT_FAILURE
#include "definitions.h" // SYS function prototypes
uint8_t buffer[] = "Test"; uint8_t buffer2[] = "Test5";
void delay(int nb);
int main ( void ) {
/* Initialize all modules */
SYS_Initialize ( NULL );
int pbClk;
pbClk = 24000000 / 2; // Our PBCLK2 divider was set to 1, so PBCLK2 is exactly half the speed of the system clock, or 12Mhz
U2MODE = 0; // Set UART 5 off prior to setting it up
U2MODEbits.BRGH = 0; // We want standard speed mode. Not necessary as we just set
U5MODE to 0 so this is just for explanation's sake
U2BRG = pbClk / (16 * 38400) - 1;// This is the formula straight from the datasheet
U2STA = 0; // Disable the TX and RX pins, clear all flags
U2STAbits.UTXEN = 1; // Enable the TX pin
//U2STAbits.URXEN = 1; // Enable the RX pin
U2MODEbits.PDSEL = 0; // PDSEL controls how many data bits and how many parity bits we want, this is the default of 8-bit data, no parity bits that most terminals use
U2MODEbits.STSEL = 0; // STSEL controls how many stop bits we use, let's use the default of 1
U2MODEbits.ON = 1; // Turn on the UART 2 peripheral
int test = 0;
while ( true )
{
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
if(test ==0){
UART2_Write(&buffer[0],sizeof(buffer));
//U2STAbits.UTXEN = 0; // Enable the TX pin
test = 1;
}else{
UART2_Write(&buffer2[0],sizeof(buffer2));
test = 0;
}
delay(1200);
}
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE ); }
void delay(int nb) {
if(nb == 0)
return;
int i = 0;
do
i= i + 1;
while(i < nb); }
有时候,当我启动代码时,我陷入了“crt0.S”第 119 行(_reset 中的
jal _startup
),我不明白为什么。当我遇到这个错误时,我什至没有通过 SYS_Initialize
我的 main.c.
/*********************************************************************
*
* C Runtime Startup
*
*********************************************************************
* Filename: crt0.S
*
* Processor: PIC32
*
* Compiler: MPLAB XC32
* MPLAB X IDE
* Company: Microchip Technology Inc.
********************************************************************/
#include "xc.h"
#include <cp0defs.h>
#ifdef __LIBBUILD__
# Replace the standard debugging information with a simple filename. This
# prevents the library build directory from showing up in MPLAB IDE. It
# also effectively disables source-line debugging.
.file 1 "libpic32/startup/crt0.S"
.loc 1 0
#endif
#if (__XC32_VERSION > 1000) && !defined(CPP_INIT)
#define CPP_INIT
#endif
#if !defined(PIC32_SRS_SET_COUNT)
# if defined(__PIC32_SRS_SET_COUNT)
# define PIC32_SRS_SET_COUNT __PIC32_SRS_SET_COUNT
# else
# warning PIC32_SRS_SET_COUNT not defined on build line
# define PIC32_SRS_SET_COUNT 2
# endif
#endif
#if defined(__PIC32MX) || defined(__PIC32MM) || defined(__PIC32MZ)
#define INIT_DATA 1
#endif
/* This file contains 32-bit assembly code */
.set nomips16
##################################################################
# Entry point of the entire application
##################################################################
.section .reset,code,keep
.align 2
.set noreorder
.ent _reset
############################
# Begin ISA switching code #
############################
#if defined (__mips_micromips)
.set micromips
#endif
#if (defined(__PIC32_HAS_MICROMIPS)) && (defined(__PIC32_HAS_MIPS32R2))
_reset:
.word 0x10000003 /* MIPS32: branch forward 0x10 bytes from here */
/* MicroMIPS: ADDI32 $0, $0, 0x0007 (nop) */
/* DO NOT change the relative branch */
.word 0x00000000 /* NOP */
__reset_micromips_isa:
.set micromips
jal _startup
nop
.align 2
/* Device not in proper ISA mode */
.set nomicromips
__reset_switch_isa:
jal _startup
nop
#else
_reset:
jal _startup
nop
#endif /* __PIC32_HAS_MICROMIPS */
.align 2
.end _reset
.globl _reset
.size _reset, .-_reset
.section .reset.startup,code,keep
.align 2
.set noreorder
#if defined (__mips_micromips)
.set micromips
#else
.set nomicromips
#endif
############################
# End ISA switching code #
############################
##################################################################
# Startup code
##################################################################
.align 2
.globl _startup
.set noreorder
.ent _startup
_startup:
##################################################################
# If entered because of an NMI, jump to the NMI handler.
##################################################################
mfc0 k0,_CP0_STATUS
ext k0,k0,19,1 # Extract NMI bit
beqz k0,_no_nmi
nop
la k0,_nmi_handler
jr k0
nop
_no_nmi:
##################################################################
# Initialize Stack Pointer
# _stack is initialized by the linker script to point to the
# starting location of the stack in DRM
##################################################################
la sp,_stack
##################################################################
# Initialize Global Pointer
# _gp is initialized by the linker script to point to "middle"
# of the small variables region
##################################################################
la gp,_gp
#if (PIC32_SRS_SET_COUNT == 2)
##################################################################
# Initialize Global Pointer in Shadow Set
# The SRSCtl's PSS field must be set to the shadow set in which
# to initialize the global pointer. Since we have only a
# single shadow set (besides the normal), we will initialize
# SRSCtl<PSS> to SRSCtl<HSS>. We then write the global pointer
# to the previous shadow set to ensure that on interrupt, the
# global pointer has been initialized.
##################################################################
mfc0 t1,_CP0_SRSCTL # Read SRSCtl register
add t3,t1,zero # Save off current SRSCtl
ext t2,t1,26,4 # to obtain HSS field
ins t1,t2,6,4 # Put HSS field
mtc0 t1,_CP0_SRSCTL # into SRSCtl<PSS>
ehb # Clear hazard before using new SRSCTL
wrpgpr gp,gp # Set global pointer in PSS
mtc0 t3,_CP0_SRSCTL # Restore SRSCtl
ehb
#elif (PIC32_SRS_SET_COUNT > 2)
##################################################################
# Initialize Global Pointer in Shadow Set(s)
# The SRSCtl PSS field must be set to the shadow set in which
# to initialize the global pointer. We will initialize
# SRSCtl<PSS> to the number of reg sets and work down to set zero.
# We write the global pointer to the previous shadow set to
# ensure that on interrupt, the global pointer has been
# initialized.
##################################################################
mfc0 t1,_CP0_SRSCTL # Read SRSCtl register
add t3,t1,zero # Save off current SRSCtl
li t2,(PIC32_SRS_SET_COUNT-1)
1: ins t1,t2,6,4 # Put next shadow set field
mtc0 t1,_CP0_SRSCTL # into SRSCtl<PSS>
ehb # Clear hazard before using new SRSCTL
wrpgpr gp,gp # Set global pointer in PSS
addiu t2,t2,-1 # Next lower shadow set
# Loop for all sets
bne t2,$0,1b # Down to zero (normal GPR set)
nop
mtc0 t3,_CP0_SRSCTL # Restore SRSCtl
ehb
#endif /* (PIC32_SRS_SET_COUNT > 2) */
##################################################################
# Call the "on reset" procedure
##################################################################
la t0,_on_reset
jalr t0
nop
#if defined(INIT_MMU_MZ_FIXED) || defined(__PIC32_HAS_MMU_MZ_FIXED)
##################################################################
# Initialize TLB for fixed mapping to EBI and SQI
##################################################################
.extern __pic32_tlb_init_ebi_sqi
la t0,__pic32_tlb_init_ebi_sqi
jalr t0
nop
#endif
##################################################################
# Clear uninitialized data sections
##################################################################
_start_bss_init:
la t0,_bss_begin
la t1,_bss_end
b _bss_check
nop
_bss_init:
sw zero,0x0(t0)
addu t0,4
_bss_check:
bltu t0,t1,_bss_init
nop
#if defined(INIT_L1_CACHE) || defined(__PIC32_HAS_L1CACHE)
##################################################################
# Initialize L1 cache. This must be done after bss clearing
# since the _bss_end symbol may not be cache-line aligned.
##################################################################
.extern __pic32_init_cache
la t0,__pic32_init_cache
jalr t0
nop
#endif
#if defined(INIT_DATA) || defined(__PIC32_HAS_INIT_DATA)
#if defined(__LIBBUILD__) /* Prebuilt crt0.o file */
##################################################################
# Initialize data using the linker-generated .dinit table
# For use with XC32 versions prior to XC32 v2.10 only.
##################################################################
.equiv FMT_CLEAR,0
.equiv FMT_COPY,1
_dinit_init:
la t0,_dinit_addr
#define SRC t0
#define DST t1
#define LEN t2
#define FMT t3
0: lw DST,0(SRC)
beqz DST,9f
addu SRC,4
lw LEN,0(SRC)
addu SRC,4
lw FMT,0(SRC)
beq FMT,$0,_dinit_clear
addu SRC,4
_dinit_copy:
lbu t4,0(SRC)
subu LEN,1
addu SRC,1
sb t4,0(DST)
bne LEN,$0,_dinit_copy
addu DST,1
b _dinit_end
nop
_dinit_clear:
sb $0,(DST)
subu LEN,1
bne LEN,$0,_dinit_clear
addu DST,1
_dinit_end:
addu SRC,3
addiu LEN,$0,-4
and SRC,LEN,SRC
lw DST,0(SRC)
bne DST,$0,0b
nop
9:
#else
#####################################################################
# Initialize data using the linker-generated .dinit table
# XC32 v2.10 and later provide the data-init code in a separate file
# packaged with the compiler rather than the DFP. Use that init
# code instead.
#####################################################################
.extern __pic32_data_init
la t0, __pic32_data_init
jalr t0
nop
#if defined(_OFF168_VOFF_POSITION)
lui t1,%hi(OFF168)
lui t2,%hi(__vector_offset_168)
addiu t2,t2,%lo(__vector_offset_168)
sw t2,%lo(OFF168)(t1)
#endif
#endif /* __LIBBUILD__ */
#endif /* INIT_DATA */
##################################################################
# If there are no RAM functions, skip the next section --
# initializing bus matrix registers.
##################################################################
la t1,_ramfunc_begin
beqz t1,_ramfunc_done
nop
#if defined(INIT_SSX) || defined(__PIC32_HAS_SSX)
/* No initialization required */
#else /* Use BMX */
##################################################################
# Initialize bus matrix registers if RAM functions exist in the
# application
##################################################################
la t1,_bmxdkpba_address
la t2,BMXDKPBA
sw t1,0(t2)
la t1,_bmxdudba_address
la t2,BMXDUDBA
sw t1,0(t2)
la t1,_bmxdupba_address
la t2,BMXDUPBA
sw t1,0(t2)
#endif /* INIT_SSX */
_ramfunc_done:
##################################################################
# Initialize CP0 registers
##################################################################
# Initialize Count register
##################################################################
mtc0 zero,_CP0_COUNT
##################################################################
# Initialize Compare register
##################################################################
li t2,-1
mtc0 t2,_CP0_COMPARE
##################################################################
# Ensure BEV set and Initialize EBase register
##################################################################
li t0, (1<<22)
mfc0 t2,_CP0_STATUS
or t2,t0,t2 # Set BEV bit 22
mtc0 t2,_CP0_STATUS
la t1,_ebase_address
ehb
mtc0 t1,_CP0_EBASE
##################################################################
# Initialize PRISS register to a safer default for devices that
# have it. The application should re-initialize it to an
# application-specific value.
#
# We do NOT do this by default.
##################################################################
#if defined(USE_DEFAULT_PRISS_VALUE)
#if defined(_PRISS_PRI7SS_POSITION)
#if (PIC32_SRS_SET_COUNT >= 7)
li t2, 0x76540000
addiu t2, t2, 0x3210
lui t1, %hi(PRISS)
sw t2, %lo(PRISS)(t1)
#elif (PIC32_SRS_SET_COUNT <= 2)
li t2, 0x10000000
lui t1, %hi(PRISS)
sw t2, %lo(PRISS)(t1)
#endif /* PIC32_SRS_SET_COUNT */
#endif /* _PRISS_PRI7SS_POSITION */
#endif /* USE_DEFAULT_PRISS_VALUE */
##################################################################
# Initialize IntCtl/INTCON.VS register with _vector_spacing
##################################################################
la t1,_vector_spacing
#if defined(INIT_INTCONVS) || defined(__PIC32_HAS_INTCONVS)
la t0, INTCON
lw t2, 0(t0)
li t2, 0
ins t2, t1, 16, 7
#if defined(__PIC32MM) && defined(_INTCON_MVEC_MASK)
ori t2, t2, _INTCON_MVEC_MASK
#endif
sw t2, 0(t0)
#endif
li t2,0 # Clear t2 and
ins t2,t1,5,5 # shift value to VS field
mtc0 t2,_CP0_INTCTL
##################################################################
# Initialize CAUSE registers
# - Enable counting of Count register <DC = 0>
# - Use special exception vector <IV = 1>
# - Clear pending software interrupts <IP1:IP0 = 0>
##################################################################
li t1,0x00800000
mtc0 t1,_CP0_CAUSE
##################################################################
# Initialize STATUS register
# - Access to Coprocessor 0 not allowed in user mode <CU0 = 0>
# - User mode uses configured endianness <RE = 0>
# - Preserve Bootstrap Exception vectors <BEV>
# - Preserve soft reset <SR> and non-maskable interrupt <NMI>
# - CorExtend enabled based on whether CorExtend User Defined
# Instructions have been implemented <CEE = Config<UDI>>
# - Disable any pending interrupts <IM7..IM2 = 0, IM1..IM0 = 0>
# - Disable hardware interrupts <IPL7:IPL2 = 0>
# - Base mode is Kernel mode <UM = 0>
# - Error level is normal <ERL = 0>
# - Exception level is normal <EXL = 0>
# - Interrupts are disabled <IE = 0>
# - DSPr2 ASE is enabled for devices that support it <MX = 1>
# - FPU64 is enabled for devices that support it <CU1=1> & <FR=1>
##################################################################
mfc0 t0,_CP0_CONFIG
ext t1,t0,22,1 # Extract UDI from Config register
sll t1,t1,17 # Move UDI to Status.CEE location
mfc0 t0,_CP0_STATUS
and t0,t0,0x00580000 # Preserve SR, NMI, and BEV
#if defined(INIT_DSPR2) || defined(__PIC32_HAS_DSPR2)
li t2, 0x01000000 # Set the Status.MX bit to enable DSP
or t0,t2,t0
#endif
#if defined(INIT_FPU64) || defined(__PIC32_HAS_FPU64)
li t2, 0x24000000 # Set the Status.CU1 and Status.FR bits to
or t0,t2,t0 # enable the FPU in FR64 mode
#endif
or t0,t1,t0 # Include Status.CEE (from UDI)
mtc0 t0,_CP0_STATUS
#if defined(PIC32WK) && defined(_CP0_CONFIG3) && defined (__mips_micromips)
# Ensure that the ISAONEXEC bit is set for the microMIPS ISA for the PIC32WK family
# _bsc0 (_CP0_CONFIG3, _CP0_CONFIG3_SELECT, ISAONEXEC_MASK)
li t1,0x10000 # ISAONEXEC bit
mfc0 t0,_CP0_CONFIG3
or t1,t0,t1
mtc0 t1,_CP0_CONFIG3
#endif /* PIC32WK && __mips_micromips */
#if defined(INIT_FPU64) || defined(__PIC32_HAS_FPU64)
# FPU Control and Status
li t2,0x1000000 # FCSR: RM=0, FS=1, FO=0, FN=0
# Enables: 0b00000 E=1, V=0, Z=0, O=0, U=0, I=0
ctc1 t2, $31 # High perf on denormal operands & tiny results
#endif
ehb
##################################################################
# Call the "on bootstrap" procedure
##################################################################
la t0,_on_bootstrap
jalr t0
nop
##################################################################
# Initialize Status<BEV> for normal exception vectors
##################################################################
mfc0 t0,_CP0_STATUS
and t0,t0,0xffbfffff # Clear BEV
mtc0 t0,_CP0_STATUS
##################################################################
# Call main. We do this via a thunk in the text section so that
# a normal jump and link can be used, enabling the startup code
# to work properly whether main is written in MIPS16 or MIPS32
# code. I.e., the linker will correctly adjust the JAL to JALX if
# necessary
##################################################################
and a0,a0,0
and a1,a1,0
la t0,_main_entry
jr t0
nop
.end _startup
##################################################################
# Boot Exception Vector Handler
# Jumps to _bootstrap_exception_handler
##################################################################
.section .bev_handler,code,keep
.align 2
.set noreorder
.ent _bev_exception
_bev_exception:
la k0,_bootstrap_exception_handler
jr k0
nop
.end _bev_exception
##################################################################
# General Exception Vector Handler
# Jumps to _general_exception_context
##################################################################
.section .gen_handler,code
.align 2
.set noreorder
.ent _gen_exception
_gen_exception:
0: la k0,_general_exception_context
jr k0
nop
.end _gen_exception
#if defined(INIT_MMU_MZ_FIXED) || defined(__PIC32_HAS_MMU_MZ_FIXED)
##################################################################
# Simple TLB-Refill Exception Vector
# Jumps to _simple_tlb_refill_exception_context
##################################################################
.section .simple_tlb_refill_vector,code,keep
.align 2
.set noreorder
.ent simple_tlb_refill_vector
simple_tlb_refill_vector:
la k0,_simple_tlb_refill_exception_context
jr k0
nop
.end simple_tlb_refill_vector
#endif
#if defined(INIT_L1_CACHE) || defined(__PIC32_HAS_L1CACHE)
##################################################################
# Cache-Error Exception Vector Handler
# Jumps to _cache_err_exception_context
##################################################################
.section .cache_err_vector,code,keep
.align 2
.set noreorder
.ent _cache_err_vector
_cache_err_vector:
la k0,_cache_err_exception_context
jr k0
nop
.end _cache_err_vector
#endif
.section .text.main_entry,code,keep
.align 2
.ent _main_entry
_main_entry:
#if defined(__XC32_LIBC_INIT_ARRAY)
/* MUSL C library initialization used with MPLAB XC32 v4.00 and later */
la t0,__libc_init_array
jalr t0
nop
#endif
#if defined(CPP_INIT)
.weak _init
# call .init section to run constructors etc
lui a0,%hi(_init)
addiu sp,sp,-24
addiu a0,a0,%lo(_init)
beq a0,$0,2f
sw $31,20(sp) #,
jalr a0
nop
2:
#endif
and a0,a0,0
and a1,a1,0
##################################################################
# Call main
##################################################################
la t0,main
jalr t0
nop
#if defined(CALL_EXIT)
##################################################################
# Call exit()
##################################################################
jal exit
nop
#endif
##################################################################
# Just in case, go into infinite loop
# Call a software breakpoint only with -mdebugger compiler option
##################################################################
.weak __exception_handler_break
__crt0_exit:
1:
la v0,__exception_handler_break
beq v0,0,0f
nop
jalr v0
nop
0: b 1b
nop
.globl __crt0_exit
.end _main_entry
来自模拟器xc32,硬件很好。