【蓝桥杯嵌入式】各模块代码总结

系列文章目录

留空



前言

自用


一、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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值