你的位置:首页 > 操作系统

[操作系统]CYPRESS S6E1C3 系列 FM0+ 32位单片机串口uart0 问题


/*-----------------------------前奏-----------------------------------*/

mcu型号s6e1c32c(48pin)、s6e1c32b(32pin)

本次调试:uart0【与SWD 管脚复用】
由于在启动文件中 :跳转到SystemInit ()初始化系统时钟,再跳转到main()。如下:

Reset_Handler
    LDR R0, =SystemInit
    BLX R0
    LDR R0, =__iar_program_start
    BX R0

/*-----------------------------实干-----------------------------------*/

1,实际在main中,UartInit(115200);  printf("Let us jump ......\r\n"); 并不能输出。,

2,原来FM0+ 默认没有给我们开启串口和IO管脚的时钟。需要类似stm32系列 增添代码:

  Clk_PeripheralClockEnable(ClkGateGpio);
  Clk_PeripheralClockEnable(ClkGateMfs0);//uart0 时钟

3,再次用J-Link 调试,跑飞了:正常结果。SWD被uart0共用,开启uart0,SWD自然失效。拔掉调试线,换成TTL串口查看信息。还是然并卵!!

被打败了?。。。。。。。。不可能!

4,把uart3 的管脚引出,修改串口初始化代码。 发现有打印信息,谢谢上天。还有希望。

5,问题点可能处在SWD的身上,查看SWD复用配置:SetPinFunc_SWCLK();SetPinFunc_SWDIO();再往里面看[深入~内涵一下]。

  里面有定义:bFM_GPIO_EPFR00_SWDEN = 1; 如果关闭SWD功能,即bFM_GPIO_EPFR00_SWDEN = 0; 再开启uart0,能行吗?

6,试了还真行,就是问题所在了。原来在开启uart0功能时,SWD不能自动断开。需要手动操作。

/*-----------------------------上代码-----------------------------------*/

typedef void (*pFunction)(void);
u32 g_AppAddr = 0x0;

void RemapVTOR();

void ExitIAP(void)
{
u32 JumpAddress;
pFunction Jump_To_Application;
//d_p("Jump_To_Application\n");
JumpAddress = *(vu32*) (g_AppAddr + 4);
Jump_To_Application = (pFunction) JumpAddress;

/* Initialize user application's Stack Pointer */
__set_MSP(*(vu32*)g_AppAddr);

Jump_To_Application();
}

#define InitUartIo()     {SetPinFunc_SIN0_0();SetPinFunc_SOT0_0();}

#define SWD_ON() {SetPinFunc_SWCLK();SetPinFunc_SWDIO();}
#define SWD_OFF() {bFM_GPIO_EPFR00_SWDEN = 0;}

int main(void)

{
//Clk_PeripheralClockEnable(ClkGateGpio);
//Clk_PeripheralClockEnable(ClkGateMfs0);//uart0 时钟
Clk_PeripheralClockEnableAll();//也可以开启全部时钟

//SWD_ON(); //下次调试开启并屏蔽 SWD_OFF();从新下载一遍
UartInit(115200);
printf("Let us jump ......\r\n");
//RemapVTOR();
ExitIAP();

printf("Jump faild !\r\n");
return 0;
}

uart0.c

void UartInit(uint32_t baudrate)
{
stc_uart_irq_en_t stcIntEn;
stc_uart_irq_cb_t stcIrqCb;
stc_mfs_uart_config_t stcUartConfig;

if(UartCh == &UART0)//串口0 复用SWD 需手动关闭
{SWD_OFF();}// 可以再在串口配置前加点延时。

PDL_ZERO_STRUCT(stcUartConfig);

/* Initialize UART function I/O */
InitUartIo();

/* Initialize UART RX/TX interrupt */
stcIntEn.bRxIrq = TRUE;
stcIntEn.bTxIrq = FALSE;
stcIrqCb.pfnRxIrqCb = Uart_RX_IRQHandler;
stcIrqCb.pfnTxIrqCb = NULL;
/* Initialize UART RX/TX channel */
stcUartConfig.enMode = UartNormal;
stcUartConfig.u32BautRate = baudrate;
stcUartConfig.enDataLength = UartEightBits;
stcUartConfig.enParity = UartParityNone;
stcUartConfig.enStopBit = UartOneStopBit;
stcUartConfig.enBitDirection = UartDataLsbFirst;
stcUartConfig.bInvertData = FALSE;
stcUartConfig.bHwFlow = FALSE;
stcUartConfig.pstcFifoConfig = NULL;
stcUartConfig.bUseExtClk = FALSE;
stcUartConfig.pstcIrqEn = &stcIntEn;
stcUartConfig.pstcIrqCb = &stcIrqCb;
stcUartConfig.bTouchNvic = TRUE;
Mfs_Uart_Init(UartCh, &stcUartConfig);

/* Enable TX function of UART0 */
Mfs_Uart_EnableFunc(UartCh, UartRx);
Mfs_Uart_EnableFunc(UartCh, UartTx);

return;
}

void UartSendByte(uint8_t dat)
{
while(TRUE != Mfs_Uart_GetStatus(UartCh, UartTxIdle));
while (TRUE != Mfs_Uart_GetStatus(UartCh, UartTxEmpty)); /* wait until TX buffer empty */
Mfs_Uart_SendData(UartCh, dat);

return;
}

int putchar(int ch)
{
if(ch == '\n')
{
UartSendByte('\r');
}
UartSendByte((unsigned char)ch);
return ch;
}

/*-----------------------------实际结果-----------------------------------*/

每次实现:printf("Let us jump ......\r\n");

就打印  Let us jump ...... 并跳转到复位状态,地址 0;

最后一直循环跳转,不停打印

 Let us jump ......

Let us jump ......

Let us jump ......

Let us jump ......