一、标准库(basic)
文件模板(三个文件夹):
1、最主要的函数是:
RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph,Functionalstate NewState);
RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph,Functionalstate NewState);
RCC_APB1eriphClockCmd(uint32_t RCC_APB1Periph,Functionalstate NewState);
(虽然很长但时钟配置别看错了字母了)
.h文件一般都是以下格式:
#ifndef __KEY_H
#define __KEY_H
void Key_Init(void);
uint8_t Key_GetNum(void);
#endif
2、添加文件路径,在这里面(图一)就用(图二)的方法。
3、特殊功用:STM32的 PA13/14/15 & PB3/4无法正常使用,PA13/14/15 & PB3/4默认配置为JTAG功能 。首先,STM32F10x系列的MCU复位后,PA13/14/15 & PB3/4默认配置为JTAG功能。有时我们为了充分利用MCU I/O口的资源,会把这些端口设置为普通I/O口。具体方法如下:
STM32的 PA13/14/15 & PB3/4无法正常使用_pb3按键配置完不管用-CSDN博客
3-2 LED闪烁:
- 函数介绍:
- GPIO_DeInit()调用这个函数之后,所指定的外设就会被复位&&GPIO_Init()一般初始化都是用这个&&GPIO_SetBits以下如图一都是对于GPIO的读写函数&&寻找引脚格式(如图二图三,再回溯定义就行)
- GPIO_ResetBits(GPIOA,GPIO_Pin_0);就是给灯低电平那么灯就会亮,如果是GPIO_SetBits(GPIOA,GPIO_Pin_0)灯就会灭。
二、组建工程
按键/光敏传感器(LDR):
LED模块化,之后在头文件声明一下就行 (图一);按键:GPIO_ReadInputDataBit()就是读取电平函数(图二);光敏传感器(图三)如果是实际传感器,那么有光照时指示灯会灭,没有时会亮
灰色电平:proteus中引脚灰色,说明电平处于非高非低的状态,要么加个上拉电阻(比如80C51系列的一些芯片需要在P0口加上拉电阻),要么加个下拉电阻。试试-+
具体过程(细化):
关于IO口初始电平:
- STM32中空的I/O管脚是高电平还是低电平取决于具体情况:IO端口复位后处于浮空状态,也就是其电平状态由外围电路决定。比如按键按下来就会让iO口检测到是高电平(图一),那就会把灯的电平拉低,那么灯就可以导通亮了;未按时时低电平,那么就不会亮。
- 在没有任何操作的情况下,如果比如灯是采用推挽输出的模式,那么一般都会设置其初始状态为高电平(图二),这样和前面的VCC强灌不会有电平差,也就不会亮,除非后面有被拉低电平。
传感器一般都是用上拉模式,和按键一个道理,就是会改变它的电阻值,如果电阻值低到一定的范围电压就会高到一定程度就相当于按键按下时Io口就会检测到高电平一样。
TIP:
1.小工具:keilkill.bat是一个批处理文件,可以把工程编译产生的中间文件都给删除掉。主要占空间的都是listing和object两个文件夹,如果要分享给别人这个文件,可以先双击一下这个文件,这样就会从20M变成2M的内存空间了。
2.error:Undefined symbol assert_param (referred from misc.o).是因为没添加下面这个
USE_STDPERIPH_DRIVER
3、GPIOx->ODR=Portval;表示把数据写入ODR这个GPIO的寄存器
4、从引脚定义图,PA15、PB3、PB4是JTAG的三个y调试口,所以输出是没现象的 。
5.declaration may not appear after executable sta这种要选有C99的,如下图:
6.除非是带了void的,否则都需要一个返回return,无论是变量还是函数。
7.出现unknown type name uint8_t的提示,则需要加入#include "stdint.h"解决。
8.User\main.c(29): warning: #223-D: function "Beep_on" declared implicitly是很可能是头文件的预定义声明重复了。比如写了两个LED文件,一个是LED1.c,另一个是LED2.c。他们俩都是从LED.c移植过来的,然后头文件忘了修改
OLED
调试方式:
串口调试/显示屏调试:通过串口助手将信息发送到电脑端,使用串口助手显示调试信息。Keil:借助软件的调试模式,可使用单步运行,设置断点,查看寄存器。
SCL和SDA的两个引脚要初始化为开漏输出。
接法(软件置位):
Tip:1.十六进制是16位,Note: source file '.\Hardware\oled.c' - object file renamed from '.\oled.o' to '.\oled_1.o'.:
解决方案:
1、删除重复文件,确保.c文件在工程内不重复
2、关闭KEIL工程,并运行keilkill.bat将编译链接文件全部删除(点开bat即可)
3、打开工程进行编译即可
BEEP
有源蜂鸣器上面贴的是:remove seal after washing,要注意有分正负的,长是正的,短是负的;要接个三极管上去才够电流,如下:
蜂鸣器需要5V供电吗:
当蜂鸣器连上时,出现以下这个提示,烧录不进去:
解决第一个图的方法是:
LCD:
LCD1602(接法):
lm016l和lcd1602通用吗:编程一样。接线上,LM016L不用接电源、对比度电位器,实物要接。其它 一样。
TIP:
1、一直亮不了,难道是我把PB6和PB7的端口锁住了,所以一直没有正常的电平变化的现象(检查一遍):
proteus中一端有了终端标签,那引脚也别忘记接标签了。
warning:
enumerated type mixed with another type
TIM定时器
高级定时器连接的是性能更高的是APB2。通用和基本定时器连接的是APB1
PWM
一、电机
add nem item to group->选择.c文件->改文件路径
TB6612是一款双路H桥型的直流电机驱动芯片,可以控制两个直流电机并驱动其转速和方向。
L298N:
H桥是一个典型的直流电机控制电路,因为它的电路形状酷似字母H,故得名曰“H桥”。 4个三极管组成H的4条垂直腿,而电机就是H中的横杠.
正极接Io口,负极接GND,则是pwm正极性的驱动方法,
设置步骤:1、开启RCC时钟,包括TIM外设和GPIO外设的时钟打开。(都在APB2的时钟上挂载着,定时器也一样,只要追溯进去就行):GPIO_InitStructure
2、配置时基单元,包括这前面的时钟源选择:TIM_TimeBaseInitStructure
3、配置输出比较单元,包括极性、CCR(其含义在开发版中介绍)、CNT等:TIM_OCInitStructure
4、把PWM对应的GPIO口,初始化为复用推挽输出;最后运行控制,启动定时器,就能输出PWM了。 TIM_SetCompare1(TIM2, Compare);
函数详解:
//在总线上找外设的时钟开启
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;基本定时器
TIM_OCInitTypeDef TIM_OCInitStructure;定时器比较输出结构体
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//对于普通的开漏/推挽输出,引脚的控制权是来自于输出控制寄存器的
//而查阅上图,最小面那块,对于定时器控制引脚,就要用复用推挽/开漏输出的模式,定时器就相当于片上外设,只有把引脚控制权交给他,才能使PWM输出波形
//需要初始化哪个函数,就调用哪个通道
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); //用来给结构体赋初值
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); //参数计算:ARR确定频率,CRR(capture compare register)
确定占空比 Freq:
CK_PSC/(PSC+1)/(ARR+1) Duty=CCR/(ARR+1) Reso=1/(ARR+1);根据想要多少精度的分辨率周期占空比,一步步往前推参数值
//TIM_OCMode的选择
#define TIM_OCMode_PWM1 ((uint16_t)0x0060)
#define TIM_OCMode_PWM2 ((uint16_t)0x0070)
TIP:
1、能不能输出PWM,可能和初始化函数在不在前面有关,这样就是关系到能不能给结构体赋初值了,同时要把结构体成员配置完整,有没有用的都先配置了。
2、因为是复用推挽输出模式,查数据手册中默认复用功能,若要用到TIM2的CH3,则对应必须开启PA2时钟在那里输出,关系是死定的一般不能更改。
3、若要更改,则有重定义功能,比如既要用USART2的TX引脚,又要用TIM2的CH3通道,那么他两就冲突了,没法同时用时就可以在重映射(AFIO)的列表下找,那TIM2的CH3就可以从原来的引脚,换到PB10的引脚,这样就避免了两个外设引脚的冲突。
PID温控
(比例积分微分:“pid”可以表示“Proportion(比例)、Integration(积分)、Differentiation(微分)”的缩写)
原理:用pwm脉冲的占空比控制可控硅或者固态继电器的导通/关断时长比值,实际值与设定值偏差减小,占空比也会减小。这个比值越大,温度会越高,比值越小温度越低。根据你采集到的Ds18B20的数值再增减这个pwm占空比,就能得到你想要的温度。PID采用增量算法,位置输出模式,PID的输出结果控制脉宽就可以了。先不要积分和微分项,只要比例。STM32端口信号输出时经PID控制算法计算得出数据,相应的控制PB8输出电平的PWM脉冲信号宽度,通过改变PB8输出电平的高低宽度进而控制加热器的工作状态。
你把ADC转换的实际温度值和设定相减,结果乘以比例,比如,你把比例设定为5,ADC值为230数字量,设定值为250数字量,那就是相差20,那么PWM就是=20*5=100
这个一百可以是8位PWM的占空比,也可以是10位PWM的占空比
如果是8位PWM,那么就是100/255的占空比
如果10位的PWM那就是100/1023,好像有点小,那么,你可以再*2,就有200/1023的占空比了
先进行调试,看一下效果,再对应的加减比例的大小,让温度相对稳定
这是一个多次调试的过程,不可能是半个小时或者一个小时就能搞定的
自整定没学过,就不知道(链接:stm32单片机PID温控系统源程序 18b20,硬件验证通过 - STM32/8)
(链接2:STM32 pid自整定+pid控温+pwm输出 源程序 - STM32/8)
- 半导体制冷片:帕尔贴效应即当有电流通过不同的导体组成的回路时,除产生不可逆的焦耳热外,在不同导体的接头处随着电流方向的不同会分别出现吸热、放热现象。这样就有制冷制热的说法了,就是电流方向不同。既可制冷又可加热等优点,是真正的绿色产品。相比较压缩机制冷,半导体制冷片的效果和性价比更高。
- OVEN:Proteus中的OVEN 是模拟加热的装置,加一定的电压便开始不停的升温,直到电压要消失则开始降温。 仿真时,U形加热器为红色时表示正在加热,发红时将直流电压放过来接,就会制冷,变绿。 T端输出的是电压,温度越高,电压就越高。仿真时可能需要调整一下OVEN的时间参数,要不系统仿真时候不收敛,会提示最小时间问题。
设定预期温度,然后用PID达到所需要的温度
过程(参考Up主代码垃圾电子狗的毕设(已通过答辩)-基于STM32的PID温控系统_哔哩哔哩_bilibili):
1、制冷片是用L298N另外单独供电的嘛?那cooling中的PA6和PA7如果是起到制冷功能的话,应该接入L298N的intA端进行逻辑输入,然后另一端就接在IO口上吗?不太明白这个接线。
答:像下面这样;可能5V只够给L298N正常运行,但要给12V以上才能给两边的使能口分别供够电,已经测了IN3和IN4是3.3V,就是OUTB没有电压输出。
2、不过这个文件中的MOTOR.c是给散热铝的io口初始化和使能的吗?然后Cooling.c是给制冷片io口服务的?对,两边一个加热,一个散热;
3、在使用L298N的时候注意以下几个点,否则out3和out4可能没电压:
1、GND要既和电源共地,也要和单片机共地,这样才能有基准电压参考!!!
2、如果是需要控制通道占空比,就要把ENA跳线帽给拔了,接在输出占空比的IO口上,然后IN1和IN2只是用来控制接入的方向而已;
如下接线:
要仔细考虑是不是接法的电源错了
测万用表的时候一定要有电压差。
V2:现在的这个情况是ENA感觉控制不了电压多少,一使能IN1和IN2就会让A或者B输出差不多12V电压,通过ENA,IN1,IN2控制电机A,通过ENB,IN3,IN4控制电机B。看PWM有没有正常给进去:
分电压的原理:
TIP:
这个是重点,一定要接,不要悬空不接。如果悬空不接,任你怎么捣鼓,out1~out4将没有任何输出,将不起作用。所以,要将这个口接单片机上的5V输出。另外,有些网上的资料说这个5V用于板内取电(关键的地方总是说的很模糊…),可向外供电用于给单片机提供电源。不要信,也不要这样用。
最保险的做法就是将这个5V的口接上单片机上的5V输出就可以了,没必要用这个口对外提供什么电源。至于为什么要接上接单片机上的5V输出,暂可以理解成是为L298N模块提供逻辑计算的电源。
L298N模块接线纪实_l298n驱动接线方法图-CSDN博客^v88^control_2,239^v2^insert_chatgpt&spm=1018.2226.3001.4187
DHT11
遵守单总线协议
TIP:
- 如果有函数值像图一不知道怎么传输的,那就一般都是填地址。如果是数组的可以改为图二的传数组名就行,因为他们就相当于指针。图二&图一:
- error:.\project.axf: Error: L6200E: Symbol dht11_gpio_input multiply defined (by dht11.o and main.o).有很多这个的错误会一起出现的
观察过之后发现这个是必须包含有“dht11.h”的这个头文件的,因为这个头文件里面有下图的定义,那个是寄存器版本的,而我现在的是标准库版本的,所以要找资源就要找.c文件里原本就有GPIO的直接配置
单总线协议:
1、单总线器件内部设置有寄生供电电路(Parasite Power Circuit)。当单总线处于高电平时,一方面通过二极管VD向芯片供电,另方面对内部电容C(约800pF)充电;当单总线处于低电平时,二极管截止,内部电容c向芯片供电。由于电容c的容量有限,因此要求单总线能间隔地提供高电平以能不断地向内部电容C充电、维持器件的正常工作。这就是通过网络线路“窃取”电能的“寄生电源”的工作原理。要注意的是,为了确保总线上的某些器件在工作时(如温度传感器进行温度转换、E2PROM写人数据时)有足够的电流供给,除了上拉电阻之外,还需要在总线上使用MOSFET(场效应晶体管)提供强上拉供电。
单总线的数据传输速率一般为16.3Kbit/s,最大可达142 Kbit/s,通常情况下采用100Kbit/s以下的速率传输数据。主设备I/O口可直接驱动200m范围内的从设备,经过扩展后可达1km范围。
(高电平时,二极管供电,对电容充电;低电平时,二极管截止,停止充电;电路设计方面DHT11,EEPROM):加上拉电阻+MOS管,数据传输速率一般为16.3Kbit/s)
2、单总线通信的功能命令:
主机发出ROM命令,访问指定的从机,接着发出某个功能命令。这些命令允许主机写入或读出从机暂存器、启动工作以及判断从机的供电方式。
3、数据格式:
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据
TIP:
1.在proteus中一直读取不到值,就把输出的Data线连到了PC15,就起码有有一个数值不是0了;
L298N/uln2003
测试电机有没有坏的方法:最原始方法驱动步进电机_哔哩哔哩_bilibili
程序借鉴:基于stm32F103的ULN2003步进电机驱动 源程序 - STM32/8
指电机转过一个齿距角所需脉冲数,通俗的来讲拍数指的是步进电机运行时每转一个齿距所需的脉冲数。以四相电机为例,有四相单四拍运行方式即A-B-C-D-A,有四相四拍运行方式即AB-BC-CD-DA-AB,有四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA-A。直接ABCD划过去就是正方向,反着划就是反方向
TIP:这个电机真奇怪,还得通一下电,试一下到底坏没坏才能按程序所想的去转
ENA那里是要接TIM几的io上去才能控制两边的PWM输出吗?
对啊对啊,那不然定时器怎么起作用,当然要连到ENA和ENB上面才能对他们的速度进行一个调整;一定要接ENA和ENB!!!
ENA是怎么在使能那两个引脚的时候对他们进行一个电压调配的:
PWM的占空比调速不是在ENA和ENB,而是在IN1-IN4,ENA和ENB只要使能给高电平就能控制了,所以4个io需要两个定时器分别的两个通道
AD
配置步骤:
第一步:开启RCC的时钟,包括AD和RCC的时钟,另外ADC的CLK分频器也需要配置。
第二步:如上图,先从GPIO(绿色),把需要的IO口配置成模拟输入的模式。
第三步:随后配置多路输出(黄色),把左边通道接入到右边的规则组列表中。
第四步:配置ADC转换器,用固定的结构体配置各种参数。(如果要用到中断就需要在中断输出控制里用ITConfig函数开启对应的通道输出,然后再在NVIC中配置中断优先级,就能触发中断了)
对应的重要函数解释:
RCC_ADCCLKConfig()//开启ADC预分频
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //我们大多使用STM32的最快PCLK2系统时钟72MHz。 //ADCCLK的时钟由72MHz的6分频能瞒住14MHz以下的要求 为12MHz。 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); //用来开启哪个AD和哪个通道,中间的是优先级,并且最后一个参数是设定了采样时间
ADC_DataAlign = ADC_DataAlign_Right;//采集数据右对齐 ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); //是否允许外出触发控制
ADC_GetConversionValue(ADC_TypeDef* ADCx);//ADC获取转换结果的函数 ADC_InitStructure.ADC_NbrOfChannel = 1;//是设置要转换的总通道数
怎么知道哪个Io口对应的是哪个通道:
proteus中不用ADC0832的原因主要是32内部就已经有了ADC0809了。所以直接打开通道就行,而ADC0832就下面这个的样子:
TIP:传感器要试试到底有没有用,当我们遮住光线时,输出指示灯(D0-LED)灭,代表输出高电平,如果不遮住就是两个灯都亮。这个电位器可以调节高低电平的判断阈值,但如果那个指示灯不会随着遮不遮变化的话,那那个传感器就坏了。
还有两个引脚如果靠的太近,可能不会起作用,可能会有干扰。
UART
- 一般在多个设备互连的时候,都要进行共地,这样电平才能有高低的参考
第一步,把USART和GPIO要用到的时钟打开;第二步,GPIO初始化,把TX配置出复用输出,RX配置成复用输入;第三步,配置USART,直接用一个结构体配置参数;第四步,初始化完成之后,如果需要发送数据就调用一个发送函数,如果是接收就调用接收函数,如果要获取发送和接收的状态,那就调用获取标志位的函数就行;
- 重要函数:
void UART_SendData()就是写DR寄存器,ReceiveData就是读;
fputc函数是printf函数的底层,printf函数在打印的时候,就是不断调用fputc函数一个个打印的。把fputc函数重定向到了串口,那printf自然就输出到串口了。这样才能把printf函数移植好,然后再在主函数直接用printf输出到串口。
- 程序编写过程:
TX引脚是USART外设控制的输出脚,所以要选用复用推挽输出,RX是输入脚,所以选用输入模式。如OUT IN两个概念一样
- proteus串口步骤:
STM32学习:串口通讯(proteus仿真)_proteus 串口数据-CSDN博客^v71^control_1,201^v4^add_ask&utm_term=proteus%E4%B8%B2%E5%8F%A3&spm=1018.2226.3001.4187
virtual serial port drive在proteus中的应用教程:
https://jingyan.baidu.com/article/5553fa82c615ba65a3393471.html
VSPD资料包:https://blog.csdn.net/sinat_37239798/article/details/126849141
串口如下面一个接收一个发送(如上图);
现在在main.c中放Serial_SendString("LED_ON_OK\r\n");是可以接收,不过接收的文本像下面的不对,明天再看看那些文件的功能再改改,现在是接收的问题:
HC05
对于一个全新的蓝牙模块,需要看它有没有配置过AT指令吗?不能直接连:
AT指令可以查设备名字
苹果版Bluetools(可以进行字符发送点灯)步骤从右到左:注意自己收集的程序是以ascii码发送的,不能直接就hex的形式发送00
RFID
用白卡和蓝圆卡滴的现象;51黑电子论坛-单片机 电子制作DIY MCU 嵌入式技术学习;RST改连PC14了;
HAL库
文件结构:
HAL库的文件全部位于STM32Cube_FW_H7_V1.3.0\Drivers\STM32H7xx_HAL_Driver .而stm32h7xx_hal.c/.h是HAL驱动文件,主要负责初始化HAL库的运行环境,向上层提供HAL管理的API。stm32h7xx_hal_cortex.c/.h是Cortex内核的驱动文件,对Cortex-M7内核外设进行了封装,向上层提供了MPU、NVIC、SysTick的管理API。
stm32_hal_legacy.h为提供给STM32CubeMX用于兼容老版本HAL库的文件,仅仅重新定义了一些宏和常量,使HAL库便于维护。stm32h7xx_hal_def.h定义了一些HAL的宏、枚举和结构。
与标准库不同区别,此库在初始化函数定义结构体还是得参考它原本的配置,而不是标准库里的定义结构体。下图是函数里的第一行是区别:
cannot open source input file “xxxxx“: No such file or directory一般都是要在在管理那添加路径。32,15都是一样的。
TIP:移植HAL库时要注意io口的软件程序配置是否正确,比如这个应该是PA1.PA2,那么就不应该是PA0.PB0.PB1:
安装过程:
STM32就是从以下启动文件开始执行的,而视频中所需要的是md.s格式的启动文件,然后剩下的.c.h文件都要添加进来。(带个小钥匙的都是意思为只读文件不给修改)&当开发STM32的各种型号不同时要下载其型号相符的安装包,可以对比一下如果没有安装支持包,文件夹根目录里面是没有DebugConfi这个文件的。
stm32f10x.h就是STM32的外设寄存器描述文件,跟REGX52.H一样的性质;system文件是用来配置时钟的,主频72MHZ就是在这里面的函数配置的。
ADC
作用:可以对0-3.3V之间的低到高任意电平进行量化,最终用一个变量来表示,并且读取后就可以知道引脚的具体电压是多少了。所以实际上是一个电压表。
输入电压范围:0-3.3V。18个输入通道,可测量16个外部和2个内部信号源。ADC是模拟电压转换成数字电压的桥梁,DAC则相反。本实验采取的是逐次逼近型ADC,其内部结构可参考下图。
DAC实验原理:左边IN八路输入进来外部电压,用下面的ABC来选择通道,来选择是测什么的。之后就可以通过比较器和DAC(已知精准电压值的一个参考值)比较,如果DAC较小,就会在右边的三态锁存缓冲器增加数据,从此不断修正,逐渐逼近外部真实电压。
根据上图二可知因为有规则通道数据寄存器的约束,所以如果要同时测得16个通道的数据,那么只会有第十六个数据被传出到地址上,其他十五个就会被挤掉,所以需要有DMA的存在,可以先将那十五个都放在一个地方,保证它完整。(PA0-PB1的十个引脚都是AD模拟电压采集通道,可以接,其他的就不行)
应用:
1、一般来说像光敏电阻、热敏电阻、红外接受管、麦克风等等都可以等效为一个可调电阻。如以下的电路(图一),串联一个固定值的电阻分压来测,因为 VCC到GND的电压是一定的,所以当可调电阻小(光照不够、不够响)的时候,下拉作用变强,输出端电压就下降,那么就可以得出结果。之后PA1直接接到排针上面的引脚就行了。
2、电压转换电路(图二):因为接上的电压有0-5V,而ADC只能测量出0-3.3V的电压,故根据公式:VIN/ (17K+33K) *33K可得出0-3.3V的范围(带值)
3、HAL库配置(PROJECT:GHG上图四)
由于在数据手册中,图三的最后一行写了最大14MHZ,而APB2运用的最大频率为72,也就是用了72MHZ高速运行,所以如果预分频器用了2或者4,都会大于14,故只能用6和8,得到12MHZ和9MHZ.(下图就是时钟配置)
4.在需要用到的外设中启动DMA传输,之后就可以在下面再调用一个DMA传输完成回调函数。是关于时间点的,所以在stm32f1xx_hal_tim.h中可以找到此函数。
5.标准库:写入模式时要写GPIO_Mode_AIN=0x0,也就是会断开GPIO,防止GPIO的输入输出对模拟电压有干扰。
TIP:
1.出现error: L6236E: No section matches selector。这个问题是因为CUBEMX工程在中文目录下,全部切换到英文就没有个这个问题了,有趣的是,还自动生成了启动文件在项目目录内,但就是不在keil里面,只要将项目目录中的启动文件加到keil工程中就可以了。双击左边工程框的文件夹,添加Startup开头的.s文件即可。
2.如果出现..\MYDATA\my_adc.c(14): error: #20: identifier "hadc1" is undefined,就要引用它最原本的头文件,其他根系的可能都不全面,如下的图二:
输出比较
OC(output compare)输出比较可以通过比较CNT 与 CCR寄存器的关系,来对输出电平进行置1、置0或者翻转的操作,用于输出一定频率和占空比的PWM波形 。基本定时器没有比较功能,最好用通用和高级定时器。
DMA-PWM
DMA全称为direct memory access即直接存储器访问。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直接传输数据的通道,能使CPU的效率大为提高。不会占用io,外设占用的是数据流
SPI
SPI协议:
Flash计算2k:如果是想存入最后一页地址的开始后的1k,就需要把那个地址的十进制算出来,然后加上1k乘以1024个字节之后的十进制转化成的二进制
flash为什么擦除失败:擦除失败是因为擦除的单元发生错误导致的,这个时候就看配置的参数有没有什么问题或者漏掉配置的
code-refer:STM32CUBEMX开发GD32F303(17)----内部Flash读写_gd32f303中的flash是nor还是nand-CSDN博客^v93^chatsearchT3_1&utm_term=cubemx%E5%86%85%E9%83%A8FLASH&spm=1018.2226.3001.4187
TIP:
1、出现error:start/core_cm3.c(445): error: non-ASM statement in naked function is not supported,包括ISO C need traslation等error问题点在于可以把编译的版本调低,如下图:
如果出现了missing compiler version 5的解决方法:ARM开发初级-Windows环境下的STM32开发环境搭建(包含missing compiler version 5的解决方法)-学习笔记02-CSDN博客
2、反正出了错误就看那个指示怎么改的,就怎么改,比如说某个.h文件不能直接在某个路径访问,那就按照指示添加相应的文件就行
解决方法:一定要多试几个USB看看,如果听到叮咚一声,那就是连上了。
关于st-link usb communication error的解决方法_stlink usb communication error-CSDN博客
ST-LINK USB communication error解决方法_st-link v2 usb comm-CSDN博客
4.图中的error可能是因为两个原因:
1、文件不在本地电脑直接烧录,所以可以放在桌面直接再试着烧录。
2、可能是因为OBJ里面有一些文件是有烧录方面的错误,所以可以可以全部删掉再重新再在工程编译,之后就会在OBJ文件中重新生成新的文件。
3、上下拉电阻:上拉就是初始状态是位置为高电平、下拉则为低电平 。
三、Cortex-M3补充知识
采用Thumb-2指令集,完全没有使用ARM指令集,即不能执行ARM指令。Thumb-2是16位Thumb 指令集的一个超集,在Thumb-2中,16位指令首次与32位指令并存 。
嵌套向量中断控制器 。
Cortex-M3内核中搭载了一颗中断控制器——嵌套向量中断控制器(NVIC),与内核是紧耦合的,因此我们是在Cortex-M3内核中实现NVIC。
处理器的组成:它由运算器、控制器、寄存器、高速缓冲存储器(Cache)等部件组成,结构相当复杂。
/O接口的分类
按数据传输速率
低速和高速
按数据传输方式
串行和并行
按是否需要物理连接
有线和无线
按是否能连接多个设备
总线式和独占式
IP协议:
IP协议第4版(简称IPv4) 规定,每个IP地址使用4B(32个二进制位 )表示,其中包含有网络号和主机号两部分。 前者用来指明主机所从属的物理网络的编号(称为网络号),后者是主机在所属物理网络中的编号(称为主机号)。
一个IP地址可有4个十进制数来表示,每个十进制数对应IP地址中的一个字节,十进制数之间采用小数点予以分隔, 这种方式被称为“点分十进制“;
Linux
由五个子系统组成:
虚拟文件系统、进程调度、进程间通信、网络接口、内存管理 。
嵌入式Liinux:用户进程、Linux内核、OS系统、硬件
USB
USB2.0可以达到480M/HZ 。
USB3.0可以达到640M/HZ 。
差分传输模式:两个数据线D+和D- 。
差分信号1:D+>VOH (2.8V)
D-
源文件到可执行文件的步骤:
预处理、编译、汇编、链接(代码中使用别的库,此步进行连接)
AMBA总线结构:
AMBA总线协议-先进微控制器总线结构。
ARM寄存器:
R13-堆栈指针SP(arm处理器中通常将寄存器R13作为堆栈指针,stack pointer)
R14-链接寄存器LR(Link register,主要用来保存上一级的函数调用者的地址
R15-程序计数器PC(program count,CPU从内存取指令执行,每执行一次,PC寄存器的地址值会加一就会计数一次)
R16-状态寄存器xPSR(CPSR 与SPSR,
uC|Os_II
1、抢占式实时操作系统\n\n抢占式实时操作系统且每个任务都有自用栈\n\n使用它的栈空间校验函数,可以确定每个任务到底需要多少栈空间\n\n该系统不包含设备驱动程序,只是一个纯内核\n\n不支持时间片轮转调度,所以赋给每个任务的优先级是不相同的\n\n允许每个任务之间有不同的栈空间\n\n升
2.
能够支持的任务数最多是64(保留8个给系统,实际剩下56个)\n\n最多允许的中断嵌套层数可以达到255层\n\n软件结构一般具有:应用软件层,API层,内核层和设备驱动层.
任务管理中空闲任务是系统创建的第一个任务(空闲任务永远不会处于挂起态,还可能运行态,即使优先级最低,一旦其他任务都被堵塞他就可以执行了!)
3,uC/OS系统时钟内核的基本功能(通过GLIBC调用通用函数和内核的内部功能)\n\n任务管理\n时间管理\n内存管理\n任务调度\n任务间通信和同步
最多允许的中断嵌套层数是255层 。
软件结构一般具有应用软件层、API层、内核层和设备驱动层 。
TCP/I网络协议栈分四层:
传输层-网络层-链路层-应用层
有A、B、C类三个地址络 ,其中较常用的是C类前三个字节为网络地址,第四个字节为主机地址 。
存储器:
半导体存储器芯片的存储容量取决于该芯片的地址总线的条数和数据总线的位数 。 系统正在运行的程序的大部分数据和代码存放在主存储器(内存)中
系统尚未运行的程序的大部分数据和代码存放在外部存储器中 。
按照存取特性分为:RAM和ROM
按照物理位置分为:片内存储器和片外存储器以及外部存储器
按照存储信息的类型分为:程序存储区和数据存储器 。
WLAN
无线局域网,采用的是IEEE协议
WI-FI
无线保真
Cache
通常由SRAM(static random acess memory)组成
Flash闪存
分为两类:或非型和与非型 。前者是以字节为单位读取,后者是以行为单位的,虽然速度慢,不过能存的东西多,一般都是用在U盘里 。