Open source flash program for the STM32 ARM processors using the ST serial bootloader over UART or I2C
ebox是类似于arduino的一层api,简化stm32编程
http://www.myufun.com/ https://zhuanlan.zhihu.com/p/88540944 https://mbb.eet-china.com/forum/cat/48_1.html
STM32CubeMX介绍、下载与安装
http://www.wangchaochao.top/
编译的作用就是把程序转换成二进制文件,对于相同ARM内核的单片机,指令集都是一样的,二进制接口也是一样的,所以ARM单片机都可以arm-none-eabi-gcc套件编译,当然arm-none-eabi-gcc只适合编译裸机程序,裸机程序跟linux系统程序的二进制接口是不一样的。用make+gcc开发的感觉是非常舒服的,结合强大的终端命令行,开发效率直接加倍。调试没有 keil爽
Ubuntu系统下STM32开发环境怎么搭建?
编辑器vim,编译器arm-none-eabi-gcc,调试器arm-none-eabi-gdb,项目管理gnu make,仿真器 st-link
定时器主从模式,用一个定时器做PWM输出,频率可以通过预分频值调整,这个定时器就是主定时器。再选一个定时器做从定时器,用于计数。
注意两个定时器的名字,主和从,也就是说这两个定时器是连在一起的,怎么连呢,推荐参考《STM32参考手册》
讲解一下DMA,捎带讲解一下常用的串行通信
讲解一下文件系统,可以用SPI Flash或者SD卡或者U盘
讲解一下TCP/IP通信,移植一个web server
讲解一下DSP库应用,比如PID、卡尔曼滤波
讲解一下启动代码,如果有一个bootloader的进阶会更好
UI界面可以考虑一下,用web server做一个简易的B/S也很不错
RTOS也可以做一些科普性的介绍
新书一定要注重实际应用,因为硬件性能提高意味着它有更多的应用场景,而基础教程已经很完备了,并且芯片厂商为了芯片推广已经把DK做的很友好了。
keil5 开发环境:
链接: https://pan.baidu.com/s/1RH78saG74UkKPMBJh00l0g 提取码: j3us
使用keil5自带库创建STM32工程:
https://blog.csdn.net/lanhaixuanvv/article/details/78402053
下载器:j-link / st-link
链接:https://pan.baidu.com/s/1ckivxnwoxFkxSLHQ2a9PWA
提取码:syau
st-link-v2
链接:https://pan.baidu.com/s/1pIQac49ocU-sSooLSljz4Q
提取码:l534
串口:pl2303 / ch340
链接:https://pan.baidu.com/s/12MpnvmZaNtu7ETTt7sDu0g
提取码:4hjl
参考
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MrpujkJP-1692886048079)(…\img\miniSTM32.png)]
DS0
:红色,DS1
:绿色)。MCU
和 LCD
,3 个功能按钮,其中 WK_UP
兼具唤醒功能。 GPIOA
和 GPIOB
按顺序引。引脚分配说明:见引脚EXCEL说明
ALIENTEK MiniSTM32 V3.0 版开发板选择的是 STM32F103RCT6 作为 MCU,它拥有的资源包括:48KB SRAM、256KB FLASH、2 个基本定时器、4 个通用定时器、2 个高级定时器、2 个 DMA 控制器(共 12 个通道)、3 个 SPI、2 个 IIC、5 个串口、1 个 USB、1 个 CAN、3 个12 位 ADC、1 个 12 位 DAC、1 个 SDIO 接口及 51 个通用 IO 口。
启动模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SIpNEngm-1692886048080)(…\img\start mode.png)]
USER, CORE, STM32F10X, OBJ, SYSTEM,HAEDWARE及其子文件夹
。Project->New uVersion Project, 选择STM32F103RC
Manage Project Items
,创建相应的文件夹add files->.c
文件Options for Target->Output->Create HEX file, Select Folder for Objects->选择OBJ文件夹
Options->C/C++,添加.h文件,必须到最后一级文件夹
本章用到的硬件只有 LED(DS0 和 DS1)。其电路在 ALIENTEK MiniSTM32 开发板上默认是已经连接好了的。DS0 接 PA8,DS1 接 PD2。所以只需要操作PA8和PD2两个IO口即可。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-48HcWZ9G-1692886048081)(…\img\LED.png)]
怎样通过固件库设置 GPIO的相关参数和输出?
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
//通过初始化结构体初始化 GPIO 的常用格式
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度 50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数配置 GPIO
//在固件库中操作 IDR 寄存器读取 IO 端口数据是通过 GPIO_ReadInputDataBit 函数实现的:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //置为高电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //置为低电平
跑马灯代码
//LED initialize
#include "stm32f10x.h"
#include "led.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
RCC_APB2Periph_GPIOD, ENABLE); //使能 PA,PD 端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO 口速度为 50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 ,IO 口速度为 50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高
//LED 头文件
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PAout(8) // PA8 端口定义
#define LED1 PDout(2) // PD2
void LED_Init(void);//初始化
#endif
串口时钟使能,GPIO 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
串口复位
当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作。
void USART_DeInit(USART_TypeDef* USARTx);//eg. USART_DeInit(USART1)
GPIO 端口模式设置
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
第一个参数为指定初始化的串口编号,第二个为USART_InitTypeDef类型的结构体:
USART_InitStructure.USART_BaudRate = bound; //波特率;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为 8 位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl
= USART_HardwareFlowControl_None; //无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口
串口参数初始化
STM32 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是一个双寄存器,包含了 TDR 和 RDR。当向该寄存器写数据的时候,串口就会自动发送,当收到收据的时候,也是存在该寄存器内。
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);//发送数据
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);//接收数据
开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
//如判断寄存器是否非空:USART_GetFlagStatus(USART1,USART_FLAG_RXNE);
//判断发送是否完成TC:USART_GetFlagStatus(USART1,USART_FLAG_TC);
使能串口
USART_Cmd(USART1, ENABLE);
编写中断处理函数
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,
FunctionalState NewState)
//这个函数的第二个入口参数是标示使能串口的类型,也就是使能哪种中断,因为串口的中断类型有很多种。
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断,接收到数据中断
获取相应中断状态
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c2CMNee8-1692886048081)(…\img\IT.png)]
串口初始化代码和接收代码在SYSTEM文件夹下,打开
usart.c
文件即可看到各个函数代码。
#include "sys.h"
#include "usart.h" //含有void usart_init(u32 bound)函数
#include "delay.h" //含有void delay_ms(u32 ms)等函数
#include "led.h"
int main(void)
{
u8 t;
u8 len;
u16 times=0;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组
uart_init(9600); //串口初始化为 9600
LED_Init(); //初始化与 LED 连接的硬件接口
while(1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("\r\n 您发送的消息为:\r\n");
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X40)==0);//等待发送结束
}
printf("\r\n\r\n");//插入换行
USART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\nALIENTEK MiniSTM32 开发板 串口实验\r\n");
printf("正点原子@ALIENTEK\r\n\r\n\r\n");
}
if(times%200==0)printf("请输入数据,以回车键结束\r\n");
if(times%30==0)LED0=!LED0;//闪烁 LED,提示系统正在运行.
delay_ms(10);
}
}
}
外部 IO 口的中断功能,代码主要分布在固件库的
stm32f10x_exti.h
和stm32f10x_exti.c
文件中。
线 0~15:对应外部 IO 口的输入中断。线 16:连接到 PVD 输出。线 17:连接到 RTC 闹钟事件。线 18:连接到 USB 唤醒事件。
GPIO 的管脚GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)
分别对应中断线 15~0。
配置 GPIO 与中断线的映射关系的函数 GPIO_EXTILineConfig()来实现的:
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
中断线上中断的初始化是通过函数 EXTI_Init()实现的。EXTI_Init()函数的定义是:
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line4;//中断线的标号,取值范围为EXTI_Line0~EXTI_Line15
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式,可选值为中断 EXTI_Mode_Interrupt 和事件 EXTI_Mode_Event
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发方式,可以是下降沿触发 EXTI_Trigger_Falling,上升沿触发 EXTI_Trigger_Rising
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct 中指定的
//参数初始化外设 EXTI 寄存器