- Date:2023-06-05

  • Time:15:31
  • Subject: none
  • Tags: #stm32
    [[2023-06]]

sys文件夹介绍

Pasted image 20230605153158|600

deley文件夹介绍

deley文件夹函数简介

Pasted image 20230605154243|600

SysTick工作原理

SysTick,即系统滴答[[定时器]],包含在M3/4/7内核里面,核心是一个24位的递减计数器(2的24次方,来一个脉冲就递减)
Pasted image 20230605154419|600
每次VAL到0时,VAL自动从LOAD重载!开始新一轮递减计数!

SysTick寄存器介绍

SysTick控制及状态寄存器(CTRL)

Pasted image 20230605155740|600

SysTick重装载数值寄存器(LOAD)

Pasted image 20230605155836|600

SysTick当前数值寄存器(VAL)

Pasted image 20230605160021|600

delay_init()函数(f1)

1
2
3
4
5
6
7
8
void delay_init(uint16_t sysclk)//传入72(mhz)
{
  SysTick->CTRL = 0;//hal库清空,再配置
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);//八分频,所以是72/8=9,计数频率是9mhz
  g_fac_us = sysclk / 8;//1us时机的来源
  //自动重装装载值,上面写的72/8=9,我们需要9,传入的是72,所以要处理,
  //1us是1/1000000s,频率f=9mzh,也就是T=1/9mhz=1/9000000s,因此乘以9,在这个计数频率的情况下,数九次才算1us
}

delay_us()函数(f1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void delay_us(uint32_t nus) 
{
uint32_t temp;
SysTick->LOAD = nus * g_fac_us; /* 时间加载 */ //与上面的init照应,乘以9,
SysTick->VAL = 0x00; /* 清空计数器 */
SysTick->CTRL |= 1 << 0 ; /* 开始倒数 */
do
{
temp = SysTick->CTRL;
} while ((temp & 0x01) && !(temp & (1 << 16))); /* CTRL.ENABLE位必须为1, 并等待时间到达 */ //1000000000000000(2)==2^16==65536
SysTick->CTRL &= ~(1 << 0) ; /* 关闭SYSTICK */
SysTick->VAL = 0X00; /* 清空计数器 */
}

delay_ms()函数(f1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//利用微秒延时函数实现
//us最多可以计数记多少秒:1/9000000*2^24=1s左右
void delay_ms(uint16_t nms) //传入要延时多少毫秒
{
uint32_t repeat = nms / 1000; /* 这里用1000,是考虑到可能有超频应用,
//取大于1000部分 * 比如128Mhz的时候, delay_us最大只能延时1048576us 约为1s
*/
uint32_t remain = nms % 1000; //取小于1000部分
while (repeat)
{
delay_us(1000 * 1000); /* 利用delay_us 实现 1000ms 延时 */ 也即是1s
repeat--; //把1000整数倍部分完成
}
if (remain)
{
delay_us(remain * 1000); /* 利用delay_us, 把尾数延时(remain ms)给做了 */
}
}

- Date:2023-06-05

  • Time:17:08
  • Subject: none
  • Tags: #stm32
    [[2023-06]]

printf函数输出流程

Pasted image 20230605171222|600

printf的使用

1
2
3
4
5
6
//printf("字符串\r\n");
printf("Hello World!\r\n");

//printf("输出控制符",输出参数);
uint32_t  temp = 10;
printf("%d\r\n", temp);          /* %d是输出控制符,temp是输出参数 */

常用输出控制符表

Pasted image 20230605172851|600

常用转义字符表

Pasted image 20230605172915|600

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
//printf("输出控制符1输出控制符2…",输出参数1,输出参数2,…);
uint32_t temp1 = 5;
uint32_t temp2 = 10;
printf("%d%x \r \n", temp1,temp2);

//printf("非输出控制符 输出控制符 非输出控制符",输出参数);
uint32_t  temp = 10;  
printf("temp=  %d  收到over\r\n", temp);

//如何输出%、\和双引号
printf("%% \r\n");// %
printf("\\\r\n");// \
printf("\"\"\r\n");// ""

printf函数支持

Pasted image 20230605173458|600

半主机模式简介

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

方法一:微库法

在魔术棒->Target选项卡,勾选:Use Micro LIB,即可避免半主机模式
Pasted image 20230605173808|600

方法二:代码法

1个预处理、 2个定义、3个函数,会用就行

  1. pragma import(__use_no_semihosting),确保不从C库中使用半主机函数

  2. 定义:__ FILE结构体,避免HAL库某些情况下报错
  3. 定义: FILE __ stdout,避免编译报错
  4. 实现:_ ttywrch、_ sys_exit和_sys_command_string等三个函数
    在历程(uart.c)中已经实现了
    到时候拷贝就好

微库法 VS 代码法

Pasted image 20230605174027|600

实现fputc函数

Pasted image 20230605175055|600
也不需要怎么知道