系列文章目录
留空
前言
自用
一、LED
void LED_Disp(uint8_t LEDx)
{
HAL_GPIO_WritePin(GPIOC,0xFF << 8,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,LEDx << 8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
控制LED
/*** 流水灯 ***/
for(int i=3;i >= 0;i--)
{
LED_Disp(0x01 << i);
HAL_Delay(50);
}
/*** 单独控制 ***/
uint8_t LEDx =0x00;
LEDx |= 0x01; LED_Disp(LEDx); //点亮LED1 不影响其他灯
LEDx &= ~(1 << 0); LED_Disp(LEDx); //熄灭LED1 不影响其他灯
/*** 0.1秒闪烁 ***/
__IO uint32_t LED_uwtick;
uint8_t LED1_Flag = 1;
void LED_Proc(void)
{
if(uwTick - LED_uwtick < 100) return;
LED_uwtick = uwTick;
switch(LED1_Flag)
{
case 1: LEDx |= 0x01; LED1_Flag = 2; break;
case 2: LEDx &= ~(1 << 0); LED1_Flag = 1; break;
default: break;
}
}
二、按键
#include "KEY.h"
uint8_t KEY_Down,KEY_Up,KEY_Val,KEY_Old;
__IO uint32_t Key_uwtick;
__IO uint32_t Key_uwtick1;
uint8_t KEY_Scan(void)
{
uint8_t Num = 0;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == 0) Num = 1;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0) Num = 2;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == 0) Num = 3;
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == 0) Num = 4;
return Num;
}
void KEY_Proc(void)
{
if(uwTick - Key_uwtick < 50) return;
Key_uwtick = uwTick;
KEY_Val = KEY_Scan();
KEY_Down = KEY_Val & (KEY_Val ^ KEY_Old);
KEY_Up = ~KEY_Val & (KEY_Val ^ KEY_Old);
KEY_Old = KEY_Val;
}
uint8_t KEY_State(void)
{
uint8_t Num = 0;
if(KEY_Down)
{
Key_uwtick1 = uwTick;
}
if(uwTick - Key_uwtick1 < 1000)
{
switch(KEY_Up)
{
case 1: Num = 1; break;
case 2: Num = 2; break;
case 3: Num = 3; break;
case 4: Num = 4; break;
}
}
else if(uwTick - Key_uwtick1 > 1000)
{
switch(KEY_Val)
{
case 1: Num = 5; break;
case 2: Num = 6; break;
case 3: Num = 7; break;
case 4: Num = 8; break;
}
}
return Num;
}
mian.c
中记得先扫描按键。才能执行按键相关的功能
while (1)
{
KEY_Proc();
... ...
}
三、LCD
LCD_Init();
HAL_Delay(100);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LCD_Clear(Black);
HAL_Delay(100);
//显示1
LCD_DisplayStringLine(Line4, (unsigned char *)" Hello,world. ");
HAL_Delay(1000);
//显示2
unsign char LCD_test[30];
uint8_t Num = 1;
sprintf((char *)LCD_Test,"Num:%d",Num);
LCD_DisplayStringLine(Line4, LCD_Test);
容易忘:LCD_Init();
四、串口
函数:
HAL_UART_Transmit(&huart1,(uint8_t *)Tx_Data,strlen(Tx_Data),50);
HAL_UART_Receive_IT(&huart1,(uint8_t *)&rx_data,1);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
完整代码:
char Rx_Data[30];
char Tx_Data[30];
unsigned char rx_data,rx_num;
int main(void)
{
... ...
HAL_UART_Receive_IT(&huart1,(uint8_t *)&rx_data,1);
while (1)
{
... ...
}
}
/***** 串口发送 *****/
void Usart_Tx(void)
{
// 发送1
char Num1 = 10,Num2 = 'A';
sprintf((char *)Tx_Data,"Num:%d-%c",Num1,Num2);
HAL_UART_Transmit(&huart1,(uint8_t *)Tx_Data,strlen(Tx_Data),50);
// 发送2
HAL_UART_Transmit(&huart1,(uint8_t *)"HELLO",5,50);
}
/***** 串口接收 *****/
void Usart_Rx(void)
{
// 接收1
// sprintf((char *)LCD_Test,"Rx_Data:%s",Rx_Data);
// LCD_DisplayStringLine(Line2,LCD_Test);
// 接收2
if(rx_num == 9)
{
char Rx1[4],Rx2[4];
int Rx3;
sscanf(Rx_Data,"%3s-%3s-%2d",Rx1,Rx2,&Rx3);
sprintf((char *)LCD_Test,"1:%3s;2:%3s;3:%2d",Rx1,Rx2,Rx3);
LCD_DisplayStringLine(Line2,LCD_Test);
rx_num = 0;
}
}
/***** 串口接收中断 *****/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
Rx_Data[rx_num ++] = rx_data;
HAL_UART_Receive_IT(&huart1,(uint8_t *)&rx_data,1);
}
}
猪猪:如果数据是3个字符,必须多一个给空字符,所以Rx1[4]
四个字符,否则出错!(3个字符 + 1个空字符)
unsigned char LCD_Test[30];
char Rx1[4],Rx2[4];
int Rx3;
sscanf(Rx_Data,"%3s-%3s-%2d",Rx1,Rx2,&Rx3); //拆分
sprintf((char *)LCD_Test,"1:%3s;2:%3s;3:%2d",Rx1,Rx2,Rx3); //合并
五、PWM
函数:
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
__HAL_TIM_SET_PRESCALER(&htim17,PSC);
__HAL_TIM_SET_AUTORELOAD(&htim17,ARR);
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,CCR);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
CCR1 = HAL_TIM_ReadCapturedValue(&htim16,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim16,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);
输出PWM
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
// 设置三个
void Set_PWM(uint16_t PSC,uint16_t ARR ,uint8_t CCR)
{
__HAL_TIM_SET_PRESCALER(&htim17,PSC);
__HAL_TIM_SET_AUTORELOAD(&htim17,ARR);
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,CCR);
}
// 设置 频率/占空比
void Set_Duty(uint8_t Duty)
{
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,Duty);
}
捕获PWM
HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);
void Get_Freq(void)
{
if(Capture_end == 0) return;
if(CCR3 > CCR1) Period_CCR = CCR3 - CCR1;
else if(CCR3 < CCR1) Period_CCR = (CCR1 + 0xFFFF) + 1 - CCR3;
PA7_Freq = 80000000 / 80 / Period_CCR;
Capture_end = 0;
}
void Get_Duty(void)
{
if(Capture_end == 0) return; // 注意!!
if(CCR2 > CCR1) Hign_CCR = CCR2 - CCR1;
else if(CCR2 < CCR1) Hign_CCR = (0xFFFF - CCR1) + 1 - CCR2;
if(CCR3 > CCR1) Period_CCR = CCR3 - CCR1;
else if(CCR3 < CCR1) Period_CCR = (0xFFFF - CCR1) + 1 - CCR3;
PA7_Freq = 80000000 / 80 / Period_CCR;
PA7_Duty = Hign_CCR * 100 / Period_CCR;
Capture_end = 0; // 注意!!
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if((htim == &htim16) && (Capture_end == 0)) // 注意!!
{
switch(Capture_Flag)
{
case 1:
CCR1 = HAL_TIM_ReadCapturedValue(&htim16,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim16,TIM_CHANNEL_1,
TIM_INPUTCHANNELPOLARITY_FALLING);
Capture_Flag = 2;
break;
case 2:
CCR2 = HAL_TIM_ReadCapturedValue(&htim16,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim16,TIM_CHANNEL_1,
TIM_INPUTCHANNELPOLARITY_RISING);
Capture_Flag = 3;
break;
case 3:
CCR3 = HAL_TIM_ReadCapturedValue(&htim16,TIM_CHANNEL_1);
Capture_Flag = 1;
Capture_end = 1; // 注意!!
break;
default:
break;
}
HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1); // 注意!!
}
}
六、ADC
函数
HAL_ADC_Start(&hadc1);
R38_Num = HAL_ADC_GetValue(&hadc1);
完整代码
void Get_ADC(void)
{
HAL_ADC_Start(&hadc1);
R38_Num = HAL_ADC_GetValue(&hadc1);
R38_Volt = (float)(R38_Num * 3.3) / 4095;
HAL_ADC_Start(&hadc2);
R37_Num = HAL_ADC_GetValue(&hadc2);
R37_Volt = (float)(R37_Num * 3.3) / 4095; // 注意!!先×3.3 再/4095
}
七、EEPROM
翻手册AT24C02对着手册写!!在第11页
!!
Device Address
、Byte Write
和Random Read
#include "EEPROM.h"
#define R_Add 0xA1
#define W_Add 0xA0
//把"i2c_hal.h"函数粘贴过来,对着直接复制粘贴!
//void I2CStart(void);
//void I2CStop(void);
//unsigned char I2CWaitAck(void);
//void I2CSendAck(void);
//void I2CSendNotAck(void);
//void I2CSendByte(unsigned char cSendByte);
//unsigned char I2CReceiveByte(void);
//void I2CInit(void);
void EEPROM_Write(uint8_t Add,uint8_t Data)
{
I2CStart();
I2CSendByte(W_Add);
I2CWaitAck(); // 是等待回应不是发送回应!!!
I2CSendByte(Add);
I2CWaitAck();
I2CSendByte(Data);
I2CWaitAck();
I2CStop();
HAL_Delay(5); // 必须加!!!
}
uint8_t EEPROM_Read(uint8_t Add)
{
uint8_t Data = 0x00;
I2CStart();
I2CSendByte(W_Add); // 先写地址!!
I2CWaitAck();
I2CSendByte(Add);
I2CWaitAck();
I2CStart();
I2CSendByte(R_Add); // 后读地址!!
I2CWaitAck();
Data = I2CReceiveByte();
I2CSendNotAck();
I2CStop();
return Data;
}
mian.c
中记得先初始化IIC!
uint8_t EEP_Add[5] = {0x01,0x02,0x03,0x04,0x05};
uint8_t EEP_Read[5] = {0};
int main(void)
{
... ...
I2CInit(); // 注意!!!
EEPROM_Write(0x01,11);
EEPROM_Write(0x02,22);
EEPROM_Write(0x03,33);
EEPROM_Write(0x04,44);
EEPROM_Write(0x05,55);
EEP_Read[0] = EEPROM_Read(0x01);
EEP_Read[1] = EEPROM_Read(0x02);
EEP_Read[2] = EEPROM_Read(0x03);
EEP_Read[3] = EEPROM_Read(0x04);
EEP_Read[4] = EEPROM_Read(0x05);
while (1)
{
... ...
}
}
八、RTC
函数
RTC_TimeTypeDef RTC_Time;
RTC_DateTypeDef RTC_Date;
HAL_RTC_GetTime(&hrtc,&RTC_Time,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc,&RTC_Date,RTC_FORMAT_BIN);
完整代码
void Get_RTC(void)
{
HAL_RTC_GetTime(&hrtc,&RTC_Time,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc,&RTC_Date,RTC_FORMAT_BIN);
sprintf((char *)LCD_Test,"RTC:%02d-%02d-%02d",RTC_Time.Hours,RTC_Time.Minutes,
RTC_Time.Seconds);
LCD_DisplayStringLine(Line2,LCD_Test);
sprintf((char *)LCD_Test,"RTC:%02d-%02d-%02d",RTC_Date.Year,RTC_Date.Month,
RTC_Date.Date);
LCD_DisplayStringLine(Line3,LCD_Test);
}
总结
总结以上函数:
LCD
unsign char LCD_test[30];
sprintf((char *)LCD_Test,"Num:%d",Num);
LCD_DisplayStringLine(Line4, LCD_Test);
串口
HAL_UART_Transmit(&huart1,(uint8_t *)Tx_Data,strlen(Tx_Data),50);
HAL_UART_Receive_IT(&huart1,(uint8_t *)&rx_data,1);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
PWM
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
__HAL_TIM_SET_PRESCALER(&htim17,PSC);
__HAL_TIM_SET_AUTORELOAD(&htim17,ARR);
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,CCR);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
CCR1 = HAL_TIM_ReadCapturedValue(&htim16,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim16,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);
ADC
HAL_ADC_Start(&hadc1);
R38_Num = HAL_ADC_GetValue(&hadc1);
RTC
RTC_TimeTypeDef RTC_Time;
RTC_DateTypeDef RTC_Date;
HAL_RTC_GetTime(&hrtc,&RTC_Time,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc,&RTC_Date,RTC_FORMAT_BIN);
注意
猪猪猪:
(1)检查CubeMX中的LCD引脚是否都是output
(2)容易忘记LCD的LCD_Init();
、EEPROM的I2CInit();
!
(3)按键都是intput
+pull up
(4)LEDx &= ~(1 << 0);
就是LED1,而不是(i << 1)
(5)确保LCD显示
在正确的位置
不需要
设置CubeMX的:EEPROM
设置CubeMX中断
的:串口接收、捕获PWM