- 博客(55)
- 收藏
- 关注
原创 STM32项目学习19——定时器PWM与舵机应用
PWM全名为pulse width modulation,脉冲宽度调制。通过对脉冲宽度进行调制,等效出需要的波形,对模拟信号进行数字编译。简单来说,PWM就是周期内不断变化的高低电平信号的组合。占空比指高电平占整个周期的百分比,方波占空比就是50%。PWM主要用于呼吸灯、控制直流电机弧舵机。
2025-06-23 11:17:30
1089
原创 STM32项目学习18——超声波模块
工作原理1、采用IO触发测距,需要至少10us的高电平信号。所以需要单片机给模块输入10us高电平信号2、模块自动发送8个40KHz方波,自动检测是否有信号返回3、若有信号返回,通过IO输出高电平信号,高电平持续时间就是超声波从发射到返回的时间。单片机接收模块输出的高电平信号。4、HC-SR04提供2-400cm测距功能,误差在3mm硬件连接。
2025-06-20 21:36:08
1102
原创 STNM32项目学习17——定时器和定时器中断
顾名思义,定时器是用来记录时间的工具,也是STM32的一个外设。STM32共有8个定时器,两个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和两个基本定时器(TIM6、TIM7)项目所用到的STM32F103C8T6只有4个定时器,分别是TIM1、TIM2、TIM3、TIM4三类定时器的区别高级定时器具有捕获/比较通道和互补输出,通用定时器只有捕获/比较通道,基本定时器以上都没有。
2025-05-19 11:57:46
800
原创 STM32项目学习16——透传和多连接TCP Server
透传相较于前两节采用的普通传输模式,数据没有经过打包封装,数据实时性更好。但是透传模式仅限于TCP Client单链接模式或者UDP固定传输模式才能使用。透传模式下,传输数据不需要设定数据长度,但是透传模式下传输的数据长度也是有限制的,每包最大为2048个字节,或者每包数据以20ms间隔区别。
2025-05-15 17:53:11
899
原创 STM32项目学习15——WIFI模块远端UDP传输
然后转到串口调试一栏,端口号选择UDP,远程一栏输入ESP的STAIP,UDP端口可任意设置,最后连接。第三,四个参数为远端IP和端口,即PC端建立的UDP本地端口,注意是本地端口,远程端口是ESP的IP。但是远端可变UDP传输不仅可以给设定好的IP端口发送数据,还可以给IP不同端口传输数据。因为两个端口的远程端口都是连接ESP的IP端口,因此都可以给ESP发送数据。因为我们选择的是UDP多连接模式,因此建立传输的AT指令有较多参数。第二个参数为连接类型,“TCP”,“UDP”,“SSL”
2025-05-14 21:01:52
712
原创 STM32项目学习14——WIFI模块
由一颗ESP8266作为主控和一块flash作为储存芯片组成,供电采用3.3V电压供电,使用串口进行烧录和AT指令集调试。如果把模块连接到单片机,可以实现控制控制灯,继电器,舵机灯具有开关功能的远程控制。两种模式共存,既可以通过路由器连接到互联网,也可以作为WIFI热点使其他设备连接到模块,实现广域网和局域网的无缝切换。AT+CWJAP="SSID","password" 输入PC连接的WiFi信号名称和密码,即手机热点名称和密码。模块出厂自带出厂固件,如果需要其他开发需要烧录固件,自行找到对应的固件。
2025-05-10 16:43:44
156
原创 STM32项目学习13——蓝牙模块
手机输入1→蓝牙模块接收数据,通过TX,经过PA3进入单片机→单片机收到数据,触发USART2中断函数,点亮LED,并输出“LED IS ON”→printf函数重定向通过USART1传输数据→USART1经过PA9输出“LED IS ON”到电脑显示。安信可串口调试界面如下。//-----------------------USART1电脑-------------------------//--------------------------USART2蓝牙----------------------
2025-04-25 18:28:19
1070
原创 STM32项目学习12——串口中断接收和串口控制LED
串口中断接收的步骤与串口USART项目大致一样,但是串口中断通信涉及到中断,因此在进行初始化还需要兼顾中断和中断管理器,但因为串口中断不同于外部中断,只需要在原来的基础上对NVIC即中断嵌套管理器进行初始化即可。另外,类似于外部中断需要将GPIO与外部中断线绑定,在将串口与中断信号绑定。需要用到的函数USART_ITConfig 串口中断配置,包含3个参数,分别是串口,中断信号和失能或使能。本项目以接收串口数据为例进行编程,串口选用USART1,中断信号选择接收数据寄存器非空标志位,启用中断。
2025-04-24 16:07:27
989
原创 STM32项目学习11——自定义字符串串口通信
如果不是空的,那程序代码就会停留在这一行代码,直到TDR为空。注意,因为TXE=0/RESET时,说明TDR不为空,所以需要while循环进行等待,直到TXE=1/SET,此时TDR为空,TXE不满足while的条件,进而跳出循环。从USART框图可以知道,发送数据的流程:CPU将数据写入发送数据寄存器,然后再将数据传到发送移位寄存器,最后传到TX引脚,输出到外设。然后硬件自动将TDR中的数据传输到发送移位寄存器,因为硬件传输也需要时间,因此在TDR不完全完全为空时,TXE一直为0,依然在循环。
2025-04-22 23:25:52
750
原创 STM32项目学习10——串口USART
与此同时,因为PA9和PA10是作为串口作用的,而不是简单的输出输入高低电平,还需要在中文手册里查看外设的GPIO配置。速度比并行通信慢,但是占用的硬件资源少,通常只需要时钟线,一到两根数据线和片选线即可。fPCLK:外设时钟总线,USART1在APB2,最高可取72MHz,其余四个在APB1,最高可取36MHz。数据位:可以是5-8位逻辑‘0’或‘1’,先传输bit0,再传输bit1,以此类推,从低位开始传输。5、字符帧也叫数据帧,包括起始位,数据位,奇偶校验位,停止位等,属于异步通信的重要指标。
2025-04-21 20:19:28
176
原创 STM32项目学习9——外部中断
打开startup_stm32f10x_hd.s,文件中包含多种中断函数,项目采用的是EXTI0通道,所以找到EXTI0_IRQHandler函数。STM32中有20条外部中断线,其中16条是GPIO中断线(0~15),EXTI线16连接PVD输出,EXTI线17连接RTC闹钟事件,EXTI线18连接USB唤醒事件,EXTI线19连接以太网唤醒事件(只适用于互联产品)如图所示,以PA0为例,PA0既可以作为普通的I/O口用作输入输出,还可以作为TIM2_CH1_ETR,定时器2通道1的外部触发源。
2025-04-17 20:24:20
992
原创 STM32项目学习8——433M无线传输
数据发射模块的工作频率为315M,采用声表谐振器SAW稳频,频率稳定度极高,当环境温度在-25~+85度之间变化时,频飘仅为3ppm。接收到信号,接收模块对应针脚输出高电平,有D0 D1 D2 D3,可能对应遥控器的AVB/C/D。发射器不同按键控制接收器D0-D3引脚输出高电平,然后STM32接收对应引脚的高电平,执行不同的操作。本项目通过433M无线控制LED2亮灭。USER文件夹新建433M文件夹,新建433M.c和433M.h。D0-D4:连接输入信号引脚,当发射器按键变换控制外设信号。
2025-04-16 11:45:10
536
原创 STM32项目学习7——震动传感器
假设震动传感器DO口接的是PB8,那么当PB8收到的是低电平时,触发PA1口输出低电平,使LED灯亮1s,然后熄灭。接线上,震动传感器VCC接3.3V,GND接GND,DO接PB8;继电器VCC接3.3V,GND接GND,IN接PA0,COM口接VCC,NO口接LED灯VCC;正常工作时,DO口输出高电平,震动瞬间,DO口输出低电平。打开keil工程文件,USER导入shake.c,添加stm32f10x.h和shake.h源文件,并定义函数,初始化结构体,开启外设时钟信号等。shake.c代码如下。
2025-04-14 20:42:21
1042
原创 STM32项目学习6——继电器
继电器是一个电控开关,基于电磁感应原理,内部包括一个电磁线圈和一组触点。用于控制高电流或者高电压的电路。NC(normally close):常闭接口,继电器吸合前与COM端相连,吸合后悬空。NO(normally open):常开接口,继电器吸合前悬空,吸合后与COM相连。COM(common):公共端,替班为中间触点,可以与常开或者常闭触点相连。IN:控制输入信号,连接控制信号,信号变化会改变继电器连接状态。VCC:供电正极,连接电源提供继电器电流。GND:连接电源负极或接地。
2025-04-13 17:13:46
349
原创 STM32项目学习5——按键控制
但是注意,这次使用的是输入模式,因为是通过PA0和PC13得到的电平信号决定PA1引脚输出哪种电平信号。然后在keil工程中添加button.c文件,添加button.h和stm32f10x.h源文件。如果SW3按键按下,PC13接到GND,变成低电平,此时PA1输出高电平,LED灭。如果SW2按键按下,PA0接到GND,变成低电平,此时PA1输出低电平,LED亮;在gpio.h源文件中可以找到有四行函数,注释已经标好,作用就是读取引脚的信号。假设SW2控制LED亮,SW3控制LED灭。
2025-04-13 15:10:39
932
原创 STM32项目学习4——蜂鸣器
无源:内部无震荡源,需要外部脉冲信号驱动发声声音频率可变。所以改变频率可以改变音色。有源:内部有震荡源,只要通电就可以自动发出固定频率的声音。所以频率无法改变音色。蜂鸣器是一种简单的电子发声元器件,直流电压供电。蜂鸣器的步骤与前面的LED灯基本一致,不过多作注解。开始编写程序前,需要观察一下蜂鸣器的触发方式。
2025-04-11 23:18:59
511
原创 STM32项目学习3——点亮LED
LED正极接3.3V,负极接到PA1引脚。因此要想点亮LED只需要控制PA1输出低电平即可流程:初始化GPIO外设时钟初始化LED引脚输出电平信号步骤在USER文件夹下创建LED文件夹,存放led.c和led.h,用于定义和声明函数在keil工程中,USER下添加led.c文件,并输入代码可以发现程序会报错,因为程序中没有找到led.h源文件。所以通过魔术棒,在C/C++一栏找到include paths,添加LED文件夹,此时编译,程序才能找到led,h源文件,编译成功。
2025-04-10 21:03:00
300
原创 STM32项目学习2——GPIO控制
GPIO,全称general purpose input/output,通用输入/输出接口,用于感知外部信号(输入模式)和控制外部设备(输出模式)简单项目:LED控制,按键,蜂鸣器,温度传感器等,使用一个GPIO就可以实现复杂项目:OLED模块,FLASH,六轴传感器等需要多个引脚组成“协议”传输数据,例如USART,IIC,SPI等通信协议MCU单片机大都采用引脚复用模式,也就是用一个GPIO控制输出电平高低,也可以设置为某个通信协议的引脚之一。
2025-04-09 20:45:33
579
原创 STM32项目学习1
在main.c打开stm32f10x.h文件,找到stm32f10x_conf.h,发现需要宏定义USE_STDPEROPH_DRIVER才包含这个源文件。打开魔术棒,找到C/C++,有一栏define,在里面输入USE_STDPEROPH_DRIVER,再编译,结果如下图。在keil工程文件里面也需要包含多个文件,START_UP,USER,CMSIS,DOC,FWLIB。点击魔术棒,选择C/C++,找到include path添加.h源文件,然后再进行编译,结果如下图。
2025-04-08 18:14:42
392
原创 从头开始学C语言第三十六天——函数指针和函数指针数组
函数指针用来存放函数地址,这个地址就是一个函数的入口函数名代表函数的入口地址一般形式:<数据类型> (*<函数指针名称>) (<参数说明列表>);数据类型是函数指针所指函数的返回值类型参数说明列表应该与函数指针所指函数形参保持一致函数指针名称中,*说明是指针不可缺少的,意为函数指针运行程序会发现,函数指针本质上跟前面学的指针没什么区别,只是所指对象的区别。定义了一个函数指针,并指向add这个函数的地址,在输出结果时,既可以通过函数add,也可以通过指针*p。
2025-03-30 17:32:10
417
原创 从头开始学C语言第三十五天——指针函数、递归函数
是指函数返回值为地址值的函数定义:<数据类型> *<函数名称> (<参数说明>)语句序列;指针函数的返回值:全局变量的地址/static变量的地址/字符串常量的地址用指针函数删除字符串中的空格指针函数替代strcat函数。
2025-03-28 18:11:59
226
原创 从头开始学C语言第三十四天——函数数组传参
但是我们运行程序发现,函数add中用于表示数组长度变量n结果是2,并不是5。因为数组作为函数参数传递时,数组会退化成指针,所以add函数中的数组a实际上不是数组,而是指针。64位电脑的指针默认是8个字节,int数据类型是4个字节,所以计算出来的n=2,导致结果出错。所以为了避免这种情况,我们需要在main函数里面提前把数组长度计算出来,再将它作为参数复制传递到add函数内部。以计算一维数组的元素之和为例,用函数的方法实现可以写出这个程序代码。因此add函数除了需要数组参数,还需要一个整型参数。
2025-03-26 12:06:11
388
原创 从头开始学C语言第三十三天——函数的参数传递
函数之间的参数传递分为三种:全局变量:在函数体外定义说明,程序中的每个函数都可见,函数调用的位置不同,程序结果也会受影响,不建议使用。因为程序中的每个函数都可以使用全局变量,如果全局变量在经过某个函数后发生了变化,那么就会对结果产生影响,所以一般不建议使用。复制传递:调用函数的实参传递给被调函数,被调函数将创建同类型的形参并用实参对形参进行初始化。形参是新开辟的存储空间,因此改变形参不影响实参,
2025-03-25 18:01:32
521
原创 从头开始学C语言第三十二天——函数
函数可以定义为完成特定功能的模块,函数程序代码独立,通常要求要有返回值,也就是return,也可以返回空值0主要函数分为三类:主函数也就是main函数库函数,包括用过的scanf,printf,strlen,strcpy等包含在stdio.h,string.h等库中自定义函数,程序员自己定义的函数模块一般形式:<数据类型> <函数名称> (<形式参数>)语句序列;return[(<表达式>)];数据类型是整个函数返回值的类型。
2025-03-24 16:39:58
483
原创 从头开始学C语言第三十一天——void指针和const指针
void指针是一种不确定数据类型的指针,可以通过强制转换类型让该指针指向任何数据类型的变量。说明形式:void *<指针名>对于void指针,在没有强制转换数据类型之前,不能进行指针的算术运算这一行代码中,如果我们直接输出*p,那系统弄会报错,因为此时指针p是void类型,也就是还不确定数据类型的指针,%d要求输出的是十进制的整型数因此会出现类型不匹配的错误,所以需要写成*(int *)p的形式;
2025-03-23 18:21:20
581
原创 从头开始学C语言第三十天——多级指针
指向处理数据的指针变量称为一级指针指向一级指针的指针变量称为二级指针二级指针说明形式:<存储类型> <数据类型> **<指针名称>;指针变量+1是向地址大的方向移动一位。同理,多级指针运算也是以其目标变量为单位进行偏移。例如int **p;p++;指针p向地址大的方向移动一位。同样的,指针数组也可以由一个指针来处理
2025-03-23 16:50:22
392
原创 从头开始学C语言第二十九天——指针数组
运行程序我们可以发现,p[0]的地址和a[0]地址相同,p[1]的地址和a[2]地址相同。所以我们可以发现,指针数组p[0]包含两个元素,分别是a[0]和a[1]的地址值,输出地址时输出的是a[0]的首地址,以此类推。指针数组和前面提到的数组,字符数组,字符串数组一样都是数组,区别就是他们组成的元素不同。将数组a[0]和a[1]的首地址分别赋给指针数组pa的数组元素pa[0],pa[1]<存储类型> <数据类型> *<指针数组名称> [<大小>]指针数组其实就是相同数据类型和存储类型的指针变量组成的集合。
2025-03-22 17:34:18
343
原创 从头开始学C语言第二十八天——字符指针和字符串
C语言通过字符数组处理字符串。通常把char类型的指针变量称为字符指针,字符指针也被用来处理字符串。初始化字符指针就是把字符串的首地址赋予指针,不是把字符串复制到字符指针。char a[] = "hello world";char *pa = a;*pa指向的不是字符'h',而是字符所在内存的位置。从程序我们可以看到, *pa指向a数组时,我们可以改变a数组的内容。在C语言中,当一个字符指针指向一个字符串常量,不能修改指针指向对象的值。存放在静态存储区的变量有:全局变量,static存储类型变量
2025-03-19 20:23:24
336
原创 从头开始学C语言第二十七天——指针和二维数组
但是在二维数组时,我们发现首地址a和pa取得是同一个地址,但是a+1取得的地址在首地址上多了12,但是pa+1取到的地址是在首地址上多4。因为a+1变化的是行地址,而pa+1变化的是元素地址。所以,a[0]+1改变的是整行元素的地址,而pa+1是单个元素的地址+1。一维数组时,我们可以发现指针和数组取地址时,取到的是同一个地址,不管是首地址还是各自+1后的地址都是同样的地址;元素a[0]和a[1]都是一维数组,每个一维数组都含有三个元素。int a[2][3]含有两个元素:a[0]和a[1]
2025-03-18 19:02:25
310
原创 从头开始学C语言第二十六天——指针和数组
指针和数组在访问数组元素时,一定条件下使用方法具有相同的格式,因为指针和数组名都是指向数组的首地址;但是两者不在本质上并不相同,指针变量是地址变量,而数组的指针是地址常量。例如,指针pa可以执行pa=pa++,而数组名a,不能执行a=a++的操作。假设指针pa的地址等于数组指针a(指针变量pa指向数组的首个元素),那么:a[i],*(pa+i),*(a+i)和pa[i]具有相同功能:访问数组的第i+1个元素。数组的指针是指数组的首地址,数组元素的指针是指数组元素的地址。//a就是数组的首地址。
2025-03-17 16:13:54
402
原创 从头开始学C语言第二十五天——指针运算
指针运算是以指针变量所存放的地址量作为运算量进行的运算指针运算的实质是地址的运算指针运算种类有限,只能进行赋值,算术和关系运算。
2025-03-17 14:42:24
697
原创 从头开始学C语言第二十四天——指针含义
指针指向的内存区域中的数据称为指针的目标。如果它指向的区域是程序中一个变量的内存空间,那这个变量被称为指针的目标变量,简称指针的目标。注意:引入指针要注意程序中的px,*px和&px三种方法的含义,假设px是指针,那么。//pa=a→pa=&a[0],即指针pa指向的是数组a的首地址。向指针变量赋值时,送出的必须是地常量或指针变量,除赋值0以外,不能是普通整数。2、将已有地址的指针变量赋值给相同数据类型的另一个指针变量。1、将普通变量的地址赋值给相同数据类型的指针。px,指针变量,内容是目标的地址量。
2025-03-17 10:47:25
841
原创 从头开始学C语言第二十二天——字符串函数
在使用字符串函数时,需要引用字符串库string.h常用的字符串函数包括strlen 求字符串长度函数strcpy 字符串拷贝函数strcat 字符串连接函数strcmp 字符串比较函数。
2025-03-13 17:21:25
934
原创 从头开始学C语言第二十一天——字符串数组
假设,a[]={"apple"},其中每个元素所占的位置序号为0,1,2,3,4。逆序输出相当于我们的输出顺序应该从0,1,2,3,4变成4,3,2,1,0。这里我们需要引用字符串的头文件string.h,当中的strlen函数可以帮助我们获得实际的字符串的长度,因此可以避免出现乱码或者其余位置输出空的情况。输出字符串数组的时候,分为两种方式,一种是单个字符逐个输出,一种是每次以字符串的类型输出。在输出字符串的时候用一个for循环,i从最高位,即n-1开始输出,到最低位0结束。
2025-03-11 21:03:35
232
原创 从头开始学C语言第二十天——字符数组
运行代码可以看到,printf("%s \n",str1)这一行代码输出的结果去其他三个结果不同,因为str1是字符数组,只能输出字符%c。同样的,str1[]没有对元素个数进行初始化,因此系统默认为'a','b','c'三个元素,当我们以字符串格式输出时,因为没有'\0'作结束,因此输出结果为abc[],而且每次运行的结果都不同。例如,字符类型'a','b','c'想以字符串的形式"abc"输出,那么就需要在'a','b','c'后面再加上'\0',才可转化为"abc"。
2025-03-11 19:37:26
499
原创 从头开始学C语言第十九天——二维数组
二维数组相比于一维数组需要对行数、列数进行定义。int a[3][4]→数组为三行四列,元素个数=行数*列数。特别的是,二维数组在定义声明时,行数可以省略,但是列数不能省略。在内存当中,因为内存是一维的,因此在存储二维数组的时候,按照行数序号优先排列。int a[2][3]右→a[1][1]二维数组a是由两个元素a[0]和a[1],每个元素a[i]是由含有三个元素的一维数组组成。
2025-03-11 11:27:53
786
原创 从头开始学C语言第十八天——冒泡算法
冒泡算法是一种排序算法,类似于从水底逐渐往水面上升而不断变大的泡泡。底层逻辑是通过比较相邻两个数之间的大小关系,如果符合大小关系则不改变顺序,否则则交换两数之间的位置顺序,最终实现数组当中乱序到有序的过程。
2025-03-10 16:02:16
404
原创 从头开始学C语言第十七天——一维数组
数组是具有一定顺序的若干变量的集合,组成数组的变量称为数组的元素。数组概念类似于高中学的集合。数组中的各个元素数据类型必须相同,用数组的名称和下标确定,数组可以是一维的,也可以是多维的。一维数组是指只有一个下标的数组,在计算机中的内存是连续存储。一维数组的说明形式是:<存储类型><数据类型><数组名称>[<表达式>](存储类型:auto、register、static、extern)(数据类型:int、char、float......)例如:int a[4]→注意:C语言不会对数组作越界检查。
2025-03-10 12:07:03
447
原创 从头开始学C语言第十六天——辅助控制语句
break用于从循环体内跳出一层循环体,提前结束循环;因此break只能用于循环和Switch语句。计算结果:r只计算到5,同理area=78点多。因此break可以跳出循环。假如在上述程序中在外部再嵌套一个while(1)的死循环执行程序会发现程序一直在循环r=1-5的面积值,并没有跳出while循环,只跳出了for循环。因此break只能跳出一层循环。
2025-03-09 17:57:09
528
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅