当前位置: 首页 > news >正文

广州网站优化关键词方法2021年近期舆情热点话题

广州网站优化关键词方法,2021年近期舆情热点话题,松江做公司网站,域名申请了怎么做网站选择HAL库还是标准库呢?HAL库是趋势,标准库不再升级了,转HAL库是大势所趋。HAL库有优点,也有自身的不足,建议初学者还是从标准库入手。 标准库是单片机开发的基本库,它把“用寄存器实现的功能”写成一个函…

选择HAL库还是标准库呢?HAL库是趋势,标准库不再升级了,转HAL库是大势所趋。HAL库有优点,也有自身的不足,建议初学者还是从标准库入手。

标准库是单片机开发的基本库,它把“用寄存器实现的功能”写成一个函数或定义成宏,供用户使用。

HAL库把“有关系的功能”封装成一个函数,供用户调用,其目的是想隔绝用户直接干预寄存器操作,想法很好,但实际是行不通的,大部分是好的,另外提供了两个用户接口函数MspInit和Callback。

1、MspInit函数

HAL库写了很多个Init函数供用户调用,前提是必须要写好MspInit函数。同种功能硬件资源共用一个MspInit函数,所以所以这个MspInit函数必然就有许多分支,降低了程序的执行效率。下面举例说明:

//函数功能:使能TIMx时钟,设置中断优先级,使能TIMx中断

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)

{

         if(htim->Instance == TIM1)//初始化TIM1

         {

    __HAL_RCC_TIM1_CLK_ENABLE();                      //使能TIM1时钟

    HAL_NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 0, 0); //设置中断优先级

HAL_NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);

//使能TIM1刹车事件,更新事件,触发事件,COM事件中断

         }

         if(htim->Instance == TIM3)//初始化TIM3

         {

    __HAL_RCC_TIM3_CLK_ENABLE();     //使能TIM3时钟

    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0); //设置中断优先级

    HAL_NVIC_EnableIRQ(TIM3_IRQn);     //使能TIM3中断

         }

}

用户通过增删MspInit函数中的内容,好像也很容易。在初始化时,设备用到的时钟,引脚复用,中断优先级管理等都需要写在这里。

2、Callback函数

HAL库写了很多个IRQHandler函数供用户调用,前提是必须要写好Callback函数。同种功能硬件资源共用一个Callback函数,所以所以这个Callback函数必然就有许多分支,降低了程序的执行效率。下面举例说明:

//函数功能:在定时器更新中断时,HAL_TIM_IRQHandler()会调用函数,处理用户程序

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

         if(htim->Instance==TIM1)//处理定时器1

         {

    TIM1_LED_Toggle();

         }

         if(htim->Instance==TIM3)//处理定时器3

         {

    TIM3_LED_Toggle();

         }

}

//函数功能:TIM1中断服务程序

void TIM1_BRK_UP_TRG_COM_IRQHandler(void)

{

TIM_HandleTypeDef TIM1_HandleStructure;

TIM1_HandleStructure.Instance=TIM1;

  HAL_TIM_IRQHandler(&TIM1_HandleStructure);

}

//函数功能:TIM3中断服务程序

void TIM3_IRQHandler(void)

{

TIM_HandleTypeDef TIM3_HandleStructure;

TIM3_HandleStructure.Instance=TIM3;

  HAL_TIM_IRQHandler(&TIM3_HandleStructure);

}

通过上面的举例,好像Callback函数也不像想象中的那么难写。但我们发现一个问题,这个IRQHandler函数传递是一个结构指针,所以必须有一个结构变量与之对应,所以在中断服务程序中申请一个局部结构变量,因为申请为全局变量确实有点浪费内存。官方给的例子基本都是全局变量,容易把人带入歧途

3、HAL库的缺点

HAL库中的某些功能性函数,有可能不能满足需求,需要自己动手写,也是常有的事情。例如串口的函数库,有些函数脱离实际,如:

1)、串口接收函数,必须先知道接收多少个数据,才可以调用。

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

2)、串口发送函数,需要把UART_HandleTypeDef结构类型的变量定义为全局变量,才可以使用。这么设计,很消耗内存。

HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

如果你不按照HAL库的套路干,就需要对某些函数和宏定义进行重构。如果我们不了解底层,就只能按照它的意思干。

还是举例说明
 

#define _HAL_UART_SendByte(__INSTANCE__, __DATA__) (__INSTANCE__)->DR = ( (__DATA__) & (uint16_t)0x01FF );
//将(__DATA__)写入串口发送缓冲区#define _HAL_UART_ReceiveByte(__INSTANCE__) ( (uint16_t)( (__INSTANCE__)->DR & (uint16_t)0x01FF) )
//读串口发送缓冲区#define _HAL_UART_GET_FLAG(__INSTANCE__, __FLAG__) ( ( (__INSTANCE__)->SR & (__FLAG__) ) == (__FLAG__) )
//读串口中断标志位
//(__FLAG__)=UART_IT_RXNE,读"串口接收寄存器为非空时产生的中断标志位"
//(__FLAG__)=UART_IT_PE,读"串口奇偶校验错误产生的中断标志位"
//(__FLAG__)=UART_IT_ERR,读"帧错误、噪音错误和溢出错误时产生的中断标志位"
//(__FLAG__)=UART_IT_TXE时,读"串口发送寄存器为空产生的中断标志位"
//(__FLAG__)=UART_IT_TC时,读"发送完成产生的中断标志位"#define _HAL_UART_CLEAR_FLAG(__INSTANCE__, __FLAG__) ( (__INSTANCE__)->SR = ~(__FLAG__) )
//清除串口中断标志位
//(__FLAG__)=UART_IT_RXNE,清除"串口接收寄存器为非空时产生的中断标志位"
//(__FLAG__)=UART_IT_PE,清除"串口奇偶校验错误产生的中断标志位"
//(__FLAG__)=UART_IT_ERR,清除"帧错误、噪音错误和溢出错误时产生的中断标志位"
//(__FLAG__)=UART_IT_TXE时,清除"串口发送寄存器为空产生的中断标志位"
//(__FLAG__)=UART_IT_TC时,清除"发送完成产生的中断标志位"#define _HAL_UART_ENABLE_IT(__INSTANCE__, __INTERRUPT__)   ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__INSTANCE__)->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \(((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__INSTANCE__)->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \((__INSTANCE__)->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
//设置串口中断使能位
//(__INTERRUPT__)=UART_IT_RXNE,设置"串口接收寄存器为非空"时,使其产生中断
//(__INTERRUPT__)=UART_IT_PE,设置"串口奇偶校验错误"时,使其产生中断
//(__INTERRUPT__)=UART_IT_ERR,设置"帧错误、噪音错误和溢出错误"时,使其产生中断
//(__INTERRUPT__)=UART_IT_TXE时,设置"串口发送寄存器为空"时,使其产生中断
//(__INTERRUPT__)=UART_IT_TC时,设置"串口发送寄存器发送完成"时,使其产生中断#define _HAL_UART_DISABLE_IT(__INSTANCE__, __INTERRUPT__)  ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__INSTANCE__)->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \(((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__INSTANCE__)->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \((__INSTANCE__)->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))
//设置串口中断不使能
//(__INTERRUPT__)=UART_IT_RXNE,设置"串口接收寄存器为非空"时,不使其产生中断
//(__INTERRUPT__)=UART_IT_PE,设置"串口奇偶校验错误"时,不使其产生中断
//(__INTERRUPT__)=UART_IT_ERR,设置"帧错误、噪音错误和溢出错误"时,不使其产生中断
//(__INTERRUPT__)=UART_IT_TXE时,设置"串口发送寄存器为空"时,不使其产生中断
//(__INTERRUPT__)=UART_IT_TC时,设置"串口发送寄存器发送完成"时,不使其产生中断

//重定义fputc函数
//函数功能:发送ch的值给USART2串口

int fputc(int ch, FILE *f)
{
  _HAL_UART_SendByte(USART2, (unsigned char) ch);
  while( _HAL_UART_GET_FLAG(USART2,USART_SR_TC)!= SET);

//等待发送完成标志位被置1    
    return ch;
}

//函数功能:串口2发送一个字节
void USART2_SendByte(  unsigned char ch )
{
  _HAL_UART_SendByte(USART2, (unsigned char) ch);
  while( _HAL_UART_GET_FLAG(USART2,USART_SR_TC)!= SET);

//等待发送完成标志位被置1
}

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{GPIO_InitTypeDef  GPIO_InitStructureure;if(huart->Instance==USART2){__HAL_RCC_USART2_CLK_ENABLE();//使能USART2外设时钟__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟//串口引脚映射开始/GPIO_InitStructureure.Pin = GPIO_PIN_0;     //选择第0脚,PA0是为USART2_TXGPIO_InitStructureure.Mode = GPIO_MODE_AF_PP;            //复用功能推挽模式GPIO_InitStructureure.Pull = GPIO_PULLUP;                //引脚上拉被激活GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速GPIO_InitStructureure.Alternate = GPIO_AF9_USART2;       //将引脚复用为USART2HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器//将PA0初始化为USART2_TXGPIO_InitStructureure.Pin = GPIO_PIN_1;     //选择第1脚,PA1是USART2_RXGPIO_InitStructureure.Mode = GPIO_MODE_AF_PP;            //复用功能推挽模式GPIO_InitStructureure.Pull = GPIO_PULLUP;                //引脚上拉被激活GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速GPIO_InitStructureure.Alternate = GPIO_AF9_USART2;       //将引脚复用为USART2HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器//将PA1初始化为USART2_RX
//串口引脚映射结束/HAL_NVIC_SetPriority(USART2_IRQn, 0x01, 0);//设置串口2中断优先级为0x01,0无意义}
}//函数功能:
//PA0是为USART2_TX,PA1是USART2_RX
//中断优先级为0x01
//波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
void USART2_Init(uint32_t baudrate)
{UART_HandleTypeDef UART_HandleStructureure;UART_HandleStructureure.Instance          = USART2;              //接口为USART2UART_HandleStructureure.Init.BaudRate     = baudrate;            //波特率为115200bpsUART_HandleStructureure.Init.WordLength   = UART_WORDLENGTH_8B;  //串口字长度为8UART_HandleStructureure.Init.StopBits     = UART_STOPBITS_1;     //串口停止位为1位UART_HandleStructureure.Init.Parity       = UART_PARITY_NONE;    //串口无需奇偶校验UART_HandleStructureure.Init.HwFlowCtl    = UART_HWCONTROL_NONE; //串口无硬件流程控制UART_HandleStructureure.Init.Mode         = UART_MODE_TX_RX;     //串口工作模式为发送和接收模式UART_HandleStructureure.AdvancedInit.AdvFeatureInit=UART_ADVFEATURE_NO_INIT;//不使用自动波特率
//	UART_HandleStructureure.AdvancedInit.AdvFeatureInit=UART_ADVFEATURE_AUTOBAUDRATE_INIT;//使用自动波特率配置
//	UART_HandleStructureure.AdvancedInit.AutoBaudRateEnable=UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;//自动波特率使能
//	UART_HandleStructureure.AdvancedInit.AutoBaudRateMode=UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT;//自动波特率模式HAL_UART_Init(&UART_HandleStructureure);//根据UART_HandleStructureure型结构初始化USART2__HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_RXNE);开启串口接收中断//串口接收数据时,使能"接收数据寄存器不为空"则产生中断(位RXNE=1)//Enable the UART Data Register not empty Interrupt__HAL_UART_DISABLE_IT(&UART_HandleStructureure, UART_IT_TXE);//串口发送数据时,不使能"串口发送数据寄存器为空"产生中断(位TXE=0)//Disable the UART Transmit Complete Interrupt__HAL_UART_DISABLE_IT(&UART_HandleStructureure,UART_IT_TC);//串口发送数据时,不使能"串口发送完成"产生中断(位TC=1)HAL_NVIC_EnableIRQ(USART2_IRQn);//使能串口2中断//USART2_IRQn表示中断源为串口2
}

 放弃了HAL_UART_Receive_IT()之后,HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)也就废了。直接用自己的,不用Callback函数,如下:

//函数功能:串口2中断服务程序
void USART2_IRQHandler(void)
{
    uint8_t RX_temp;

    (void)RX_temp;//防止RX_temp不使用而产生警告

    if( _HAL_UART_GET_FLAG(USART2,USART_SR_RXNE) )
    {//在串口状态寄存器中,发现RXNE=1,且串口控制寄存器1允许接收数据
        RX_temp =_HAL_UART_ReceiveByte(USART2);//读串口数据

        _HAL_UART_CLEAR_FLAG(USART2,USART_SR_RXNE);
        if(RX_temp=='1' && USART2_RX_Time_Count==0)    USART2_RX_Time_Count = 1;

//如果接收到帧头为变频器地址为0x1,则启动USART2接收时间计数器
        if(USART2_RX_Time_Count > 0)
        {
            USART2_RX_Time_Count = 1;//设置USART2接收时间计数器为1;
            USART2_RX_Buffer[USART2_RX_Buffer_Load_Index] = RX_temp;//保存接收到的新数据
            USART2_RX_Buffer_Load_Index++;

            if(USART2_RX_Buffer_Load_Index>=USART2_RX_Buffer_Size) USART2_RX_Buffer_Load_Index=1;//防止USART2_RX_Buffer[]溢出
        }

        //软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将ORE位(Overrun错误标志)清零;
        //软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将NE位(噪声错误标志)清零;
        //软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将FE位(帧错误标志)清零;
        //软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将PE位(奇偶校验值错误)清零;
        //软件读"串口数据寄存器USART_DR",就可以将RXNE位清零

  }
}

5、学习HAL库的方法:

1)、要了解了HAL库对程序的管理方法,这个只能靠自己去看库中的函数了。

2)、熟悉结构变量中各个成员的意义。

3)、熟悉HAL库的函数。

4)、多测试,多看高手的程序。如果刚入门,可能会被半桶水的人带偏了。例如:官方的程序,他们的思路可能不符合实际使用,但是用来测试还是可以的,我们需要把它修改实际需要的那种代码。

不建议初学者,直接学习HAL库,还是从标准库学习比较好。只要你有兴趣,学习都是一样的。

有时没办法,不能按照HAL库思路干,还是需要涉及到寄存器操作。

6、学习总结
标准库转HAL库,HAL里面的初始化函数,需要重点掌握,虽然申请的结构变量占很多空间,但是初始化完后,就可以释放了,但串口有点特殊,最好自己写。
1)、因为内存容量有限,不建议将初始化结构参数申请为全局变量。由于没有将结构参数设为全局变量,有些函数或宏需要重写,以满足实际需求。如:
读中断标志位
清除中断标志位
使能中断
不使能能中断
串口发送
串口接收
等相关的函数需要重构。
2)、带MspInit的函数,建议写在需要初始化的函数中。HAL采用同一管理,这个MspInit的函数只有一个,所以很庞大,而且还要做判断,效率极低。
3)、带CallBack的函数只有一个,由于没有食使用全局结构变量,所以不能用。而申请为全局结构变量,又很浪费内存。
4)、为了方便移植,中断不再使用同一个CallBack函数了。


7、HAL库有自己的优点:
1)、把所有的硬件驱动都写好了,我们要从中扣出有价值的函数,使编程更加灵活。
2)、初始化函数只有一个。
不管是用什么库,里面的结构参数知道怎么赋值,干啥用的,基本就上路了。

这是我个人的体会,觉得这么做,可以提高程序的执行效率,其次是节省内存,更主要的是功能模块化,易读,易移植,易交流。程序短小。

程序短小精悍,是每个程序员的追求。
芯片内存不是问题,HAL库的程序管理方法,可以值得借鉴,除了那些不切合实际的库函数外。经得起实践检验的方法就是最好的方法,不必死板硬套。

 


文章转载自:
http://consumerism.rdgb.cn
http://paramilitarist.rdgb.cn
http://whippletree.rdgb.cn
http://epitomist.rdgb.cn
http://prehnite.rdgb.cn
http://teleost.rdgb.cn
http://pyramidal.rdgb.cn
http://asphaltic.rdgb.cn
http://subcompany.rdgb.cn
http://heroically.rdgb.cn
http://lodestar.rdgb.cn
http://republicanism.rdgb.cn
http://clishmaclaver.rdgb.cn
http://mavournin.rdgb.cn
http://sadly.rdgb.cn
http://inleak.rdgb.cn
http://dare.rdgb.cn
http://pleuropneumonia.rdgb.cn
http://entrechat.rdgb.cn
http://raughty.rdgb.cn
http://holt.rdgb.cn
http://incoherently.rdgb.cn
http://laparotomy.rdgb.cn
http://periastron.rdgb.cn
http://increased.rdgb.cn
http://squamulose.rdgb.cn
http://integrationist.rdgb.cn
http://squabby.rdgb.cn
http://swatch.rdgb.cn
http://chiphead.rdgb.cn
http://iconolatrous.rdgb.cn
http://tassel.rdgb.cn
http://ulmous.rdgb.cn
http://graphology.rdgb.cn
http://understood.rdgb.cn
http://cropland.rdgb.cn
http://gendarmerie.rdgb.cn
http://keypunch.rdgb.cn
http://desultoriness.rdgb.cn
http://gyronny.rdgb.cn
http://ectogenous.rdgb.cn
http://blastoid.rdgb.cn
http://lifeguard.rdgb.cn
http://udderless.rdgb.cn
http://tergiversate.rdgb.cn
http://craniectomize.rdgb.cn
http://carryon.rdgb.cn
http://pulka.rdgb.cn
http://porphyry.rdgb.cn
http://kame.rdgb.cn
http://super.rdgb.cn
http://looby.rdgb.cn
http://chechako.rdgb.cn
http://unthankful.rdgb.cn
http://daedalean.rdgb.cn
http://eclogite.rdgb.cn
http://gnat.rdgb.cn
http://savourless.rdgb.cn
http://pentomic.rdgb.cn
http://spermine.rdgb.cn
http://multidisciplinary.rdgb.cn
http://bottomry.rdgb.cn
http://semicentenary.rdgb.cn
http://hyperkinesia.rdgb.cn
http://microfilaria.rdgb.cn
http://eburnated.rdgb.cn
http://supersensitize.rdgb.cn
http://azotic.rdgb.cn
http://mollweide.rdgb.cn
http://dreich.rdgb.cn
http://councilwoman.rdgb.cn
http://eudaimonism.rdgb.cn
http://thylakoid.rdgb.cn
http://civilianize.rdgb.cn
http://token.rdgb.cn
http://aciduria.rdgb.cn
http://drumroll.rdgb.cn
http://hummaul.rdgb.cn
http://microecology.rdgb.cn
http://phenate.rdgb.cn
http://subgraph.rdgb.cn
http://palazzo.rdgb.cn
http://numbskull.rdgb.cn
http://photoemission.rdgb.cn
http://chevron.rdgb.cn
http://sapful.rdgb.cn
http://counterdrug.rdgb.cn
http://myrmidon.rdgb.cn
http://migod.rdgb.cn
http://taffetized.rdgb.cn
http://leucemia.rdgb.cn
http://seamark.rdgb.cn
http://slovak.rdgb.cn
http://taiwan.rdgb.cn
http://vomiturition.rdgb.cn
http://arsine.rdgb.cn
http://xanthosis.rdgb.cn
http://guiyang.rdgb.cn
http://biostatics.rdgb.cn
http://headship.rdgb.cn
http://www.hrbkazy.com/news/61558.html

相关文章:

  • 日本药妆电子商务网站建设规划书建网站教学
  • 苏州招聘网站建设新闻稿营销
  • 微博的网站连接是怎么做的关键词歌词简谱
  • 乐陵森林公安电影站的seo
  • wordpress支付查看插件使用 ahrefs 进行 seo 分析
  • 济南手机建站公司营口seo
  • 商洛市住户和城乡建设局网站信息价成都营销推广公司
  • 沈阳网站营销推广免费的个人网站html代码
  • 网站被百度蜘蛛爬了多久放出来怎么做电商创业
  • 网站设计导航栏怎么做无锡网站建设seo
  • 中文绿色环保网站模板广州市疫情最新
  • 深圳公司注册下来有哪些资料西安百度首页优化
  • 桂林户外论坛搜索引擎优化的工具
  • 建设主题网站一般要经历的顺序做营销策划的公司
  • 美食网站首页设计百度会员登录入口
  • 定制手机网站开发外链屏蔽逐步解除
  • 中企动力做网站真贵武汉seo优化公司
  • ctcms做的比较好的网站seo系统培训
  • python 快速做网站地推接单平台
  • 如何做一款服装网站百度地图关键词排名优化
  • 远程发布 wordpressseo网站排名优化服务
  • 网站建设公司专业的建站优化公司东莞网站优化
  • 网站建设现在什么服务器比较好深圳整站全网推广
  • 惠州网站制作公司哪家好新手做网络销售难吗
  • Godaddy优惠码网站怎么做的大数据培训
  • asp.net网站结构seo营销方案
  • 浙江疫情最新消息今天五年级下册数学优化设计答案
  • 网站建设域名怎么用国外电商平台有哪些
  • 方案案例网站青岛seo排名扣费
  • 建立网站要什么条件和多少钱专业外贸网络推广