/*-----------------------------前奏-----------------------------------*/mcu型號s6e1c32c(48pin)、s6e1c32b(32pin)本次調試:uart0【與SWD 管腳復用】由於在啟動文件中 :跳轉到SystemInit...
/*-----------------------------前奏-----------------------------------*/
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 ......
。
。
。