小细节“./n“造成的 printf()死锁

在Windows 10环境下使用Visual C++ 2019开发控制台程序时,遇到了printf函数导致程序死锁的问题。经过排查,发现特定的字符组合会导致该问题出现,通过简单的修改解决了此现象。

Win10+VC2019控制台程序 printf死锁问题

我遇到的问题:

环境:VC2019 控制台程序+ window10

操作
调试控制台时用到,printf()输出显示。

printf("输入一个字符,开始下一个测试.\n");      // 注意:问题在.\n 这里

测试时发现,控制台偶尔会莫名的卡死,没有任何显示。
逐行查找后发现,程序运行到printf()就在也没有了动静。

由此证明printf()造成了程序死锁。

先查阅网友的经验:
摘录

C++ printf 、cout 无法输出到控制台问题
再编写程序的过程中,使用printf 输出变量值没用,然后用cout进行替换也是没用

#include <stdio.h>
#include <stdlib.h>
#include <iostrea>
#include <string.h>

using namespace std;

int main (int args,char *argv[])

{
         if (args !=2) printf("please set prot  , such as you can set 8000" );   // 注意:这里没有 /n

        printf("port : %s",argv[1]);

        cout <<port :<<argv[1];

        .....
        return 0;
}

编译调试后发现 什么都没有输出出来。

查询资料得知 :
printf的内容放在缓冲区里面还没有刷出来,原则上是缓冲区满了以后才输出,成为标准输出流

1. 实验目的和要求 1. 理解信号量的概念 2. 掌握POSIX信号量的使用方法 3. 掌握利用信号量机制实现互斥 2. 实验内容 1. 写一段C程序,使用POSIX信号量互斥地修改一个全局变量。 2. 哲学家就餐问题。(参考下面代码) 3. 给出的哲学家就餐问题的代码在什么情况下会发生死锁?请修改代码解决这个问题。 3. 实验指导 1. 信号量的基本思想:整型信号量最初Dijkstra把整型信号量定义为一个用于表示资源数目的整型量 S,它与一般的整型量不同,除初始化外,仅能通过两个标准原子操作(Atomic Operation) wait(S)和signal(S)操作可以描述为 int S = 1;//初始化整型信号量,表示资源数 void wait(int S) { //wait原语,检查和上锁一气呵成 while(S <= 0); //资源数不够就循环等待 S = S - 1; //资源数够,就占用一个资源 } } void signal(int S) { //signal原语 S = S + 1; //使用完资源后释放资源 2. 初始化信号量: int sem_init(sem_t *sem, int pshared, unsigned int value); 参数: sem :指向要初始化的信号量的指针。 pshared :用于指示信号量是在进程间共享还是线程间共享的标志。如果值为 0,表示信号量 将在线程间共享;如果不为 0,则表示在进程间共享。 value :指定信号量的初始值。信号量是一个计数器,用于控制同时访问共享资源的线程或进 程数量。 返回值:初始化成功返回0,失败则返回-1。 3. wait操作: int sem_wait(sem_t *sem); 参数: sem :指向信号量的指针,这是一个由 sem_init 初始化的信号量对象。它用于表示线程等 待的信号量。在等待期间,如果信号量的值大于0,则线程可以继续执行。如果信号量的值为 0,则线程会被阻塞,直到信号量的值大于0。 返回值: 如果函数成功执行并且信号量的值大于0,则返回值为0。 如果函数执行失败,则返回值为-1,并设置 4. signal操作: int sem_post(sem_t *sem); errno 变量来指示错误的类型。 参数: sem :指向要增加的信号量的指针。 返回值: 如果函数调用成功,返回值为 0。 如果函数调用失败,返回值为 -1,并设置 5. 销毁信号量: int sem_destroy(sem_t *sem); errno 来指示错误类型。 参数: sem_t *sem:一个指向要销毁的信号量的指针。 返回值: 如果函数调用成功,返回值为 0。 如果函数调用失败,返回值为 -1。 4. 参考代码 1. 第二个实验: #include<stdio.h> #include<stdlib.h> #include<pthread.h> #include<semaphore.h> #define N 5 sem_t chopstick[N]; // 筷子信号量 // 哲学家线程函数 void* philosopher(void* arg) { int i = (int)arg; // 哲学家序号 for (;;) { // 思考 printf("[%d] I'm thinking ...\n", i); sleep(rand() % 3); // 休眠随机时间,不超过3秒 // 等待筷子 sem_wait(&chopstick[i]); sem_wait(&chopstick[(i+1)%N]); // 就餐 printf("\t\t\t[%d] I'm eating ...\n", i); sleep(rand() % 3); // 休眠随机时间,不超过3秒 // 放回筷子 sem_post(&chopstick[i]); sem_post(&chopstick[(i+1)%N]); } } int main() { pthread_t id[N]; int i; for (i = 0; i < N; i++) { sem_init(&chopstick[i], 0, 1); } for (i = 0; i < N; i++) { pthread_create(&id[i], NULL, philosopher, (void*)i); } for (i = 0; i < N; i++) { pthread_join(id[i], NULL); } for (i = 0; i < N; i++) { sem_destroy(&chopstick[i]); } return 0 给我以下4点: 三、实验环境 (实验平台描述,操作系统、数据库管理系统、编译环境..) 四、实验过程描述 (语言描述实验细节+具体代码实现+截图) 五、结果分析 得到什么结果(数据)?有什么问题?分析原因 六、结论
06-22
static int fwcli__stackRoleChangeCallback(IN UINT8 roleChg) { DBG_ALZ("fwcli__stackRoleChangeCallback"); if (roleChg) /*master-->slave 和 slave-->master*/ { DBG_ALZ("zsz: role change"); if (DEV_ROLE_IS_MASTER(UNIT_CURRENT)) /* slave ==>> master */ { printf("\nconnected to the Master.\n"); /* 关闭之前的tfakeConsoel */ pal_mutex_take(mtx_fakeConsole, pal_mutex_FOREVER); if(TRUE == bUseFakeConsole) { /* 存在重复检查,不影响程序,先不用修改 */ pal_mutex_give(mtx_fakeConsole); DBG_ALZ("tFackConsole存在 关闭tFackConsole"); cli__stopUseFakeConsole(); return OK; } pal_mutex_give(mtx_fakeConsole); /* 运行slaveSession监听线程 */ pal_mutex_take(mtx_slaveSession, pal_mutex_FOREVER); if(FALSE == slaveSession ) /* 没有运行slaveSession监听线程,需要创建 */ { DBG_ALZ("没有运行slaveSession监听线程,需要创建"); slaveSession = TRUE; // 打开监听会话 fwcli_openSlaveSession(); /*首次运行设备成为master和slave-->master的情况运行*/ } pal_mutex_give(mtx_slaveSession); } else /* 含 master ==>> slave */ { printf("\nconnected to the Slave.\n"); /* 关闭监听线程 */ pal_mutex_take(mtx_slaveSession, pal_mutex_FOREVER); if(TRUE == slaveSession ) /* */ { DBG_ALZ("关闭监听会话 "); slaveSession = FALSE; // 关闭监听会话 } pal_mutex_give(mtx_slaveSession); /* 关闭之前连接到该设备的slave_session 会话 */ RCC__TELNETD_SlavesStopMasterCli(); /* 向新的master发起重定向连接 */ DBG_ALZ("master-->slave 直接启用fakeConsole\n"); pal_mutex_take(mtx_fakeConsole, pal_mutex_FOREVER); if (FALSE == bUseFakeConsole) { pal_mutex_give(mtx_fakeConsole); fwcli__useMasterCliServer(); //锁就会阻塞 return OK; } pal_mutex_give(mtx_fakeConsole); } } else /* master-->master 和 slave-->slave */ { DBG_ALZ("zsz: role no change"); if (DEV_ROLE_IS_MASTER(UNIT_CURRENT)) /* master-->master */ { printf("\n connected to the Master.\n"); DBG_ZSZ("master -> master 继续运行原监听线程即可"); } else /* slave-->slave */ { printf("\nconnected to the Slave.\n"); if(TRUE == cli_MasterIsChange()) /* master端关闭socket,slave自动关闭资源,只需要向新的master发起连接*/ { printf("master change.\n"); pal_mutex_take(mtx_fakeConsole, pal_mutex_FOREVER); if (FALSE == bUseFakeConsole) { pal_mutex_give(mtx_fakeConsole); fwcli__useMasterCliServer(); //锁就会阻塞 return OK; } pal_mutex_give(mtx_fakeConsole); } else { printf("master no change\n"); } } } return OK; } static int fwcli__stackRoleChangeCallback(IN UINT8 roleChg) { DBG_ALZ("fwcli__stackRoleChangeCallback"); if (roleChg) /*master-->slave 和 slave-->master*/ { DBG_ALZ("zsz: role change"); if (DEV_ROLE_IS_MASTER(UNIT_CURRENT)) /* slave ==>> master */ { printf("\nconnected to the Master.\n"); /* 行slaveSession监听线程 */ pal_mutex_take(mtx_slaveSession, pal_mutex_FOREVER); if(FALSE == slaveSession ) /* 没有运行slaveSession监听线程,需要创建 */ { DBG_ALZ("没有运行slaveSession监听线程,需要创建"); slaveSession = TRUE; // 打开监听会话 fwcli_openSlaveSession(); /*首次运行设备成为master和slave-->master的情况运行*/ } pal_mutex_give(mtx_slaveSession); /* 关闭之前的 */ pal_mutex_take(mtx_fakeConsole, pal_mutex_FOREVER); if(TRUE == bUseFakeConsole) { /* 存在重复检查,不影响程序,先不用修改 */ pal_mutex_give(mtx_fakeConsole); DBG_ALZ("tFackConsole存在 关闭tFackConsole"); cli__stopUseFakeConsole(); return OK; } pal_mutex_give(mtx_fakeConsole); } else /* 含 master ==>> slave */ { printf("\nconnected to the Slave.\n"); /* 关闭监听线程 */ pal_mutex_take(mtx_slaveSession, pal_mutex_FOREVER); if(TRUE == slaveSession ) /* */ { DBG_ALZ("关闭监听会话 "); slaveSession = FALSE; // 关闭监听会话 } pal_mutex_give(mtx_slaveSession); /* 关闭之前连接到该设备的slave_session 会话 */ RCC__TELNETD_SlavesStopMasterCli(); /* 向新的master发起重定向连接 */ DBG_ALZ("master-->slave 直接启用fakeConsole\n"); pal_mutex_take(mtx_fakeConsole, pal_mutex_FOREVER); if (FALSE == bUseFakeConsole) { pal_mutex_give(mtx_fakeConsole); fwcli__useMasterCliServer(); //锁就会阻塞 return OK; } pal_mutex_give(mtx_fakeConsole); } } else /* master-->master 和 slave-->slave */ { DBG_ALZ("zsz: role no change"); if (DEV_ROLE_IS_MASTER(UNIT_CURRENT)) /* master-->master */ { printf("\n connected to the Master.\n"); DBG_ZSZ("master -> master 继续运行原监听线程即可"); } else /* slave-->slave */ { printf("\nconnected to the Slave.\n"); if(TRUE == cli_MasterIsChange()) /* master端关闭socket,slave自动关闭资源,只需要向新的master发起连接*/ { printf("master change.\n"); pal_mutex_take(mtx_fakeConsole, pal_mutex_FOREVER); if (FALSE == bUseFakeConsole) { pal_mutex_give(mtx_fakeConsole); fwcli__useMasterCliServer(); //锁就会阻塞 return OK; } pal_mutex_give(mtx_fakeConsole); } else { printf("master no change\n"); } } } return OK; } 这两个函数有啥不一样
10-17
/** * @file main.c * @author Nations * @version v1.0.0 * * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. */ #define HSE_VALUE (40000000) #include <stdio.h> #include "main.h" #include "sys_var.h" #include "key.h" #include "n32g43x_gpio.h" int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* NVIC configuration */ NVIC_Configuration(); /* Configure the GPIO ports */ GPIO_Configuration(); /* USART configuration */ USART_Configuration(); /* TIM Configuration */ TIM_Configuration(); DelayMs(200);//待上电稳定 ADC_Initial(); //检测上电类型 if(1) { /* Check if the system has resumed from solft reset */ if (RCC_GetFlagStatus(RCC_CTRLSTS_FLAG_SFTRSTF) != RESET) { /* solft reset flag set */ printf("\n\rsystem solft reset\n\r\n\r"); /* Clear reset flags */ RCC_ClrFlag(); } else { /* WWDGRST flag is not set */ printf("\n\rnormal power on\n\r\n\r"); } } PrintSystemClock(); gpio_func_init(); printf("\n\r seat 8 io project\n\rbuild datetime : %s %s\n\r",__DATE__,__TIME__); //printf("\n\rwhile\n\r"); mode_state = 1; air_bag_ctrl.current_mode = mode_state; air_bag_ctrl.schedule_table_pntr = air_bag_schedule_table[mode_state]; TimeOutSet(&StopWork_Timer, work_mode_total_duration[mode_state]); statck_init(); statck_push(&air_bag_ctrl.schedule_table_pntr[0]); while (1) { /* running led*/ { if(IsTimeOut(&LedTimer)) { TimeOutSet(&LedTimer,1000); GpioToggle(LED); } } #ifdef FY_1KEY_3LED /* mode led */ set_led_mode(mode_state); /* key led */ GpioSetOut(LED5,1); // if(!GpioGet(KEY6)) // { // GpioSetOut(LED5,1); // } // else // { // GpioSetOut(LED5,0); // } #endif /* key func */ //if (IsTimeOut(&KeyScanTimer)) { keyScan(); if( key_mode == KEY_MODE_ADC) { AdcKeyFunc(); //TimeOutSet(&KeyScanTimer,50); } if( key_mode == KEY_MODE_GPIO) { GpioKeyFunc(); //TimeOutSet(&KeyScanTimer,80); } } } } /** * @} */ /** * @} */ #include "app.h" #include "key.h" #include "sys_var.h" #ifdef FY_1KEY_3LED void set_led_mode(uint8_t mode) { if(mode == 0x1) { GpioSetOut(LED4,1); GpioSetOut(LED3,0); GpioSetOut(LED2,0); } else if(mode == 0x2) { GpioSetOut(LED4,1); GpioSetOut(LED3,1); GpioSetOut(LED2,0); } else if(mode == 0x3) { GpioSetOut(LED4,1); GpioSetOut(LED3,1); GpioSetOut(LED2,1); } else { GpioSetOut(LED4,0); GpioSetOut(LED3,0); GpioSetOut(LED2,0); } } #endif void air_bag_init(void) { GpioInitOut( SW1 ); GpioInitOut( SW2 ); GpioInitOut( SW3 ); GpioInitOut( SW4 ); GpioInitOut( SW5 ); GpioInitOut( SW6 ); GpioInitOut( SW7 ); GpioInitOut( SW8 ); GpioInitOut( SW9 ); GpioInitOut( SW10 ); //GpioInitOut( SW11 ); //GpioInitOut( SW12 ); GpioInitOut( POWER_FB ); GpioInitOut( POWER_EN ); GpioInitOut( MOTOR_PWM); GpioSetOut( SW1 ,0); GpioSetOut( SW2 ,0); GpioSetOut( SW3 ,0); GpioSetOut( SW4 ,0); GpioSetOut( SW5 ,0); GpioSetOut( SW6 ,0); GpioSetOut( SW7 ,0); GpioSetOut( SW8 ,0); GpioSetOut( SW9 ,0); GpioSetOut( SW10 ,0); //GpioSetOut( SW11 ,0); //GpioSetOut( SW12 ,0); GpioSetOut( POWER_FB ,1); GpioSetOut( POWER_EN ,0); GpioSetOut( MOTOR_PWM,0); } void air_bag_idle(void) { POWER_OFF; MOTOR_OFF; GpioSetOut( SW1 ,0); GpioSetOut( SW2 ,0); GpioSetOut( SW3 ,0); GpioSetOut( SW4 ,0); GpioSetOut( SW5 ,0); GpioSetOut( SW6 ,0); GpioSetOut( SW7 ,0); GpioSetOut( SW8 ,0); GpioSetOut( SW9 ,0); GpioSetOut( SW10 ,0); //GpioSetOut( SW11 ,0); //GpioSetOut( SW12 ,0); } void air_bag_out(void) { GpioSetOut( SW1 ,0); GpioSetOut( SW2 ,0); GpioSetOut( SW3 ,0); GpioSetOut( SW4 ,0); GpioSetOut( SW5 ,0); GpioSetOut( SW6 ,0); GpioSetOut( SW7 ,0); GpioSetOut( SW8 ,0); GpioSetOut( SW9 ,0); GpioSetOut( SW10 ,0); } void gpio_func_init(void) { #ifdef FY_1KEY_3LED GpioInitIn(KEY6); #elif defined(FY_1KEY_NOLED) GpioInitIn(KEY4); #endif #ifdef FY_1KEY_3LED GpioInitOut(LED); GpioSetOut(LED,0); GpioInitOut(LED2); GpioSetOut(LED2,0); GpioInitOut(LED3); GpioSetOut(LED3,0); GpioInitOut(LED4); GpioSetOut(LED4,0); GpioInitOut(LED5); GpioSetOut(LED5,0); #endif air_bag_init(); } void AdcKeyFunc(void) { static unsigned char last_adckey_code = 0; static unsigned char last_adckey_type = 0; if(( last_adckey_code != key.KeyEventCode || last_adckey_type != key.KeyEventType) ) { if(key.KeyEventCode > 0 && key.KeyEventType > 0 ) printf("\n\rADC key KeyEventCode : %d KeyEventType : %d \n\r",key.KeyEventCode , key.KeyEventType); if( key.KeyEventCode == ADC_KEY_CODE_UP && key.KeyScanState >= KEYSCANSTATE_HOLD) { { //上充下放 POWER_ON; MOTOR_ON; #ifdef FY_SEAT_10 WAIST_1_IN; WAIST_2_OUT; #endif air_bag_out(); } air_bag_ctrl.current_mode = SEAT_FUNC_MODE_IDLE; TimeOutSet(&Out_15S_Before_Stop_Timer,0); mode_state = 0; } else if( key.KeyEventCode == ADC_KEY_CODE_DOWN && key.KeyScanState >= KEYSCANSTATE_HOLD) { { //下充上放 POWER_ON; MOTOR_ON; #ifdef FY_SEAT_10 WAIST_2_IN; WAIST_1_OUT; #endif air_bag_out(); } air_bag_ctrl.current_mode = SEAT_FUNC_MODE_IDLE; TimeOutSet(&Out_15S_Before_Stop_Timer,0); mode_state = 0; } else if( key.KeyEventCode == ADC_KEY_CODE_LEFT && key.KeyScanState >= KEYSCANSTATE_HOLD) { { //全充 POWER_ON; MOTOR_ON; #ifdef FY_SEAT_10 WAIST_1_IN; WAIST_2_IN; #endif air_bag_out(); } air_bag_ctrl.current_mode = SEAT_FUNC_MODE_IDLE; TimeOutSet(&Out_15S_Before_Stop_Timer,0); mode_state = 0; } else if( key.KeyEventCode == ADC_KEY_CODE_RIGHT && key.KeyScanState >= KEYSCANSTATE_HOLD) { { //全放 POWER_ON; MOTOR_OFF; #ifdef FY_SEAT_10 WAIST_1_OUT; WAIST_2_OUT; #endif air_bag_out(); } air_bag_ctrl.current_mode = SEAT_FUNC_MODE_IDLE; TimeOutSet(&Out_15S_Before_Stop_Timer,0); mode_state = 0; } else if( key.KeyEventCode == ADC_KEY_CODE_OK) { if( key.KeyEventType == KEYTYPE_HOLD) { printf("\n\rkey hold\n\r"); TimeOutSet(&ModeSwitch_Timer,1000); if(mode_state) { mode_state = 0; } else { mode_state = 1; } air_bag_ctrl.current_mode = mode_state; air_bag_ctrl.schedule_table_pntr = air_bag_schedule_table[air_bag_ctrl.current_mode]; air_bag_ctrl.current_schedule_index = 0; air_bag_ctrl.last_schedule_index = 0; air_bag_ctrl.current_schedule_duration = 0; TimeOutSet(&StopWork_Timer,work_mode_total_duration[mode_state]); statck_init(); air_bag_idle(); statck_push(&air_bag_ctrl.schedule_table_pntr[0]); printf(" air_bag_ctrl.current_mode : %d\r\n",air_bag_ctrl.current_mode); } else if( key.KeyEventType == KEYTYPE_SINGLE) { //printf("\n\radc key down \n\r"); TimeOutSet(&ModeSwitch_Timer,1000); if(mode_state) { mode_state = (mode_state + 1) % SEAT_FUNC_MODE_AMOUNT ; if(mode_state == 0) mode_state = 1; } air_bag_ctrl.current_mode = mode_state; air_bag_ctrl.schedule_table_pntr = air_bag_schedule_table[air_bag_ctrl.current_mode]; air_bag_ctrl.current_schedule_index = 0; air_bag_ctrl.last_schedule_index = 0; air_bag_ctrl.current_schedule_duration = 0; TimeOutSet(&StopWork_Timer,work_mode_total_duration[mode_state]); statck_init(); air_bag_init(); statck_push(&air_bag_ctrl.schedule_table_pntr[0]); printf(" air_bag_ctrl.current_mode : %d\r\n",air_bag_ctrl.current_mode); } #ifdef FY_SEAT_10 WAIST_1_IDLE; WAIST_2_IDLE; #endif } else { //无按键动作 if(!IsTimeOut(&Out_15S_Before_Stop_Timer)) { { //放气15S POWER_ON; MOTOR_OFF; air_bag_idle(); } } else if(mode_state == 0) { //闭气 air_bag_idle(); POWER_OFF; MOTOR_OFF; #ifdef FY_SEAT_10 WAIST_1_IDLE; WAIST_2_IDLE; #endif } } last_adckey_code = key.KeyEventCode; last_adckey_type = key.KeyEventType; } // else if(mode_state) //循环工作中 // { // if( key.KeyEventCode == ADC_KEY_CODE_OK && key.KeyEventType == KEYTYPE_LONGPRES) // { // //退出循环工作 // air_bag_ctrl.current_mode = SEAT_FUNC_MODE_IDLE; // air_bag_ctrl.autoWorkFlag = 0; // TimeOutSet(&Out_15S_Before_Stop_Timer,SECOND_15); // } // } } void GpioKeyFunc(void) { static unsigned char last_key_code = 0; static unsigned char last_key_type = 0; /* LED KEY */ if(last_key_code != key.KeyEventCode || last_key_type != key.KeyEventType) { if(key.KeyEventCode > 0 && key.KeyEventType > 0 ) printf("\n\rGPIO key KeyEventCode : %d KeyEventType : %d \n\r",key.KeyEventCode , key.KeyEventType); if( key.KeyEventCode == GPIO_KEY_CODE_K6 && key.KeyEventType == KEYTYPE_SINGLE) { //printf("\n\rgpio key down \n\r"); TimeOutSet(&ModeSwitch_Timer,1000); //if(mode_state) { mode_state = (mode_state + 1) % 4 ; } air_bag_ctrl.current_mode = mode_state; air_bag_ctrl.schedule_table_pntr = air_bag_schedule_table[air_bag_ctrl.current_mode]; air_bag_ctrl.current_schedule_index = 0; air_bag_ctrl.last_schedule_index = 0; air_bag_ctrl.current_schedule_duration = 0; TimeOutSet(&StopWork_Timer,work_mode_total_duration[mode_state]); statck_init(); air_bag_init(); statck_push(&air_bag_ctrl.schedule_table_pntr[0]); // printf(" air_bag_ctrl.current_mode : %d\r\n",air_bag_ctrl.current_mode); } last_key_code = key.KeyEventCode; last_key_type = key.KeyEventType; } } /** * @file n32g43x_it.c * @author Nations * @version v1.0.0 * * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. */ #include <stdio.h> #include "n32g43x_it.h" #include "bsp.h" #include "sys_var.h" #include "util.h" extern uint8_t mode_state; /** @addtogroup N32G43X_StdPeriph_Template * @{ */ /******************************************************************************/ /* Cortex-M4 Processor Exceptions Handlers */ /******************************************************************************/ /** * @brief This function handles NMI exception. */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } } /** * @brief This function handles Memory Manage exception. */ void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } } /** * @brief This function handles Bus Fault exception. */ void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } } /** * @brief This function handles Usage Fault exception. */ void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } } /** * @brief This function handles SVCall exception. */ void SVC_Handler(void) { } /** * @brief This function handles Debug Monitor exception. */ void DebugMon_Handler(void) { } /** * @brief This function handles SysTick Handler. */ void SysTick_Handler(void) { } /** * @brief This function handles TIM2 update interrupt request. */ void TIM2_IRQHandler(void) { if (TIM_GetIntStatus(TIM2, TIM_INT_UPDATE) != RESET) //1ms 定时中断 { TIM_ClrIntPendingBit(TIM2, TIM_INT_UPDATE);//重置定时器 //软定时器滴答 TimerTickHandler(); if( (air_bag_ctrl.current_mode != SEAT_FUNC_MODE_IDLE && !IsTimeOut(&StopWork_Timer) && IsTimeOut(&ModeSwitch_Timer) )) { int stack_idx; for(stack_idx = 0;stack_idx < STACK_SIZE;stack_idx++) { if (schedule_stack[stack_idx].IsUsed) { if (schedule_stack[stack_idx].InDuration > 0) { //充气 POWER_ON; air_bag_set_in(schedule_stack[stack_idx].OpAirBagGroup); schedule_stack[stack_idx].InDuration --; } else { if (schedule_stack[stack_idx].OutDuration > 0) { //放气 POWER_ON; air_bag_set_out(schedule_stack[stack_idx].OpAirBagGroup); schedule_stack[stack_idx].OutDuration --; if (schedule_stack[stack_idx].OutDuration == 0) { //停止放气 //放气完毕,出栈 //printf("out end idx %d\r\n",schedule_stack[stack_idx].sch_idx); statck_pop(stack_idx); if(0) { int i; for (i = 0; i < STACK_SIZE; i++) { //printf(" st_idx : %d is_used : %d sch_idx : %d InD :%d OutD :%d NexD : %d \r\n",i,schedule_stack[i].IsUsed,schedule_stack[i].sch_idx,schedule_stack[i].InDuration,schedule_stack[i].OutDuration,schedule_stack[i].NextOpDuration); } } } } } if (schedule_stack[stack_idx].NextOpDuration > 0) { schedule_stack[stack_idx].NextOpDuration --; //下一动作入栈 if (schedule_stack[stack_idx].NextOpDuration == 0) { if(schedule_stack[stack_idx].sch_idx + 1 <= schedule_stack[stack_idx].sch_idx_max) { statck_push(&air_bag_ctrl.schedule_table_pntr[schedule_stack[stack_idx].sch_idx+1]); //printf("next op idx %d\r\n",schedule_stack[stack_idx].sch_idx + 1); { int i; for (i = 0; i < STACK_SIZE; i++) { //printf(" st_idx : %d is_used : %d sch_idx : %d InD :%d OutD :%d NexD : %d \r\n",i,schedule_stack[i].IsUsed,schedule_stack[i].sch_idx,schedule_stack[i].InDuration,schedule_stack[i].OutDuration,schedule_stack[i].NextOpDuration); } } } else { statck_push(&air_bag_ctrl.schedule_table_pntr[0]); //printf("cycle end return 0 idx %d\r\n",schedule_stack[stack_idx].sch_idx); { int i; for (i = 0; i < STACK_SIZE; i++) { //printf(" st_idx : %d is_used : %d sch_idx : %d InD :%d OutD :%d NexD : %d \r\n",i,schedule_stack[i].IsUsed,schedule_stack[i].sch_idx,schedule_stack[i].InDuration,schedule_stack[i].OutDuration,schedule_stack[i].NextOpDuration); } } } } } if(schedule_stack[stack_idx].InDuration == 0 && schedule_stack[stack_idx].OutDuration == 0 && schedule_stack[stack_idx].NextOpDuration == 0) { statck_pop(stack_idx); } } } } else if( (air_bag_ctrl.current_mode != SEAT_FUNC_MODE_IDLE && IsTimeOut(&StopWork_Timer))) { statck_init(); air_bag_idle(); mode_state = 0; air_bag_ctrl.current_mode = SEAT_FUNC_MODE_IDLE; printf(" timeout air_bag_ctrl.current_mode : %d\r\n",air_bag_ctrl.current_mode); } } } /** * @brief This function handles lin usart interrupt request. */ void USART_LIN_S_IRQHandler(void) { } void EXTI15_10_IRQHandler(void) { #ifdef CFG_LOW_POWER_MODE if (EXTI_GetITStatus(LPM_WAKEUP_LINE) != RESET) { /* Clear the Key Button EXTI line pending bit */ EXTI_ClrITPendBit(LPM_WAKEUP_LINE); } #endif } /** * @} */ /***************************************************************************** * Copyright (c) 2022, Nations Technologies Inc. * * All rights reserved. * ****************************************************************************/ /** * @file bsp.c * @author Nations * @version V1.2.2 */ #include <stdio.h> #include "bsp.h" USART_InitType USART_InitStructure; TIM_TimeBaseInitType TIM_TimeBaseStructure; /** * @brief Configures GPIO. * @param GPIOx x can be A to G to select the GPIO port. * @param Pin This parameter can be GPIO_PIN_0~GPIO_PIN_15. */ void GpioInitOut(GPIO_Module* GPIOx, uint16_t Pin) { GPIO_InitType GPIO_InitStructure; /* Check the parameters */ assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); /* Enable the GPIO Clock */ if (GPIOx == GPIOA) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); } else if (GPIOx == GPIOB) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); } else if (GPIOx == GPIOC) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE); } else if (GPIOx == GPIOD) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOD, ENABLE); } /* Configure the GPIO pin */ if (Pin <= GPIO_PIN_ALL) { GPIO_InitStruct(&GPIO_InitStructure); GPIO_InitStructure.Pin = Pin; GPIO_InitStructure.GPIO_Current = GPIO_DC_12mA; GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure); } } /** * @brief Configures GPIO. * @param GPIOx x can be A to G to select the GPIO port. * @param Pin This parameter can be GPIO_PIN_0~GPIO_PIN_15. */ void GpioInitIn(GPIO_Module* GPIOx, uint16_t Pin) { GPIO_InitType GPIO_InitStructure; /* Check the parameters */ assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); /* Enable the GPIO Clock */ if (GPIOx == GPIOA) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); } else if (GPIOx == GPIOB) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); } else if (GPIOx == GPIOC) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE); } else if (GPIOx == GPIOD) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOD, ENABLE); } /* Configure the GPIO pin */ if (Pin <= GPIO_PIN_ALL) { GPIO_InitStruct(&GPIO_InitStructure); GPIO_InitStructure.Pin = Pin; GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Input; GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure); } } /** * @brief Turns selected gpio as output low/hight level. * @param GPIOx x can be A to G to select the GPIO port. * @param Pin This parameter can be GPIO_PIN_0~GPIO_PIN_15. * @param value This parameter can be 0/1. */ void GpioSetOut(GPIO_Module* GPIOx, uint16_t Pin,uint8_t value) { GPIO_InitType GPIO_InitStructure; if(value) { /* Configure the GPIO pin */ if (Pin <= GPIO_PIN_ALL) { GPIO_InitStruct(&GPIO_InitStructure); GPIO_InitStructure.Pin = Pin; GPIO_InitStructure.GPIO_Current = GPIO_DC_12mA; GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure); } GPIOx->PBSC = Pin; } else { /* Configure the GPIO pin */ if (Pin <= GPIO_PIN_ALL) { GPIO_InitStruct(&GPIO_InitStructure); GPIO_InitStructure.Pin = Pin; GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA; GPIO_InitStructure.GPIO_Pull = GPIO_No_Pull; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure); } GPIOx->PBC = Pin; } } /** * @brief Toggles the selected gpio. * @param GPIOx x can be A to G to select the GPIO port. * @param Pin This parameter can be GPIO_PIN_0~GPIO_PIN_15. */ uint8_t GpioGet(GPIO_Module* GPIOx, uint16_t Pin) { return GPIO_ReadInputDataBit(GPIOx, Pin); } /** * @brief Toggles the selected gpio. * @param GPIOx x can be A to G to select the GPIO port. * @param Pin This parameter can be GPIO_PIN_0~GPIO_PIN_15. */ void GpioToggle(GPIO_Module* GPIOx, uint16_t Pin) { GPIOx->POD ^= Pin; } /** * @brief Configures tim2 clocks. */ void TIM_Configuration(void) { /* 公式1:频率Fpwm = 1/T周期 = TIMER_CLK/[(Period+1)*(Prescaler+1)] ①、TIMER_CLK是TIMEx挂在系统时钟APB1总线上的时钟频率; ②、Period是设置在下一个更新事件装入活动的自动重装载寄存器周期的值(计数值); ③、Prescaler是预分频值; ④、频率单位:hz,周期单位:s; */ /* Time base configuration */ TIM_InitTimBaseStruct(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.Period = 5; TIM_TimeBaseStructure.Prescaler = 8999; TIM_TimeBaseStructure.ClkDiv = 0; TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP; TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure); /* TIM2 enable update irq */ TIM_ConfigInt(TIM2, TIM_INT_UPDATE, ENABLE); /* TIM2 enable counter */ TIM_Enable(TIM2, ENABLE); } /** * @brief Configures the different system clocks. */ void RCC_Configuration(void) { /* PCLK1 = HCLK/4 */ RCC_ConfigPclk2(RCC_HCLK_DIV1); /* TIM2 clock enable */ RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2, ENABLE); #ifdef _UART_DEBUG_ /* Enable GPIO clock */ UART_DEBUG_GPIO_APBxClkCmd(UART_DEBUG_GPIO_CLK, ENABLE); /* Enable UART_DEBUG_CLK Clock */ UART_DEBUG_APBxClkCmd(UART_DEBUG_CLK, ENABLE); #endif } /** * @brief Configures the different GPIO ports. */ void GPIO_Configuration(void) { GPIO_InitType GPIO_InitStructure; /* Initialize GPIO_InitStructure */ GPIO_InitStruct(&GPIO_InitStructure); #ifdef _UART_DEBUG_ /* Initialize GPIO_InitStructure */ GPIO_InitStruct(&GPIO_InitStructure); /* Configure LPUART Tx as alternate function push-pull */ GPIO_InitStructure.Pin = UART_DEBUG_TxPin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /******重要 *******/ GPIO_InitStructure.GPIO_Alternate = UART_DEBUG_Tx_GPIO_AF; GPIO_InitPeripheral(UART_DEBUG_GPIO, &GPIO_InitStructure); /* Configure LPAURT Rx as alternate function push-pull and pull-up */ GPIO_InitStructure.Pin = UART_DEBUG_RxPin; GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up; /******重要 *******/ GPIO_InitStructure.GPIO_Alternate = UART_DEBUG_Rx_GPIO_AF; GPIO_InitPeripheral(UART_DEBUG_GPIO, &GPIO_InitStructure); #endif } /** * @brief Configures the nested vectored interrupt controller. */ void NVIC_Configuration(void) { NVIC_InitType NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* Enable the TIM2 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #ifdef _UART_DEBUG_ /* Enable the LPUART Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif } /* USART configuration ------------------------------------------------------*/ void USART_Configuration(void) { USART_InitType USART_InitStructure; USART_StructInit(&USART_InitStructure); #ifdef _UART_DEBUG_ USART_StructInit(&USART_InitStructure); /* UART_DEBUG configuration ------------------------------------------------------*/ USART_InitStructure.BaudRate = 19200; USART_InitStructure.WordLength = USART_WL_8B; USART_InitStructure.StopBits = USART_STPB_1; USART_InitStructure.Parity = USART_PE_NO; USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE; USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX; USART_Init(UART_DEBUG, &USART_InitStructure); /* Enable USARTz Receive and Transmit interrupts */ //USART_ConfigInt(UART_DEBUG, USART_INT_RXDNE, ENABLE); //USART_ConfigInt(UART_DEBUG, USART_INT_TXDE, ENABLE); /* Enable the UART_DEBUG */ USART_Enable(UART_DEBUG, ENABLE); #endif } void ADC_Initial(void) { /* Enable GPIOB clocks */ RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); /* Enable ADC clocks */ RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC, ENABLE); /* RCC_ADCHCLK_DIV16*/ ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB, RCC_ADCHCLK_DIV16); RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV8); //selsect HSE as RCC ADC1M CLK Source //GPIO_Configuration { GPIO_InitType GPIO_InitStructure; GPIO_InitStruct(&GPIO_InitStructure); /* Configure PC0 PC1 as analog input -------------------------*/ GPIO_InitStructure.Pin = ADC_KEY_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Analog; GPIO_InitPeripheral(ADC_KEY_PORT, &GPIO_InitStructure); } // ADC Initial { ADC_InitType ADC_InitStructure; /* ADC configuration ------------------------------------------------------*/ ADC_InitStructure.MultiChEn = DISABLE; ADC_InitStructure.ContinueConvEn = DISABLE; ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE; ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R; ADC_InitStructure.ChsNumber = 1; ADC_Init(ADC, &ADC_InitStructure); /* Enable ADC */ ADC_Enable(ADC, ENABLE); /* Check ADC Ready */ while(ADC_GetFlagStatusNew(ADC,ADC_FLAG_RDY) == RESET) ; /* Start ADC1 calibration */ ADC_StartCalibration(ADC); /* Check the end of ADC1 calibration */ while (ADC_GetCalibrationStatus(ADC)) ; } } uint16_t ADC_GetData(uint8_t ADC_Channel) { uint16_t dat; ADC_ConfigRegularChannel(ADC, ADC_Channel, 1, ADC_SAMP_TIME_55CYCLES5); /* Start ADC Software Conversion */ ADC_EnableSoftwareStartConv(ADC,ENABLE); while(ADC_GetFlagStatus(ADC,ADC_FLAG_ENDC)==0){ } ADC_ClearFlag(ADC,ADC_FLAG_ENDC); ADC_ClearFlag(ADC,ADC_FLAG_STR); dat=ADC_GetDat(ADC); return dat; } /** * @brief 配置低功耗模式 * @param * @param */ void LowPowrModeInit(void) { #ifdef CFG_LOW_POWER_MODE printf("Low Power Mode Configuration\n"); /* Enable PWR and BKP clock */ RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_PWR, ENABLE); /* Enable WKUP pin */ PWR_WakeUpPinEnable(LPM_WAKEUP_NO, ENABLE); #endif } /** * @brief 打印系统时钟信息 * @param * @param */ void PrintSystemClock(void) { RCC_ClocksType RCC_Clocks; RCC_GetClocksFreqValue(&RCC_Clocks); printf("SysclkFreq : %d\n", RCC_Clocks.SysclkFreq); printf("HclkFreq : %d\n", RCC_Clocks.HclkFreq); printf("Pclk1Freq : %d\n", RCC_Clocks.Pclk1Freq); printf("Pclk2Freq : %d\n", RCC_Clocks.Pclk2Freq); printf("AdcPllClkFreq : %d\n", RCC_Clocks.AdcPllClkFreq); printf("AdcHclkFreq : %d\n", RCC_Clocks.AdcHclkFreq); } /** * @brief Configures system clock after wake-up from low power mode: enable HSE, PLL * and select PLL as system clock source. * @param freq: PLL clock eg 108000000 * @param src * This parameter can be one of the following values: * @arg SYSCLK_PLLSRC_HSI, * @arg SYSCLK_PLLSRC_HSIDIV2, * @arg SYSCLK_PLLSRC_HSI_PLLDIV2, * @arg SYSCLK_PLLSRC_HSIDIV2_PLLDIV2, * @arg SYSCLK_PLLSRC_HSE, * @arg SYSCLK_PLLSRC_HSEDIV2, * @arg SYSCLK_PLLSRC_HSE_PLLDIV2, * @arg SYSCLK_PLLSRC_HSEDIV2_PLLDIV2, */ void SetSysClockToPLL(uint32_t freq, uint32_t RCC_SYSCLKSource) { uint32_t pllsrcclk; uint32_t pllsrc; uint32_t pllmul; uint32_t plldiv = RCC_PLLDIVCLK_DISABLE; uint32_t latency; uint32_t pclk1div, pclk2div; uint32_t msi_ready_flag = RESET; uint8_t src = SYSCLK_PLLSRC_HSE; ErrorStatus HSEStartUpStatus; ErrorStatus HSIStartUpStatus; if (HSE_VALUE != 8000000) { /* HSE_VALUE == 8000000 is needed in this project! */ while (1); } /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */ if ((src == SYSCLK_PLLSRC_HSI) || (src == SYSCLK_PLLSRC_HSIDIV2) || (src == SYSCLK_PLLSRC_HSI_PLLDIV2) || (src == SYSCLK_PLLSRC_HSIDIV2_PLLDIV2)) { /* Enable HSI */ RCC_ConfigHsi(RCC_HSI_ENABLE); /* Wait till HSI is ready */ HSIStartUpStatus = RCC_WaitHsiStable(); if (HSIStartUpStatus != SUCCESS) { /* If HSI fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error Go to infinite loop */ while (1); } if ((src == SYSCLK_PLLSRC_HSIDIV2) || (src == SYSCLK_PLLSRC_HSIDIV2_PLLDIV2)) { pllsrc = RCC_PLL_HSI_PRE_DIV2; pllsrcclk = HSI_VALUE/2; if(src == SYSCLK_PLLSRC_HSIDIV2_PLLDIV2) { plldiv = RCC_PLLDIVCLK_ENABLE; pllsrcclk = HSI_VALUE/4; } } else if ((src == SYSCLK_PLLSRC_HSI) || (src == SYSCLK_PLLSRC_HSI_PLLDIV2)) { pllsrc = RCC_PLL_HSI_PRE_DIV1; pllsrcclk = HSI_VALUE; if(src == SYSCLK_PLLSRC_HSI_PLLDIV2) { plldiv = RCC_PLLDIVCLK_ENABLE; pllsrcclk = HSI_VALUE/2; } } } else if ((src == SYSCLK_PLLSRC_HSE) || (src == SYSCLK_PLLSRC_HSEDIV2) || (src == SYSCLK_PLLSRC_HSE_PLLDIV2) || (src == SYSCLK_PLLSRC_HSEDIV2_PLLDIV2)) { /* Enable HSE */ RCC_ConfigHse(RCC_HSE_ENABLE); /* Wait till HSE is ready */ HSEStartUpStatus = RCC_WaitHseStable(); if (HSEStartUpStatus != SUCCESS) { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error Go to infinite loop */ while (1); } if ((src == SYSCLK_PLLSRC_HSEDIV2) || (src == SYSCLK_PLLSRC_HSEDIV2_PLLDIV2)) { pllsrc = RCC_PLL_SRC_HSE_DIV2; pllsrcclk = HSE_VALUE/2; if(src == SYSCLK_PLLSRC_HSEDIV2_PLLDIV2) { plldiv = RCC_PLLDIVCLK_ENABLE; pllsrcclk = HSE_VALUE/4; } } else if ((src == SYSCLK_PLLSRC_HSE) || (src == SYSCLK_PLLSRC_HSE_PLLDIV2)) { pllsrc = RCC_PLL_SRC_HSE_DIV1; pllsrcclk = HSE_VALUE; if(src == SYSCLK_PLLSRC_HSE_PLLDIV2) { plldiv = RCC_PLLDIVCLK_ENABLE; pllsrcclk = HSE_VALUE/2; } } } latency = (freq/32000000); if(freq > 54000000) { pclk1div = RCC_HCLK_DIV4; pclk2div = RCC_HCLK_DIV2; } else { if(freq > 27000000) { pclk1div = RCC_HCLK_DIV2; pclk2div = RCC_HCLK_DIV1; } else { pclk1div = RCC_HCLK_DIV1; pclk2div = RCC_HCLK_DIV1; } } if(((freq % pllsrcclk) == 0) && ((freq / pllsrcclk) >= 2) && ((freq / pllsrcclk) <= 32)) { pllmul = (freq / pllsrcclk); if(pllmul <= 16) { pllmul = ((pllmul - 2) << 18); } else { pllmul = (((pllmul - 17) << 18) | (1 << 27)); } } else { while(1); } /* Cheak if MSI is Ready */ if(RESET == RCC_GetFlagStatus(RCC_CTRLSTS_FLAG_MSIRD)) { /* Enable MSI and Config Clock */ RCC_ConfigMsi(RCC_MSI_ENABLE, RCC_MSI_RANGE_4M); /* Waits for MSI start-up */ while(SUCCESS != RCC_WaitMsiStable()); msi_ready_flag = SET; } /* Select MSI as system clock source */ RCC_ConfigSysclk(RCC_SYSCLK_SRC_MSI); FLASH_SetLatency(latency); /* HCLK = SYSCLK */ RCC_ConfigHclk(RCC_SYSCLKSource);//RCC_SYSCLK_DIV1 /* PCLK2 = HCLK */ RCC_ConfigPclk2(pclk2div); /* PCLK1 = HCLK */ RCC_ConfigPclk1(pclk1div); /* Disable PLL */ RCC_EnablePll(DISABLE); RCC_ConfigPll(pllsrc, pllmul, plldiv); /* Enable PLL */ RCC_EnablePll(ENABLE); /* Wait till PLL is ready */ while (RCC_GetFlagStatus(RCC_CTRL_FLAG_PLLRDF) == RESET); /* Select PLL as system clock source */ RCC_ConfigSysclk(RCC_SYSCLK_SRC_PLLCLK); /* Wait till PLL is used as system clock source */ while (RCC_GetSysclkSrc() != 0x0C); if(msi_ready_flag == SET) { /* MSI oscillator OFF */ RCC_ConfigMsi(RCC_MSI_DISABLE, RCC_MSI_RANGE_4M); } } void LPM_WakeupExtiInit(GPIO_Module* GPIOx, uint16_t Pin) { } void AllGpioDeInit(void) { #ifdef _LPUART_DEBUG_ GpioInitIn(UART_DEBUG_GPIO,UART_DEBUG_TxPin); GpioInitIn(UART_DEBUG_GPIO,UART_DEBUG_RxPin); #endif #ifdef _UART_DEBUG_ GpioInitIn(UART_DEBUG_GPIO,UART_DEBUG_TxPin); GpioInitIn(UART_DEBUG_GPIO,UART_DEBUG_RxPin); #endif GpioInitIn(LED); } #ifdef _UART_DEBUG_ /* retarget the C library printf function to the LPUART */ int fputc(int ch, FILE* f) { USART_SendData(UART_DEBUG, (uint8_t)ch); while (USART_GetFlagStatus(UART_DEBUG, USART_FLAG_TXDE) == RESET) ; return (ch); } #endif #if !defined(_LPUART_DEBUG_) && !defined(_UART_DEBUG_) int fputc(int ch, FILE* f) { return (ch); } #endif #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file pointer to the source file name * @param line assert_param error line source number */ void assert_failed(const uint8_t* expr, const uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ //while (1) { } } #endif /** * @} */ /** * @} */ 现在的初始化(配置)有问题吗?如何在只改细节的情况下修改
最新发布
10-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值