站内搜索
发作品签到
专业版

#训练营#STM32天空星拓展板

工程标签

783
0
0
0

简介

基于天空星高配版,f407系列真的挺强的,使用eda专业版自主设计原理图和pcb,板子两个电位器的io配置有问题。已经附上源码,都是模块化好的。

简介:基于天空星高配版,f407系列真的挺强的,使用eda专业版自主设计原理图和pcb,板子两个电位器的io配置有问题。已经附上源码,都是模块化好的。
立创·天空星扩展板征集令

开源协议

GPL 3.0

创建时间:2024-08-07 11:40:19更新时间:2024-09-09 14:43:16

描述

Keil5配置

2024年9月9日

11:02

 

lcd驱动(需要外部导入相关库文件)

 

 

将这三个文件放入所建工程的组文件中(模块化的调用相当是)

 

 

LCD_Init(); //初始化lcd

LCD_Clear(Black);// 清屏并显示初始背景色

LCD_SetBackColor(Black); //背景颜色

LCD_SetTextColor(White); //字体颜色

 

 

char miao[10];

int hh = 0;

sprintf(miao," %d",hh); // 转换函数 需要包含stdio.h 头文件

//将需要的内容打印到字符串中

//我理解为将后边hh整形数据存入 miao[]数组中,再用下边函数指针取首地址向后输入 LCD_DisplayStringLine(Line1, (u8 *)miao);

//lcd屏幕字符输出函数,行+内容

CubeMx配置

2024年9月9日

10:56

 

创建新工程:

1,芯片选型(正确的芯片型号,正确的封装

2,Debug选择

3,时钟配置,先根据需要开启时钟,再对时钟树进行配置

 

时钟树配置时要根据板子实际外部晶振进行调整

4,GPIO配置

 

 

小提示

2024年9月9日

11:01

keil5使用的时候ctrl + alt +空格显示提示词需要有键盘模式

 

 

重定义变量类型

2024年9月9日

10:50

typedef signed char int8_t; //给有符号char,取别名为int8_t

typedef signed short int int16_t; //给有符号短整型short int,取别名int16_t

typedef signed int int32_t; //给有符号整型short int,取别名int32_t

typedef signed __INT64 int64_t; typedef unsigned char uint8_t; //给无符号char,取别名为uint8_t

typedef unsigned short int uint16_t;//给无符号短整型short int,取别名为uint16_t

typedef unsigned int uint32_t; //给无符号整型short int,取别名为uint32_t

typedef unsigned __INT64 uint64_t;

/* 7.18.1.2 */ //和上面一样,取其他别名

/* smallest type of at least n bits */

/* minimum-width signed integer types */

typedef signed char int_least8_t;

typedef signed short int int_least16_t;

typedef signed int int_least32_t;

typedef signed __INT64 int_least64_t;

 

/* minimum-width unsigned integer types */

typedef unsigned char uint_least8_t;

typedef unsigned short int uint_least16_t;

typedef unsigned int uint_least32_t;

typedef unsigned __INT64 uint_least64_t;

/* fastest minimum-width signed integer types */

typedef signed int int_fast8_t;

typedef signed int int_fast16_t;

typedef signed int int_fast32_t;

typedef signed __INT64 int_fast64_t;

/* fastest minimum-width unsigned integer types */

typedef unsigned int uint_fast8_t;

typedef unsigned int uint_fast16_t;

typedef unsigned int uint_fast32_t;

typedef unsigned __INT64 uint_fast64_t;

定时器中断

2024年9月9日

11:03

 

 

 

HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim); //开启时钟中断,必要函数,但是注意放在定时器初始化函数之后

 

配置中断可通过两种方式

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

if (htim->Instance == TIM1) // 确保是 TIM1 定时器触发了回调

{

// 在这里添加你的代码,例如更新变量、触发中断等

}

}

void TIM3_IRQHandler(void)

{

HAL_TIM_IRQHandler(&htim3)

//中断处理函数

}

 

 

 

定时器的定时计算:

开启定时器中断后,定时器每完成一次计时会进入一次中断服务函数。

中断:

抢占优先级,响应优先级;

多个中断请求时,根据抢占、响应的顺序先后进行。(低优先的中断可被高优先中断打断)

抢占、响应优先级都相同时,系统根据自然排序处理。

(所以中断一定有前后顺序)

 

 

 

对定时器的理解:

定时器是独立的计数器,不受中断影响,即使进入中断,定时器也会不断计数。

所以用定时器来取代delay 延时,每当计数完成一次 才会进入一次中断处理函数,此时程序进入中断服务函数,但这个时间极其短暂(我认为可以忽略),相比delay程序停下来能获得更好的延时方案。

外部中断(以按键中断为例)

2024年9月9日

11:09

 

void EXTI1_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);

// 外部中断处理函数 }

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

//在hal_gpio.c中,是外部中断的回调函数,需放在主函数下

}

 

 

 

 

 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

if(GPIO_Pin == GPIO_PIN_12)

{

 

}

}//多按键中断回调处理函数

SPI通信

2024年9月9日

10:54

 

 

 

 

SPI 是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola(摩托罗拉)首先在其MC68HCXX系列处理器上定义的。

 

SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

SPI主从模式

SPI分为主、从两种模式,一个SPI通讯系统需要包含一个(且只能是一个)主设备,一个或多个从设备。提供时钟的为主设备(Master),接收时钟的设备为从设备(Slave),SPI接口的读写操作,都是由主设备发起。当存在多个从设备时,通过各自的片选信号进行管理。

 

SPI是全双工且SPI没有定义速度限制,一般的实现通常能达到甚至超过10 Mbps

 

SPI信号线

SPI接口一般使用四条信号线通信:

SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)

 

MISO: 主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据。 MOSI: 主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据。 SCLK:串行时钟信号,由主设备产生。 CS/SS:从设备片选信号,由主设备控制。它的功能是用来作为“片选引脚”,也就是选择指定的从设备,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。

SPI通信

2024年9月9日

10:54

 

 

 

 

SPI 是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola(摩托罗拉)首先在其MC68HCXX系列处理器上定义的。

 

SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

SPI主从模式

SPI分为主、从两种模式,一个SPI通讯系统需要包含一个(且只能是一个)主设备,一个或多个从设备。提供时钟的为主设备(Master),接收时钟的设备为从设备(Slave),SPI接口的读写操作,都是由主设备发起。当存在多个从设备时,通过各自的片选信号进行管理。

 

SPI是全双工且SPI没有定义速度限制,一般的实现通常能达到甚至超过10 Mbps

 

SPI信号线

SPI接口一般使用四条信号线通信:

SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)

 

MISO: 主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据。 MOSI: 主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据。 SCLK:串行时钟信号,由主设备产生。 CS/SS:从设备片选信号,由主设备控制。它的功能是用来作为“片选引脚”,也就是选择指定的从设备,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。

串口通信

2024年9月9日

11:15

 

 

 

 

 

I2C是半双工,SPI的全双工,uart是全双工

 

USART:通用同步和异步收发器

UART:通用异步收发器

当进行异步通信时,这两者是没有区别的。区别在于USART比UART多了同步通信功能。 这个同步通信功能可以把USART当做SPI来用,比如用USART来驱动SPI设备。

 

阻塞式发送:单片机等发送完毕,期间不做其他事

非阻塞式发送:使能发送中断,发送完毕回调函数

 

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t*pData, uint16_t Size,uint32_t Timeout);//阻塞式发送

HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart,uint8_t*pData,uint16_t Size);//非阻塞式发送

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);//回调函数

void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);//一半回调函数

 

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t*pDa ta, uint16_t Sizeuint32_t Tim neout);//阻塞式接收 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);//非阻塞式接收 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);

 

 

进行串口发送、接收时要清楚串口对应的引脚号。

ch340 RX接单片机TX

TX接单片机RX 一定要共地!!!!!!!

串口调试工具

 

标准库

void Uart1_init(u32 bound){

//GPIO端口设置

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟

//USART1_TX GPIOA.9

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

//USART1_RX GPIOA.10初始化

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10

//USART 初始化设置

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); //初始化串口1

//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断

USART_Cmd(USART1, ENABLE); //使能串口1

}

编码器驱动

2024年9月9日

11:21

 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //PB12,PB13编码器计数函数

{

if(GPIO_Pin == GPIO_PIN_12)

{

if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13) == HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12))

{

key_count--;

} else

{

key_count++;

}

}

}

搭配下边代码同时使用

if(key_count!=0)

{

key_num += key_count;

key_count = 0;

}

 

注意通过中断处理来确定旋转方向

 

 

void EXTI0_IRQHandler(void)//正转:A的上升沿对应B的低电平;反转:B的上升沿对应A的低电平。

{

if (EXTI_GetITStatus(EXTI_Line0) == SET)//判断编码器A是否为高电平,中断是否触发

{

if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) ==0)//判断编码器B是否为低电平

{

Encoder_Count++;

}

EXTI_ClearITPendingBit(EXTI_Line0);//如果是,则清空标志位

}

}

void EXTI1_IRQHandler(void)

{

if (EXTI_GetITStatus(EXTI_Line1) == SET)//判断编码器B是否为高电平,中断是否触发

{

if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) ==0)//判断编码器A是否为低电平

{

Encoder_Count--;

}

EXTI_ClearITPendingBit(EXTI_Line1);//如果是,则清空标志位

}

}

 

分别定义两个中断函数EXTI0_IRQHandler和EXTI1_IRQHandler。基本逻辑跟第一小节讲的一样,先判断第一个中断是不是被触发了,即A管脚是否是上升沿。A管脚接的是GPIOB_0,对应的中断0.然后判断B管脚是不是低电平。

EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line=EXTI_Line0 | EXTI_Line1;//配置中断线 EXTI_InitStructure.EXTI_LineCmd=ENABLE;//开启或关闭中断 EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//定义中断模式 EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;//触发中断方式,选择上升沿触发 EXTI_Init(&EXTI_InitStructure);

 

两个中断前后优先级区分清楚,先判断一个再判断另一个

oled驱动注意点

2024年9月9日

11:26

 

首先拉入相关的字库.h文件

oled的.c .h文件 在编译器中包含路径

主函数中包含头文件,

配置硬件iic,只需要把两个通信接口使能即可。

注意时钟频率,主频太高可能影响显示效果。

(硬件IIC是通过IIC控制器硬件模块来实现IIC通信的,而软件IIC是通过软件控制GPIO口来模拟IIC通信)

OLED_Init();//oled初始化文件

 

 

 

char text[20];

 

sprintf(text,字符(%d),变量);

 

OLED_ShowString(2,1,text);

 

清屏问题,设置屏幕背景色等

PWM配置

2024年9月9日

11:27

只需在CubeMx中配置响应的定时器pwm输出通道即可

 

 

HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);

TIM2->CCR1 = (常数/定时器计数值或定时器溢出值)//控制 tim2 1通道输出pwm占空比

 

PWM有效驱动两条代码

 

PWM频率:Freq = CK_PSC/(PSC+1)/(ARR+1)

PWM占空比:Duty = CCR/(ARR+1)

PWM分辨率:Reso = 1/(ARR+1)

 

TIM定时器PWM1模式与PWM2模式的比较

STM32 定时器的 PWM 存在两种模式,即 PWM1 模式与 PWM2 模式,两种模式相似却又恰恰相反。

PWM1 模式:向上计数,当 TIMx_CNT < TIMx_CCRn 时,定时器 TIMx 的通道 n 为有效电平,否则为无效电平;向下计数,当 TIMx_CNT > TIMx_CCRn 时,定时器 TIMx 的通道 n 为无效电平,否则为有效电平 有效电平,否则为无效电平。

 

PWM2 模式:向上计数,当 TIMx_CNT < TIMx_CCRn 时,定时器 TIMx 的通道 n 为无效电平,否则为有效电平;向下计数,当 TIMx_CNT > TIMx_CCRn 时,定时器 TIMx 的通道 n 为有效电平,否则为无效电平 无效电平,否则为有效电平。

 

下面是 PWM1 模式与 PWM2 模式的比较表格图,能够比较直观的反映出两者的区别。

两种PWM模式的比较 注:

全文中的 TIMx 表示 STM32 的定时器,x 表示某个定时器,取值需要根据芯片来定;

全文中的 TIMx_CNT,表示定时器 TIMx 的计数器寄存器值;

全文中的 TIMx_CCRn,表示捕获比较寄存器的值,其中 n 表示某个通道,取值为1、2、3、4;

 

ADC采样

2024年9月9日

11:29

 

 

 

只需在CubeMx中开始相关引脚adc采样通道

 

 

 

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

3D模型

序号文件名称下载次数
暂无数据

附件

序号文件名称下载次数
1
天空星拓展板.mp4
0
2
天空星拓展板.mp4
1
3
STM32F407_ProjectTemplate.zip
7
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

知识产权声明&复刻说明

本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。

请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。

评论

全部评论(1
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航