(基于ARM的)微机扩展篇(1):STM32H743系统实现
0:Introduction
在你航仪器科学与光电工程学院的《微机原理与接口技术》课程中我们接触了R710F芯片开发板,它的核心是ARM7TDMI,主频最高48MHz.
在这里说个题外话,这个课的考试里面不会考你怎么用C语言或者汇编语言给ARM开发板编程,怎么打开板子的时钟和外设,也不会考你动手接线用硬件实现什么功能,至于那个实验开发板,一言难尽,它上面甚至没有SYSTICK定时器.考试有不少是概念和默写,你甚至不需要编程实现把硬件SPI的数据通过DMA搬到内存里面,你需要背下来DMA的概念,咣咣咣都写出来就能得高分,但是鄙人的记忆能力过于有限,所以考试成绩并不是很高.我的老师曾经教过我,能用硬件就不要软件,比如说能用硬件IIC和硬件SPI就不要用软件模拟IIC和SPI;能用硬件定时器做PWM就不要用软延时做PWM因为根本跑不准.能用中断或者DMA的情况下要考虑用下,在对性能要求不高的地方才考虑用轮询.至于STM32F103硬件IIC的缺陷(暂时先不讨论)
还是在你航仪光的《仪光科技》课程中我们简单了解了STM32芯片,用的STM32F103ZET6开发板,还有STM32F103C8T6最小系统板它们的核心是Cortex-M3,主频可以达到72MHz.(在下个学期会用STM32F103ZET6搭智能小车,可能会更新之前的坑)
稍微新一些的是树莓派PICO.它的RP2040芯片,双核Cortex-M0+,主频最高可达到133MHz.
OK,我们跳过STM32的F2系列,F3系列,F4系列,G4系列,F7系列,直接快进到STM32的最高级芯片,H7系列高性能处理器.STM32H743是一种Cortex-M7内核的单片机,主频可以达到400MHz,自带浮点数单元和DSP指令,可以用硬件处理float型和double型浮点数(注意STM32F4的硬件浮点数单元只是对float型的,如果是double型还是软件;STM32F1和树莓派PICO只有没有硬件浮点数单元,对float和double操作全部是软件),性能比STM32F103啥的要好的多.使用STM32H743这个板子可以做更多高级的事情,比如下面这个视频,播放破2000是我真的没想到的.

1:Environment configuration
环境选择Visual Studio 2022,需要安装最新版VisualGDB,需要和(po)谐(jie),相关工具可以私信我.在VisualGDB中安装软件依赖包(包管理器,点上STM32软件包,最好装到D盘),在这里为了方便以后的DSP相关实验我把DSP库给带上了,毕竟双精度FPU是真的香,拖进去DSP库以后大概长这个样子.Header Files和Source Files里面有VisualGDB帮你配置好的HAL库和启动文件(在VisualGDB里面启动文件是用C语言写的,配合arm-none-eabi-gcc编译器).Shared里面是我自己写的一些驱动(硬件IIC,硬件SPI,OLED屏幕,SDIO,串口).在这个视频中我们用到了FATFS读写SD卡,所以还需要FATFS.

2:FATFS and its transplantation

FATFS是一组管理文件的API(个人理解) ,使用它后,在应用层就不用顾虑"硬盘"的硬件细节,进行文件操作,这里所谓的"硬盘"可以是SD卡,FLASH芯片甚至是U盘.它的文件包括以下的内容

ff.h和ff.c两个文件是FATFS的核心,这块不用动.
ffunicode.c是unicode支持文件,需要带着.
ffsystem.c是fatfs使用的内存管理和RTOS支持,我没有用到,扔了.
diskio.h是FATFS操作硬件的接口函数原型声明和相关类型的定义,带上,基本上不要动.

参考正点原子的例程(寄存器方式轮询,又长又容易出错,如果理解不了就直接粘进去,也能用)
还有下面的CSDN专栏
大佬包装了中断版的SDIO和DMA版的SDIO读写函数,直接粘到disk_read和disk_write里面,读写0号硬盘(SD卡,pdrv等于0)
再魔改下,砍掉动态内存分配(正点原子他们都是用的自己的内存管理程序malloc.c实现了mymalloc函数),通过分析FATFS里面的一个配置,在处理长文件名的时候可能需要用到堆区和动态内存分配(而且只在这里用了),我们改这个参数把LFN功能给挪到BSS区(全局变量和静态变量区)或者栈区(单片机的栈一般不会开的很大.注意修改启动文件,小心栈溢出)

3:Hardware driver
OLED驱动就用正点原子的例程改的,把他的软件模拟SPI改成硬件SPI,可以直接用.
思路:写一个初始化函数打开SPI,HAL会调用一个callback函数初始化SPI管脚,我们用硬件SPI1,就查手册写callback函数,把相关管脚配置为SPI复用模式.写函数oled_writebyte实现硬件SPI读写一个字节(正点原子等各种例程用的软件模拟SPI,我们直接用硬件SPI做,先拉低CS引脚,然后根据要写的是DATA还是CMD修改DC引脚,最后用HAL硬件SPI把一个字节发过去,个人感觉用轮询够用了,实在不行就去研究实现SPI的中断收发或者DMA收发).
在函数外面开个全局的FATFS变量.上电初始化时钟和delay功能,先初始化硬件,把0号盘挂到开好的FATFS变量上(调用f_mount函数)主函数里面读一个SD卡二进制文件(做好的OLED视频文件)然后用while循环,每次读1KB(注意缓冲区数组开成全局的)如果出错了或者文件读完了就退出循环,否则把这1KB数据调用OLED驱动函数显示出来即可.
SDIO目前实现了中断读写SD卡(DMA版本在VisualGDB里面编译的程序似乎有些小bug)感谢CSDN的NoDistanceY大佬助我逃离例程的屎山:)