正电原子SYSTEM文件夹介绍

开局一条狗(system文件夹),包含工程师日常常用且必备的一些函数和驱动,完全可以运用到实际的项目当中

sys文件夹函数简介

void sys_stm32_clock_init(uint32_t plln)函数

void sys_stm32_clock_init(uint32_t plln)
{
    HAL_StatusTypeDef ret = HAL_ERROR;
    RCC_OscInitTypeDef rcc_oscinitstructure = {0};
    RCC_ClkInitTypeDef rcc_clkinitstructure = {0};

    rcc_oscinitstructure.OscillatorType = RCC_OSCILLATORTYPE_HSE;       /* 外部高速时钟使能HSEON */
    rcc_oscinitstructure.HSEState = RCC_HSE_ON;                         /* 打开HSE */
    rcc_oscinitstructure.HSEPredivValue = RCC_HSE_PREDIV_DIV1;          /* HSE预分频 */
    rcc_oscinitstructure.PLL.PLLState = RCC_PLL_ON;                     /* 打开PLL */
    rcc_oscinitstructure.PLL.PLLSource = RCC_PLLSOURCE_HSE;             /* PLL时钟源选择HSE */
    rcc_oscinitstructure.PLL.PLLMUL = plln;                             /* 主PLL倍频因子 */
    ret = HAL_RCC_OscConfig(&rcc_oscinitstructure);                     /* 初始化 */

    if (ret != HAL_OK)
    {
        while (1);                                                      /* 时钟初始化72M失败,之后的程序将可能无法正常执行,可以在这里加入自己的处理 */
    }

    /* 选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2*/
    rcc_clkinitstructure.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
    rcc_clkinitstructure.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;        /* 设置系统时钟时钟源为PLL */
    rcc_clkinitstructure.AHBCLKDivider = RCC_SYSCLK_DIV1;               /* AHB分频系数为1 */
    rcc_clkinitstructure.APB1CLKDivider = RCC_HCLK_DIV2;                /* APB1分频系数为2 */
    rcc_clkinitstructure.APB2CLKDivider = RCC_HCLK_DIV1;                /* APB2分频系数为1 */
    ret = HAL_RCC_ClockConfig(&rcc_clkinitstructure, FLASH_LATENCY_2);  /* 同时设置FLASH延时周期为2WS,也就是3个CPU周期。 */

    if (ret != HAL_OK)
    {
        while (1);                                                      /* 时钟初始化72M失败,之后的程序将可能无法正常执行,可以在这里加入自己的处理 */
    }
}

RCC_OscInitTypeDef结构体类型成员OscillatorType(选择震荡器类型),可选择的宏有:

这里只对外部晶振进行调整,所以选择HSE。若需要配置其它晶振,用 ‘|’ 接着添加其它晶振宏即可。成员HSEState字面意思。HSEPredivValue分频系数。成员PLL锁相环,PLL有三个成员:State状态、Source时钟源、PLLMUL倍频系数,函数的形参对应这里的倍频值。

RCC_ClkInitTypeDef结构体类型成员ClockType选择要配置的时钟:系统时钟、AHB总线、APB1总线、APB2总线。成员SYSCLKSource选择系统时钟来源,来源于PLL也就是8MHz*9=72MHz。后三个成员分别配置每条总线的预分频系数。

为什么之前用标准库时没有配置这些?

  • 标准库:依赖SystemInit()的默认配置,无需手动调用时钟函数即可运行,但可能无法发挥芯片性能。
  • HAL库:需显式调用时钟配置函数,否则可能使用默认低频时钟(HSI),导致外设异常。
  • 核心差异:HAL库提供了更灵活的时钟配置接口,而标准库的默认配置可能隐藏了关键细节。

delay文件夹函数简介

使用OS(实时操作系统)

不使用OS(裸机)

delay_init()

初始化系统滴答定时器,形参时钟频率

delay_us()

用系统滴答定时器实现微秒延时

delay_ms()

用微秒延时函数实现毫秒延时

usart文件夹介绍

printf函数输出流程

printf函数支持

1、避免使用半主机模式(两种办法:微库法、代码法

2、实现fputc函数(实现单个字符输出)

半主机模式简介

用于 ARM 目标的一种机制,可将来自应用程序代码的输入/输出请求传送至运行调试器的主机。简单说:就是通过仿真器实现开发板在电脑上的输入和输出

方法一:

方法二:

/******************************************************************************************/
/* 加入以下代码, 支持printf函数, 而不需要选择use MicroLIB */

#if 1

#if (__ARMCC_VERSION >= 6010050)            /* 使用AC6编译器时 */
__asm(".global __use_no_semihosting\n\t");  /* 声明不使用半主机模式 */
__asm(".global __ARM_use_no_argv \n\t");    /* AC6下需要声明main函数为无参数格式,否则部分例程可能出现半主机模式 */

#else
/* 使用AC5编译器时, 要在这里定义__FILE 和 不使用半主机模式 */
#pragma import(__use_no_semihosting)

struct __FILE
{
    int handle;
    /* Whatever you require here. If the only file you are using is */
    /* standard output using printf() for debugging, no file handling */
    /* is required. */
};

#endif

/* 不使用半主机模式,至少需要重定义_ttywrch\_sys_exit\_sys_command_string函数,以同时兼容AC6和AC5模式 */
int _ttywrch(int ch)
{
    ch = ch;
    return ch;
}

/* 定义_sys_exit()以避免使用半主机模式 */
void _sys_exit(int x)
{
    x = x;
}

char *_sys_command_string(char *cmd, int len)
{
    return NULL;
}


/* FILE 在 stdio.h里面定义. */
FILE __stdout;

/* MDK下需要重定义fputc函数, printf函数最终会通过调用fputc输出字符串到串口 */
int fputc(int ch, FILE *f)
{
    while ((USART_UX->SR & 0X40) == 0);     /* 等待上一个字符发送完成 */

    USART_UX->DR = (uint8_t)ch;             /* 将要发送的字符 ch 写入到DR寄存器 */
    return ch;
}
#endif
/******************************************************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值