用AM335X_StarterWare_02_00_00_06 库,通过uartEcho.c 改的。主要改写了时钟一部分。
现在,发送是可以,但是用中断接收不行。 我用 PC发送数据给AM3352,然后程序就死掉了。
感觉没有进中断,但是发生了中断。应该是没有正确的进入中断服务函数。也感觉中断向量表没有初始化 void (*fnRAMVectors[NUM_INTERRUPTS])(void);(这个数组在interrupt.c中),就是我标记为红色的函数。
希望大家帮忙看看代码,哪里出错了。也可以发一个正确的Demo给我参考参考(1073922360@qq.com),谢谢了!!
#include "hw_control_AM335x.h"
#include "uart_irda_cir.h"
#include "soc_AM335x.h"
#include "interrupt.h"
#include "uartStdio.h"
#include "beaglebone.h"
#include "hw_cm_wkup.h"
#include "hw_cm_per.h"
#include "hw_types.h"
/******************************************************************************
** INTERNAL MACRO DEFINITIONS
******************************************************************************/
#define UART_MODULE_INPUT_CLK (48000000)
/******************************************************************************
** INTERNAL FUNCTION PROTOTYPES
******************************************************************************/
static void Uart1InterruptEnable(void);
static void UART1AINTCConfigure(void);
static void UartFIFOConfigure(unsigned int baseAdd);
static void UartBaudRateSet(unsigned int baseAdd,unsigned int baudRate);
static void UART1Isr(void);
/******************************************************************************
** GLOBAL VARIABLE DEFINITIONS
******************************************************************************/
unsigned char txArray[] = "StarterWare AM335X UART Interrupt application\r\n";
/******************************************************************************
** FUNCTION DEFINITIONS
******************************************************************************/
/**
* \brief This function selects the UART pins for use. The UART pins
* are multiplexed with pins of other peripherals in the SoC
*
* \param instanceNum The instance number of the UART to be used.
*
* \return None.
*
* \note This pin multiplexing depends on the profile in which the EVM
* is configured.
*/
void UART1PinMuxSetup(unsigned int instanceNum)
{
if(1 == instanceNum)
{
/* RXD */
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_RXD(1)) =
(CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_PUTYPESEL |
CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_RXACTIVE);
/* TXD */
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_TXD(1)) =
CONTROL_CONF_UART1_TXD_CONF_UART1_TXD_PUTYPESEL;
}
}
void UART1ModuleClkConfig(void)
{
/* Configuring L3 Interface Clocks. */
/* Writing to MODULEMODE field of CM_PER_L3_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) |=
CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while(CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) &
CM_PER_L3_CLKCTRL_MODULEMODE));
/* Writing to MODULEMODE field of CM_PER_L3_INSTR_CLKCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) |=
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while(CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) &
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE));
/* Writing to CLKTRCTRL field of CM_PER_L3_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) |=
CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
/* Waiting for CLKTRCTRL field to reflect the written value. */
while(CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) &
CM_PER_L3_CLKSTCTRL_CLKTRCTRL));
/* Writing to CLKTRCTRL field of CM_PER_OCPWP_L3_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) |=
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
/*Waiting for CLKTRCTRL field to reflect the written value. */
while(CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) &
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL));
/* Writing to CLKTRCTRL field of CM_PER_L3S_CLKSTCTRL register. */
HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) |=
CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
/*Waiting for CLKTRCTRL field to reflect the written value. */
while(CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) &
CM_PER_L3S_CLKSTCTRL_CLKTRCTRL));
//2017.3.27 zhao
HWREG(SOC_CM_PER_REGS + CM_PER_UART1_CLKCTRL) |=
CM_PER_UART1_CLKCTRL_MODULEMODE_ENABLE;
while(CM_PER_UART1_CLKCTRL_MODULEMODE_ENABLE !=
(HWREG(SOC_CM_PER_REGS + CM_PER_UART1_CLKCTRL) &
CM_PER_UART1_CLKCTRL_MODULEMODE));
/* Checking fields for necessary values. */
/* Waiting for IDLEST field in CM_PER_L3_CLKCTRL register to be set to 0x0. */
while((CM_PER_L3_CLKCTRL_IDLEST_FUNC << CM_PER_L3_CLKCTRL_IDLEST_SHIFT)!=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) &
CM_PER_L3_CLKCTRL_IDLEST));
/*
** Waiting for IDLEST field in CM_PER_L3_INSTR_CLKCTRL register to attain the
** desired value.
*/
while((CM_PER_L3_INSTR_CLKCTRL_IDLEST_FUNC <<
CM_PER_L3_INSTR_CLKCTRL_IDLEST_SHIFT)!=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) &
CM_PER_L3_INSTR_CLKCTRL_IDLEST));
/*
** Waiting for CLKACTIVITY_L3_GCLK field in CM_PER_L3_CLKSTCTRL register to
** attain the desired value.
*/
while(CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) &
CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK));
/*
** Waiting for CLKACTIVITY_OCPWP_L3_GCLK field in CM_PER_OCPWP_L3_CLKSTCTRL
** register to attain the desired value.
*/
while(CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) &
CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK));
/*
** Waiting for CLKACTIVITY_L3S_GCLK field in CM_PER_L3S_CLKSTCTRL register
** to attain the desired value.
*/
while(CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK !=
(HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) &
CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK));
//
/* Configuring registers related to Wake-Up region. */
}
void UARTInit(unsigned int baseAdd,unsigned int baudRate)
{
/* Configuring the system clocks for UART1 instance. */
UART1ModuleClkConfig();
/* Performing the Pin Multiplexing for UART1 instance. */
UART1PinMuxSetup(1);
/* Performing a module reset. */
UARTModuleReset(baseAdd);
/* Performing FIFO configurations. */
UartFIFOConfigure(baseAdd);
/* Performing Baud Rate settings. */
UartBaudRateSet(baseAdd,baudRate);
/* Switching to Configuration Mode B. */
UARTRegConfigModeEnable(baseAdd, UART_REG_CONFIG_MODE_B);
/* Programming the Line Characteristics. */
UARTLineCharacConfig(baseAdd,
(UART_FRAME_WORD_LENGTH_8 | UART_FRAME_NUM_STB_1),
UART_PARITY_NONE);
/* Disabling write access to Divisor Latches. */
UARTDivisorLatchDisable(baseAdd);
/* Disabling Break Control. */
UARTBreakCtl(baseAdd, UART_BREAK_COND_DISABLE);
/* Switching to UART16x operating mode. */
UARTOperatingModeSelect(baseAdd, UART16x_OPER_MODE);
UARTCharPut(SOC_UART_1_REGS,'J');
/* Performing Interrupt configurations. */
Uart1InterruptEnable();
UARTCharPut(SOC_UART_1_REGS,'E');
}
/*
** A wrapper function performing Interrupt configurations.
*/
static void Uart1InterruptEnable(void)
{
/* Enabling IRQ in CPSR of ARM processor. */
IntMasterIRQEnable();
/* Configuring AINTC to receive UART0 interrupts. */
UART1AINTCConfigure();
/* Enabling the specified UART interrupts. */
UARTIntEnable(SOC_UART_1_REGS, (UART_INT_LINE_STAT | UART_INT_THR |
UART_INT_RHR_CTI));
}
/*
** A wrapper function performing FIFO configurations.
*/
static void UartFIFOConfigure(unsigned int baseAdd)
{
unsigned int fifoConfig = 0;
//Setting the TX and RX FIFO Trigger levels as 1. No DMA enabled.
fifoConfig = UART_FIFO_CONFIG(UART_TRIG_LVL_GRANULARITY_1,
UART_TRIG_LVL_GRANULARITY_1,
1,
1,
1,
1,
UART_DMA_EN_PATH_SCR,
UART_DMA_MODE_1_ENABLE);
// Configuring the FIFO settings.
UARTFIFOConfig(baseAdd, fifoConfig);
}
/*
** A wrapper function performing Baud Rate settings.
*/
static void UartBaudRateSet(unsigned int baseAdd,unsigned int baudRate)
{
unsigned int divisorValue = 0;
/* Computing the Divisor Value. */
divisorValue = UARTDivisorValCompute(UART_MODULE_INPUT_CLK,
baudRate,
UART16x_OPER_MODE,
UART_MIR_OVERSAMPLING_RATE_42);
/* Programming the Divisor Latches. */
UARTDivisorLatchWrite(baseAdd, divisorValue);
}
/*
** Interrupt Service Routine for UART.
*/
static void UART1Isr(void)
{
static unsigned int txStrLength = sizeof(txArray);
static unsigned int count = 0;
unsigned char rxByte = 0;
unsigned int intId = 0;
/* Checking ths source of UART interrupt. */
intId = UARTIntIdentityGet(SOC_UART_1_REGS);
UARTCharPut(SOC_UART_1_REGS,'I');
switch(intId)
{
case UART_INTID_TX_THRES_REACH:
if(0 != txStrLength)
{
UARTCharPut(SOC_UART_1_REGS, txArray[count]);
txStrLength–;
count++;
}
else
{
/* Disabling the THR interrupt. */
UARTIntDisable(SOC_UART_1_REGS, UART_INT_THR);
}
break;
case UART_INTID_RX_THRES_REACH:
rxByte = UARTCharGetNonBlocking(SOC_UART_1_REGS);
UARTCharPutNonBlocking(SOC_UART_1_REGS, rxByte);
break;
case UART_INTID_RX_LINE_STAT_ERROR:
case UART_INTID_CHAR_TIMEOUT:
rxByte = UARTCharGetNonBlocking(SOC_UART_1_REGS);
break;
default:
break;
}
}
/*
** This function configures the AINTC to receive UART interrupts.
*/
static void UART1AINTCConfigure(void)
{
UARTCharPut(SOC_UART_1_REGS,'F');
/* Initializing the ARM Interrupt Controller. */
IntAINTCInit();
/* Registering the Interrupt Service Routine(ISR). */
IntRegister(SYS_INT_UART1INT, UART1Isr);
/* Setting the priority for the system interrupt in AINTC. */
IntPrioritySet(SYS_INT_UART1INT, 0, AINTC_HOSTINT_ROUTE_IRQ);
/* Enabling the system interrupt in AINTC. */
IntSystemEnable(SYS_INT_UART1INT);
UARTCharPut(SOC_UART_1_REGS,'Z');
}
Jian Zhou:
请问你是改写哪里了?想修改波特率么?
user4937584:
回复 Jian Zhou:
void UART1ModuleClkConfig(void) 这个函数,好像是时钟配置。其他改写的就是把UART0的地址改为UART1地址。
user4937584:
回复 Jian Zhou:
就是我用红色标记的那个函数,是把中断服务函数写到一个中断向量表数组里面, 这个向量表没有初始化。当中断来的时候,找不到中断服务函数。