嵌入式蓝桥杯所有模块HAL库函数和代码总结

文章详细介绍了在蓝桥杯竞赛中可能用到的嵌入式编程函数模块,包括EEPROM读写、I2C通信、TIM定时器、UART串口通信、ADC和DAC模拟数字转换,强调了重要模块如TIM和HAL库函数的使用
摘要由CSDN通过智能技术生成

描述:本文整理了所有嵌入式蓝桥杯可能使用到的函数模块和代码

!!!!!!注意重点掌握每个函数,函数内容(代码)可自行编写,但是需要调用的HAL库函数是唯一的

II2模块-->>EEPROM读写

------->>注意该模块无HAL库函数调用

此模块通过编写II2时序对具有存储功能的外设进行读写操作,如对M24C02芯片(存储芯片)、MCP4017T芯片(数字电位器)进行操作。

其中M24C02又称为AT24C02---->>>>即eeprom,此模块在竞赛中多次出现,重点需掌握对IIC时序的理解。

MCP4017目前为止未在考题中出现。

---------------------根据官方给出的i2c_hal.c-----------------------

我们编写对eeprom的读写函数。


/**
  * @param--address:要将数据写入到eeprom中的地址
  * @param--info:写如到eeprom中的数据内容
  * @retval: None
  */
void x24c02_write(unsigned char address,unsigned char info)
{
    I2CStart();/*开启I2C*/
    I2CSendByte(0xa0);/*这里首先要对eeprom进行选择,因为IIC总线能够挂载多个外设,所以这里需要选 
    I2CWaitAck();                                                        择外设为eeprom*/
    /*下面开始真正对eeprom进行操作*/
    I2CSendByte(address);/*选择eeprom的地址*/
    I2CWaitAck();/*等待eeprom回应*/
    I2CSendByte(info);/*发送要写入到所选地址中的数据*/
    I2CWaitAck();/**/
    I2CStop();/*关闭I2C*/
}/*编写注意:只要记得在代码开始和完成时分别调用I2CStrat();和I2CStop();
            以及在每次发送数据位后调用I2CWaitAck();就可以快速写出代码*/


/**
  * @param--address:选择读取哪个存储单元内的数据
  * @retval--(uint8_t) val:因为是读操作,所以1必要要将读取到的内容返回,故需要调用return函数
  *                        注意此时函数从void类型---->>变为uint8_t(返回值的类型)          
  **/

uint8_t x24c02_read(uint8_t address)
{
    unsigned char val;
    I2CStart();
    I2CSendByte(0xa0);/*选择外设为eeprom*/
    I2CWaitAck();
    
    I2CSendByte(address);
    I2CWaitAck();
    I2CSendByte(0xa1);/*表示对eeprom进行读操作*/
    I2CWaitAck();
    val = I2CReceiveByte();
    I2CStop();

    return val;
}
version--2
uchar eeprom_read(uchar addr)
{
	uchar dat;
	I2CStart();
	I2CSendByte(0xa0);//写指令/*1010 000x*//*x(R/W)==1表示read,x==0表示write*//*这里写指令                                            
                                                                  表示联系芯片*/
	I2CWaitAck();
	I2CSendByte(addr);/*读的地址*/
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0xa1);/*读指令*/
	I2CWaitAck();
	dat=I2CReceiveByte();
	I2CWaitAck();
	I2CStop();
	return dat;
}


void eeprom_write (uchar addr,uchar dat)
{
	I2CStart();
	I2CSendByte(0xa0);/*表示联系芯片且告知芯片要读取那个存储单元*/
	I2CWaitAck();
	I2CSendByte(addr);/*写的地址*/
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}
TIM定时器模块----->>>>属于最重要的模块

!!!---->此模块调用了最多的HAL库函数,需要着重记忆

在这里定时器分为四个部分:
->TIM

->PWMOUT

->FREQIN

->PWMIN

--------------------------------------------------------TIM----------------------------------------------------

/*以基本定时器TIM6为例,演示定时器的基本定时功能,
  以及触发中断后的中断处理函数与中断回调函数*/

HAL_TIM_Base_Start_IT(&htim6);/*定时器基本操作-->开始(定时/更新)中断*/
            /*相似函数HAL_TIM_Base_Start(&htim6);表示定时器基础--->开启定时器*/
__HAL_TIM_CLEAR_IT(&htim6,TIM_IT_UPDATE);/*清楚定时器中断标志-->清除类型--更新中断*/
                                  /*注意该函数可有可无!!*/


/**************中断回调函数**********/
/**初始定义为  _weak  需要用户自行编写**/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(++led_time == 1000)    
    {
        LED_Time=0;
		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | 
													GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);			
	}
}

-----------------------------------------------------------PWMOUT-------------------------------------------------------

HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);/*定时器--->PWN开启*/
            /*注意区分:HAL_TIM_PWM_Start_IT();---定时器---->PWM 中断开启*/
__HAL_TIM_CLEAR_IT(&htim2,TIM_IT_UPDATE);/*依旧是清除更新中断*/

__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,500);/*函数功能:设置捕获比较寄存器(CCRx)的值*/

------------------------------------------------------------FERQIN--------------------------------------------------------

/*单个定时器输入捕获示例*/
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);/*开启定时器输入捕获中断*/

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)/*输入捕获回调函数*/
{
    cc_value = __HAL_TIM_GET_CPUNTER(&htim3);/*获取计数器的值*/
    __HAL_TIM_Setcounter(&htim3,0);
    f39 = (80000000/(80-1))/cc_value;
} /*上升沿捕获,所以检测到低电平到高电平变化时开始采集-采集一个周期时间,从而计算频率;
                         CNT-->ARR(CNT==ARR)*/

/*两个定时器输入捕获示例*/
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    /*注意对定时器进行判断*/
    if(htim->Instance == TIM3)
    {
        cc1_value = __HAL_TIM_GET_COUNTER(&htim3);
        __HAL_TIM_Setcounter(&htim3,0);
        f39 = 1000000/cc1_value;
        HAL_TIM_IC_Start_IT(&himt3);/*更新*/
    }
    if(htim->Instance == TIM2)
    {
        cc2_value = __HAL_TIM_GET_COUNTER(&htim2);
        __HAL_TIM_Setcounter(&htim2,0);
        f40 = 1000000/cc2_value;
        HAL_TIM_IC_Start_IT(&htim2);
    }
}

--------------------------------------------------------------PWMIN--------------------------------------------------------

uint32 Duty = 0;
uint32 Freq = 0;

HAL_TIM_IC_Start_IC(&hitm2,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IC(&htim2,TIM_CHANNEL_2);

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    volatile static uint32_t Freq_val = 0,Duty_val = 0;
    if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
    {
        Freq_val = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)//周期---上升沿
        Freq = 1000000/Freq_val;
    }
    else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
    {
        Duty_val = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)//占空---下降沿
        Duty = Duty_val * 100 / Freq_val;
    }

}
USART串口通信---->>>开发板与上位机进行转串口通信-----!!!!!重点为UART

!!!!重点掌握UART通信即异步串口通信

该模块的使用也非常简单,只需要调用两个HAL库函数,以及编写一个接收中断回调函数即可

uint8_t str[20];

/*(开发板向上位机)发送数据*/
HAL_UART_Transmit_IT(&huart1,(unsigned char *)"Hello,World.\r\n",16);
                                                        /*注意这里发送的是定长数据*/
HAL_UART_Transmit_IT(&huart1,(unsigned char *)str,strlen((char *)str));
只需要在While循环中一直调用HAL_UART_Transmit_IT(……);函数即可实现发送数据功能


/*(开发板接收上位机发送到数据)接收数据*/

uint8_t rx[20];

HAL_UART_Receive_IT(&huart1,(uint8_t *)rx,10);/*注意该函数需要进行初始化,即在main函数前调用, 
                                                        以便更新中断,时该函数重复执行*/

HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    LCD_DisplayStringLine(Line8, (uint8_t *)(rx));
	HAL_UART_Receive_IT(&huart1, (uint8_t *)rx, 10);/*更新*/
}
ADC&DAC-----------模拟信号<->数字信号  转换

该模块的模拟输出可以使用开发板集成的R37、R38两个旋钮,得到电压的值。

这里需要用户子自定义函数,不过函数的内容还是调用HAL库有关ADC的函数

/*******ADC代码示例********/
uint16_t getADC_R37(void)
{
    uint16_t adc_value;
    HAL_ADC_Start(&hadc2);
    HAL_ADC_PollForConversion(&hadc2,10);/*这里设置一个超时时间,等待常规组转换完成*/
    adc_value = HAL_ADC_GetValue(&hadc2);
    HAL_ADC_Stop(&hadc2);
    return (adc_value *3.3 /4096);/*ADC值的转换-这里总电压为3.3V,ADC精度为12位2^12 == 4096*/
}
uint16_t getADC_R38(void)
{
    uint16_t adc_value;
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1,10);
    adc_value = HAL_ADC_GetValue(&hadc1);
    HAL_ADC_Stop(&hadc1);
    return (adc_value *3.3/4096);
}
/*******DAC代码示例**********/
HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);

	DAC1_Set_Vol(2.57);
	HAL_Delay(1000);
	DAC1_Set_Vol(1.25);
	HAL_Delay(1000);

void DAC_Set_Vol(float vol)
{
    uint16_t temp;
	temp = (4096*vol/3.3f);
	HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1,DAC_ALIGN_12B_R,temp);
}
version--2
double getADC(ADC_HandleTypeDef *pin)
{
	uint adc;
	HAL_ADC_Start (pin);
	adc = HAL_ADC_GetValue(pin);
	return adc*3.3/4096;
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值