Cubemx 基础配置
开启STlink下载
使用外部晶振
- System Core -> RCC
GPIO
- 以PF9,PF10 引脚为例
Cubemx 配置
GPIO输出配置
配置引脚为输出
其他配置
- output level 起始电平
- High 高电平
- Low 低电平
- mode 工作模式
- Push Pull 推挽
- Open Drain 开漏
- Pull-up/Pull-down 上下拉
- Pull-up 上拉
- Pull-down 下拉
- outPut Speed 速度
- Low 低10MHz
- Medium 中25MHz
- High 高 50MHz
- very High 超高100MHz
使用
- 引脚输出电平
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_RESET);
/*
参数1:引脚组:
GPIOA~GPIOF
参数2:引脚:
GPIO_Pin_x
参数3:输出状态
GPIO_PIN_RESET 低电平
GPIO_PIN_SET 高电平
- 引脚反转
HAL_GPIO_TogglePin(GPIOF,GPIO_Pin);
/*
参数1:引脚组
GPIOA~GPIOF
参数2:引脚
GPIO_PINx
*/
GPIO输入配置
配置引脚为输入
其他配置
- Pull-up/Pull-down 上下拉
- Pull-up 上拉
- Pull-down 下拉
使用
- 引脚输出电平
HAL_GPIO_ReadPin(GPIOF,GPIO_Pin_9);
/*
参数1:引脚组:
GPIOA~GPIOF
参数2:引脚:
GPIO_Pin_x
返回值类型:int
*/
EXTI 外部中断
Cubmx配置
配置引脚为中断
GPIO配置
- mode 模式
- Externmal interrupt 中断
- Rising 上升沿
- Falling 下降沿
- Externmal Event 事件
- Rising 上升沿
- Falling 下降沿
- Externmal interrupt 中断
中断NVIC配置
使用
中断服务函数位于
- stm32f4xx_it.c
- void EXTI2_IRQHandler(void)
//判断中断发送
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
//清除中断标志位
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
Timer 定时器
Cubmx配置
Timer 配置
NVIC 中断配置
使用
中断函数位置
- stm32f4xx_it.c
- void TIM3_IRQHandler(void)
开定时器中断函数
HAL_TIM_Base_Start_IT(&htim2);
//参数:定时器句柄地址
关定时器中断函数
HAL_TIM_Base_Stop_IT(&htim2);
//参数:定时器句柄地址
UART 串口
Cubmx配置
-
Mode 工作模式
- Asynchronous 异步通信
- synchronous 同步通信
- single 半双工
-
Baud Rate 波特率
-
Word Length 数据长度
- 8
- 9
-
Parity 校验位
- Even 奇检验
- Odd 偶校验
-
Stop Bits 停止位
- 1
- 2
-
Data Direction 数据方向
- Receive and TranSmit 发送和接收
- Receive Only 仅发送
- TranSmit Only 仅接收
使用
- 轮询发送数据与接收数据
//发送数据
HAL_UART_Transmit(&huart1,(uint8_t*)"hello hal",9,1000);
/*
参数1:串口地址
参数2:数据指针
参数3:数据长度
参数4:超时时间
*/
//等待发送结束
while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);
//接收数据
HAL_UART_Receive(&huart1,(uint8_t *)RX_BUF,16,1000);
/*
参数1:串口地址
参数2:存储空间地址
参数3:数据长度
参数4:超时时间
*/
- printf
//版本一:
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (uint8_t) ch;
return ch;
}
//版本二:
int fputc(int ch,FILE *f)
{
while(!((USART1->ISR)&(1<<7)));
USART1->TDR = ch;
return ch;
}
- 其他
HAL_UART_Transmit_IT();串口中断模式发送
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收
2、串口中断函数
HAL_UART_TxHalfCpltCallback();一半数据发送完成时调用
HAL_UART_TxCpltCallback();数据完全发送完成后调用
HAL_UART_RxHalfCpltCallback();一般数据接收完成时调用
HAL_UART_RxCpltCallback();数据完全接受完成后调用
HAL_UART_ErrorCallback();传输出现错误时调用
PWM
Cubmx配置
- 配置引脚为定时器
- Prescaler 重载值
- counter Mode 计数模式
- up 向上
- down 向下
- Counter Period 预分频
- Intermal Clock Division 时钟分频
- auto-reload preload 自动重载值加载
- Mode 工作模式
- PWM 1
- PWM 2
- Pulse 初始值
- Output compart 输出比较
- Fast Mode 快速模式
- CH Polarity 输出极性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9xPy4ZYU-1601965233092)(C:\Users\49\AppData\Roaming\Typora\typora-user-images\image-20201005095544240.png)]
使用
- 开启PWM
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_2);
/*
参数1:定时器地址
参数2:通道
*/
- 修改占空比
//寄存器修改占空比
TIMx->CCRx = 100;
//函数
__HAL_TIM_SetCompare(&htim5, TIM_CHANNEL_2, 100);
/*
参数1:定时器地址
参数2:通道
参数3:占空比
*/
DAC 模拟输出
Cubemx配置
使用
//DAC的输出电压=Value*3.3/4096;
HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1 ,DAC_ALIGN_12B_R ,Value);
//开启DAC
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
//关闭DAC
HAL_DAC_Stop(&hdac, DAC_CHANNEL_1);
ADC 模拟输入
Cubemx 配置
HAL_ADC_Start(&hadc1); //启动ADC转换
HAL_ADC_PollForConversion(&hadc1, 50); //等待转换完成,50为最大等待时间,单位为ms
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
{
ADC_Value = HAL_ADC_GetValue(&hadc1); //获取AD值
printf("ADC1 Reading : %d \r\n",ADC_Value);
printf("PA3 True Voltage value : %.4f \r\n",ADC_Value*3.3f/4096);
}
IIC协议
- 由于STM32IIC不稳定古采用软件模拟IIC
空闲状态
SDA与SCL均为高电平
- 宏定义
//IO方向设置
#define SDA_IN() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;} //PB9输入模式
#define SDA_OUT() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<9*2;} //PB9输出模式
//IO操作
#define IIC_SCL PBout(8) //SCL
#define IIC_SDA PBout(9) //SDA
#define READ_SDA PBin(9) //输入SDA
开始信号
在SCL为高电平时SDA产生下降沿
例
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
停止信号
在SCL为高电平时SDA产生上升沿
例
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
应答信号
在数据位的第九给周期内将SDA拉低
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
数据传输有效性
在SCL改变时SDA必须保持稳定
即 在SDA产生数据位后将SCL拉高,在SCL拉低后改变数据位,
数据传输
传输数据位时先将SDA拉至对应电平,在将SCL拉高延时后拉低
例
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
SPI
- 参考链接:
https://blog.csdn.net/as480133937/article/details/105849607
使用
- 发送数据
HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//发送数据
参数:
*hspi: 选择SPI1/2,比如&hspi1,&hspi2
*pData : 需要发送的数据,可以为数组
Size: 发送数据的字节数,1 就是发送一个字节数据
Timeout: 超时时间,就是执行发送函数最长的时间,超过该时间自动退出发送函数
- 接收数据
HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//接收数据
参数:
*hspi: 选择SPI1/2,比如&hspi1,&hspi2
*pData : 接收发送过来的数据的数组
Size: 接收数据的字节数,1 就是接收一个字节数据
Timeout: 超时时间,就是执行接收函数最长的时间,超过该时间自动退出接收函数