4-STM32开发(模块学习–基础3)

一、MPU6050 & 光电门–编码器 &摄像头:

➽6050:在mpu6050中我们用陀螺仪传感器测角度,用加速度传感器测加速度。通过IIC对MPU6050寄存器进行读写

VCC:接5V电源

GND:接地

SCL:主IIC时钟线 (我接的PB10)

SDA:主IIC数据线 (我接的PB11)

AD0:地址线,接3V地址为0x68,接地地址为0x69(我接的PA15,高电平,地址为0x68)

检查步骤:先看看能不能读取ID值,MPU6050出现问题的原因有几个:

参考:

https://blog.csdn.net/qq_26039737/article/details/79214887

https://www.shuzhiduo.com/A/KE5Q43AqJL/

➽光电门:

关于io定义:

编码器的两个输入引脚借用了输入捕获的通道1和通道2(CH1和CH2),

CH3和CH4不能接编码器

在PID控制中,反馈是重要的一环,而电机速度的反馈就是通过编码器这个东西反馈。测量方法:

1、需要知道参数(例子):比如A项的上升沿和B项上升沿的时间之差是3.5ms,查阅数据手册可以知道转动一个方格的时候小车走了1cm,即可知道编码器旋转的速度了;E选择了TI1和TI2的话就是实际上是倍频了四次(会读四次),

A波形与B波形一次周期就是会有四次相对的变化,故此时的四倍频是全部计数读取(沿和沿之间的变化);

Input filter 设置为6能很好抑制波动,io口设置为上拉输入;ARR 65535;Counter mode为UP;  程序不会自动打开编码器的接口,需要自己开启:TIM_Encoder_Start;每个编码器需要一个定时器;因为F103的定时器是16位的,所以定时器写入的时候不能大于65535

2、具体知道电机速度的方法(M法测速-路程除以时间):

路程就是脉冲数目,查阅电机的数据手册就可以了解电机旋转一圈会出现几个脉冲;

减速比是34(即电机转轴转1圈,电机本身要转34圈)

电机转一圈的物理脉冲数是11 

每一个脉冲所旋转的距离会是: π*d/(脉冲数*4*齿轮加速比例);

例如我使用的电机旋转一周为12个脉冲,乘4再乘齿轮比例4.5等于216;轮径为6cm,也就是直径为18.84约19cm,也就是0.19m,接下来还得取时间:

自己可以用中断去取时间,比如在滴答定时器里面定义i是增到50ms时,根据编码器的读取函数,然后再读取编码器的时间,然后再让他除以50个ms,就可以得到电机此时的运行速度了,返回上位机就行;

但实际上如果要进行PID运算时,并不需要精确的速度,只需要传入脉冲个数,比如50ms,我捕获到他转了100个脉冲,直接把这100个脉冲传给接下来的PID计算的函数;

PID的三个变量调整对应图,右上角是参数赋值:60fed80a7655405cb22885ad3f902cb3.png

 对于I:累加的I才能回到正确的轨道线1,前面的历史误差让它有回到正确轨道的根据:

cafc91e54b304f2481b4af217c97cea4.png

16c1d69a5ff240c78cc7c374cd77f391.png VOFA+ 专为PID调试(对接收到数据进行波形绘制):https://www.bilibili.com/video/BV1zT411B7kg/?spm_id_from=333.337.search-card.all.click&vd_source=4e5eec7bb844b69adc695d11b9ce1bb2

 ➽摄像头:

摄像头处理的数据叫做图像数据,也就是一帧的图像。可以通过lwip中的TCP或者UDP连接到上位机,有分为全帧传送和拆分传送。要先建立连接,才能把图像数据发送到上位机或者云端,通过netconn_accept。

随后再通过netconn_write 来把图像数据写到上位机。然后下面的代码是我们连接到上位机了之后,发出一个关闭请求,然后执行全部代码知道退出这个最里面的循环。

我们的开发板作为服务器上位机,也就是客户端的时候,当客户端也就是网络连接助手,连接服务器的时候,要进入while的时候,需要提前等待客户端连接才能执行里面的代码。

服务器把摄像头处理的数据使用网卡发送至服务器中,并且在服务器实时更新图像。

其中,主要运用了SCCB总线协议:

与IIC协议十分相似,SCCB协议由两条信号线组成-SIO_C(类似IIC的SCL)和SIO_D(类似IIC的SDA)

然后不同的是,应答名字不一样,IIC协议在传输完1字节也就是8位的数据后,还需要有1位的接收方反向发过来的确认位。而SCCB协议一次性要直接由发送方发过来9位,前八位也是数据位,第九位名为 X,表示Do not care,而IIC的应答位叫做ACK。

然后也有区别是SCCB只能单次读,而IIC除了单次读还可以连续读。

最后读操作中,.SCCB读操作中间有stop,而IIC读操作中间可以有stop也可以不需要stop,具体表现如下:

16be81653def43ecaaa27bb6836c817d.png

232是连接着串口的,所以需要开发板上面的是连着232而不是Slave

OV7670和OV2640的区别:

ov2640能输出JPEG,前者不能,应用的话我也没用过。又因为例程里面是需要转换成JPEG格式,所以7670跑不了

二、CAN  & USB:

CAN:✿芯片型号是TJA1050-是一个CAN总线收发器,能把从单片机内部发来的数据(由内部CAN总线控制器-这是与RS485的区别了,与USART无关)转换成H和L两条线上的电平,PA11和PA12对应的是硬件CAN,

本协议位速率高达1M/s,它可以接收和发送11位标识符的标准帧,也可以接收和发送29位标识符的扩展帧,使用的是双绞线,两端要连着两个120欧的电阻。如果L线和H线接反了,总线就会无法通信。

自拟:

✿与IIC,SPI不同的是,CAN没有时钟线,故是异步通讯。它只有CAN_High和CAN_Low两条信号线,使用差分形式进行通讯(这样两条线的逻辑电平相减的时候,就影响不大,因为变的话是两条线一起变),

虽然有两根线,但是传输的信号只能一种方向,不像SPI有MISO和MOSI这样可以发接同时,所以CAN是异步半双工,它也没有主从设备的概念而已,只能节点满足条件,就能发数据。

✿发送函数:当 CAN 节点需要发送数据时,控制器把要发送的二进制编码通过 CAN_Tx 线发送到收发器,然后由收发器把这个普通的逻辑电平信号转化成差分信号,通过差分线 CAN_High 和 CAN_Low 线输出到 CAN 总线网络
✿接收函数:则是相反的过程,收发器把总线上收到的 CAN_High 及 CAN_Low 的差分信号转化成普通的逻辑电平信号,通过 CAN_Rx 输出到控制器中,这样单片机就能解析出来了。
✿STM32上,CAN要构成通信,除了要有两个接收端子,还要有收发芯片TJA1050。和485相比主要优点是:CAN有ID识别,知道是谁发,然后数据包不用加帧头。485则要帧头帧尾。

如图示意:a9b42fe5fc2c4188bdafa12d0c256330.png

☀代码:为了保证通信的成功,所有节点的波特率都要保持一致。

加强理解---CAN:

☀区别:与IIC,SPI具有时钟信号的同步通讯方式不同的是CAN是异步通讯,只有CAN_High和CAN_Low共同构成一组差分信号。(由于差分信号线具有很多优点,所以在USB协议、485协议、以太网协议及CAN协议的物理层中,都使用了差分信号传输。 )

☀逻辑定义:当CAN收发器从CAN_Tx线接收到来自CAN控制器的低电平信号时(逻辑0), 它会使CAN_High输出3.5V,同时CAN_Low输出1.5V,从而输出显性电平表示逻辑0,如下图:

268e06530cb4405382c8bb25246d44c0.png

 ☀CAN的波特率

☀标准数据帧的结构:分为帧起始–仲裁段(总线会根据仲裁段的内容决定哪个数据包能被传输,ID决定着数据帧发送的优先级。

若节点1和2竞争,当他们发送报文的时候,若首先出现隐性电平就会失去总线的占有权转为接收;若为显,则继续发送)–控制段(用于表示本报文中的数据段含有多少个字节 )–CRC段–ACK段( 发送节点发送的是隐性位,而接收节点则在这一位中发送显性位以示应答 )–帧结束

☀过滤方法有以下两种模式:①标识符列表模式(只有和自己所列表符合的才能接受到) ②掩码模式:掩码,可以把它理解成关键字搜索,只要掩码(关键字)相同,就符合要求,报文就会被保存到接收FIFO。

(前一个寄存器写ID,后一个寄存器写筛选的数字是前一个中的哪几位,两个寄存器为一组掩码)

☀补充:因为CAN总线上的数据是以广播的形式,所以所有连接到CAN上面的节点都会接收到其他节点发出的数据,因而CAN控制器大多具有根据ID过滤报文的作用,它可以控制自己只接受哪些ID的报文。1408df831817454e96292a6ddbcc46d1.png

 CAN发送/接收结构体:uint32_t StdId; /*存储报文的标准标识符11位,0-0x7FF. */uint32_t ExtId;/存储报文的扩展标识符29位,0-0x1FFFFFFF./

如果只有一个实验板, 也可以使用CAN的回环模式进行测试,不影响学习的。为此,我们提供了“CAN—双机通讯”及“CAN—回环测试”两个工程。

➽USB协议:

读卡器与虚拟串口实验:读卡器是相当于读SD卡的内存,有多少M.

有主机和从机的相应接口的:16be00dacaf0486eb3689aead569ff70.png

 USB协议:应用-USB的读卡器、声卡、虚拟串口是把 stm32作为从机slave,而USB的U盘、鼠标键盘则是把32作为主机host。

介绍-USB是一种主从系统,数据交换只能由主机主动发起。一共由四根线组成: VBUS(电源线)、差分线正、差分线负、电源负。然后全速/高速设备接在D+,低速则在D–,

所以信号线相当于只有一根,所以是半双工。(OTG则是指主从可以随意切换,DFU则是设备固件设计类、CDC是虚拟串口类)协议间内存冲突:USB和CAN共享一个512字节的SRAM,所以不能共同用。

代码移植步骤(这是对于HOST或者SLAVE而言):①查看ST官方的MSC例程

②拷贝工程所需文件(别忘了还有spi工程在NORFLASH上面)

③MDK改成设置fb842367951f4037a0812928e951ecb2.png

④修改usbd_storage.c992a761340cc4a28b17131f0b4ccc356.png

(代码分析:文件系统在外部FLASH的起始地址,因为我们定义SPI FLASH前12M给文件系统用,所以地址从0开始 ; USB状态–用bit0-bit4表示–◆电脑正向SD卡写入/读出数据/ ◆SD卡读/写数据错误标志位 )

⑤修改usbd_conf.h:

f96d01584d2d4b2f9978b565a4f399d8.png

⑥修改usbd_msc.h:
为了支持大于4G的内存卡,要把uint32_t  scsi_blk_addr改成uint64_t scsi_blk_addr;  并且要将
uint32_t scsi_blk_nbr改成uint32_t scsi_blk_nbr[STORAGE_LUN_NBR],这样才能既支持SD卡又支持SPI _ flash这两个磁盘,所以才要把变量改成数组以支持多个磁盘。这样就有电脑上面显示两个U盘了。

➽IAP:

IAP(In-Application Programming在应用编程)

概念:指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。在应用编程(IAP)是用户的应用代码对片内Flash存储器进行擦除/编程的方法。

设备固件升级(DFU):

也是IAP中的一种,不过这个是ST公司推出来的固件升级方案:

- 概述:利用STM32内置的Bootloader来实现USB DFU(Device Firmware Upgrade)固件升级功能,如何配置STM32芯片以支持USB DFU,并提供相应的代码示例和步骤说明。

USB DFU是一种通过USB接口进行设备固件升级的通用解决方案。它允许开发者通过USB连接来升级设备的固件,而无需使用外部编程器或者其他特殊的硬件设备。

- 工作原理:USB DFU通过在设备内部Flash中提供一个Bootloader程序来实现固件升级。当设备进入DFU模式时,它将暂停运行当前固件,然后通过USB接口与主机进行通信。

主机通过USB传输固件数据给设备,Bootloader程序接收并将固件数据写入设备的Flash存储器中。完成固件数据的传输和写入后,设备重启,并加载新的固件运行。

通常被开发者用来当作远程升级的手段。烧录到flash里面,然后重启之后会重新烧录进拷贝进来的程序。

启动过程:①初始化MSP,从0x8000 0000 ②初始化PC,从0x8000 0004 ④初始化中断向量表 ⑤调用初始化函数SystemInit()。⑥调用_main的标准C库函数。(PC是程序计数器,用来存放和指示下一条要执行的指令的地址; MSP是memory system protection)

- 加入IAP后的烧录启动过程区别:每一次的上电都会有执行复位中断服务函数的过程,正常是接着执行main里面程序,

可是加了IAP之后,就会执行IAP里面的main函数,然后再执行IAP过程,随后就会跳转到APP的中断向量表,也就是自己的hex文件里面的中断向量表,随后再跳转到自己hex文件里面的main函数;

- 然后正常发生中断的时候,会直接跳到中断向量表根据中断源跳转到相应的终端服务函数,可是加了这个IAP之后发生中断时,

会强制跳转到地址为0x8000 0000的中断向量表,随后根据设置的中断向量偏移表,跳转到APP对应的中断服务函数。(IAP过程就是把bin从外面读进来)

- APP生成步骤:

首先要看这个IAP原本的bootloader应用程序要大概多少大小,在IAP.map下面就要24k左右,

而在正点例程里面已经设置成了红框框里面的0x8010 0000,大概就是10000约等于64kb给DFU程序留了64kb后面的才是自己的发送的APP的hex文件的大小,所以APP一定要在bootloader后面,偏移量是0x200的倍数。

总的来说,FLASH是从0x8000 0000开始,SRAM是从0x2000 0000,而对于空间分配,一共要有三部分需要考究清楚-第一部分是Bootloader程序运行预留4kb,然后存放APP程序预留48kb,APP程序运行预留12KB,下面这个图自己标记过了:

1b34f70c16dc4a368bd398a59d0825f2.png

 - 移植过程:

①设置APP程序的起始地址和存储空间大小'

 ②设置中断向量表偏移量(也就是比如APP存放在flash的话,也就是SCB->VTOR=FLASH_BASE|0x10000;而SRAM就是SCB->VTOR=SRAM_BASE|0x1000;)  

 ③设置MDK编译后运行fromelf.ex,从而能生成bin

使用RTE试试:这个应该不属于USB协议里面,所以在RTE里面选择不了,有IAP的文件应该就可以更新了,和stmflash.c的文件:

ac2136b1c62f41dfb83c20be7aa9bd14.png

a9a9bb9d6e2c49f7be5346e69f6f0f22.png

 关键代码(正点):

c8f6de572f4a44fc89c7985823544c0f.png

294d02a4121f43d094cbc4b096584774.png69b40c762a8243eab2ee84285d6aa1a3.png

ead992a72f8448398b80e1c50cb0e0ba.png

 - 学习过程:.bin文件就是有.axf文件生成的;主函数代码分析(对于IAP里面)

※更新FLASH代码:主要用到flash写入数据的函数---STMFLASH_Write(),为什么判断i==512的时候要把i重新赋值为0

※from yang:参考链接-https://blog.csdn.net/ZZZganfan/article/details/134367775?spm=1001.2014.3001.5501

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值