范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

一个学妹写的按键检测函数把我秀翻了

  上来第一个例程就是使用按键点亮一个LED灯,好家伙。点灯小师弟比较在行,毕竟32、FPGA、Linux的小灯都被小师弟点了一遍。哈哈哈!所以今天还是来说一说按键检测吧!
  一、如何进行按键检测
  检测按键有中断方式和GPIO查询方式两种。推荐大家用GPIO查询方式。  1.从裸机的角度分析中断方式 :中断方式可以快速地检测到按键按下,并执行相应的按键程序,但实际情况是由于按键的机械抖动特性,在程序进入中断后必须进行滤波处理才能判定是否有效的按键事件。如果每个按键都是独立的接一个 IO 引脚,需要我们给每个 IO 都设置一个中断,程序中过多的中断会影响系统的稳定性。中断方式跨平台移植困难。 查询方式 :查询方式有一个最大的缺点就是需要程序定期的去执行查询,耗费一定的系统资源。实际上耗费不了多大的系统资源,因为这种查询方式也只是查询按键是否按下,按键事件的执行还是在主程序里面实现。 2.从OS的角度分析中断方式 :在 OS 中要尽可能少用中断方式,因为在RTOS中过多的使用中断会影响系统的稳定性和可预见性。只有比较重要的事件处理需要用中断的方式。 查询方式 :对于用户按键推荐使用这种查询方式来实现,现在的OS基本都带有CPU利用率的功能,这个按键FIFO占用的还是很小的,基本都在1%以下。 二、最简单的按键检测程序
  先给他说了一种经典的按键检测代码,相信大多数人使用按键函数都见过它,很简单就不过多介绍了!  #define KEY0_PRES 1  //KEY0   #define KEY1_PRES 2  //KEY1  #define WKUP_PRES 3  //WK_UP   u8 KEY_Scan(u8 mode) {    static u8 key_up=1;//按键按松开标志  if(mode)key_up=1;  //支持连按      if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))  {   delay_ms(10);//去抖动    key_up=0;   if(KEY0==0)return KEY0_PRES;   else if(KEY1==0)return KEY1_PRES;   else if(WK_UP==1)return WKUP_PRES;   }else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;         return 0;// 无按键按下 }  int main(void) {   u8 t=0;     delay_init();       //延时函数初始化     LED_Init();       //初始化与LED连接的硬件接口  KEY_Init();           //初始化与按键连接的硬件接口  LED=0;     //点亮LED  while(1)  {   t=KEY_Scan(0);  //得到键值   switch(t)   {         case KEY0_PRES:  //如果KEY0按下      LED=!LED;     break;    default:     delay_ms(10);    }   } }
  如果你在工作中使用这种代码,有可能会被同事笑话。当然我这里并不是说这种代码不好,不管黑猫白猫,能抓住老鼠就是好猫。只要能满足项目需求实现对应的功能就是好代码。但是如果你使用下面这种个人感觉可能会更好。
  其实也并没有什么神秘感,就是使用了FIFO机制。参考的就是安富莱的按键例程,不过源代码相对比较复杂,对于初学者并不友好,所以小小的修改了一下,仅供参考!
  在前面分享了使用系统滴答定时器实现了多个软件定时器,在按键FIFO中也需要使用这个定时器。在系统的开始我们会启动一个10ms的软件定时器。在这个10ms的软件定时器中不断的进行按键扫描,与其他的任务互不影响。  三、为什么要了解FIFO
  要回答什么是FIFO,先要回答为什么要使用FIFO。只有搞清楚使用FIFO的好处,你才会有意无意的使用FIFO。学习FIFO机制和状态机机制一样,都是在裸机编程中非常重要的编程思想。编程思想很重要。初级coder总是在关注代码具体是怎么写,高级coder关注的是程序的框架逻辑,而不是某个细节。只要你框架逻辑通了,则一通百通。  四、什么是FIFO
  FIFO是先入先出的意思,即谁先进入队列,谁先出去。比如我们需要串口打印数据,当使用缓存将该数据保存的时候,在输出数据时必然是先进入的数据先出去,那么该如何实现这种机制呢?首先就是建立一个缓存空间,这里假设为10个字节空间进行说明。
  从这张图就知道如果要使用FIFO,就要定义一个结构体,而这个结构体至少应该有三个成员。 数组buf、读指针read、写指针write 。 typedef struct {  uint8_t Buf[10];  /* 缓冲区 */  uint8_t Read;   /* 缓冲区读指针*/  uint8_t Write;   /* 缓冲区写指针 */ }KEY_FIFO_T;
  缓存一开始没有数据,并且用一个变量write指示下一个写入缓存的索引地址,这里下一个存放的位置就是0,用另一个变量read 指示下一个读出缓存的索引地址,并且下一个读出数据的索引地址也是0。目前队列中是没有数据的,也就是不能读出数据,队列为空的判断条件在这里就是两个索引值相同。
  现在开始存放数据:
  在这里可以看到队列中加入了9个数据,并且每加入一个数据后队尾索引加 1,队头不变,这就是数据加入队列的过程。但是缓存空间只有10个,如何判断队列已满呢?如果只是先一次性加数据到队列中,然后再读出数据,那这里的判断条件显然是队尾索引为9。
  好了这就是FIFO的基本原理,下面来看一下 按键FIFO是怎么操作的 。
  我们这里以5个字节的FIFO空间进行说明。Write变量表示写位置,Read 变量表示读位置。初始状态时,Read = Write = 0。
  我们依次按下按键 K1,K2,那么FIFO中的数据变为:
  如果 Write!= Read,则我们认为有新的按键事件。我们通过函数 KEY_FIFO_Get() 读取一个按键值进行处理后,Read 变量变为 1。Write 变量不变。
  继续通过函数 KEY_FIFO_Get() 读取 3 个按键值进行处理后,Read 变量变为 4。此时Read = Write= 4。两个变量已经相等,表示已经没有新的按键事件需要处理。
  有一点要特别的注意,如果 FIFO 空间写满了,Write 会被重新赋值为 0,也就是重新从第一个字节空间填数据进去,如果这个地址空间的数据还没有被及时读取出来,那么会被后来的数据覆盖掉,这点要引起大家的注意 。我们的驱动程序开辟了 10 个字节的 FIFO 缓冲区,对于一般的应用足够了。 五、按键FIFO的优点可靠地记录每一个按键事件,避免遗漏按键事件。特别是需要实现按键的按下、长按、自动连发、弹起等事件时。  读取按键的函数可以设计为非阻塞的,不需要等待按键抖动滤波处理完毕。  按键 FIFO 程序在嘀嗒定时器中定期的执行检测,不需要在主程序中一直做检测,这样可以有效地降低系统资源消耗。  六、按键 FIFO 的实现1.定义结构体
  在我们的key.h文件中定义一个结构体类型为 KEY_FIFO_T 的结构体。就是前面说的那个结构体。这只是类型声明,并没有分配变量空间。 typedef struct {  uint8_t Buf[10];  /* 缓冲区 */  uint8_t Read;   /* 缓冲区读指针*/  uint8_t Write;   /* 缓冲区写指针 */ }KEY_FIFO_T;
  接着在key.c 中定义 s_tKey 结构变量, 此时编译器会分配一组变量空间。  static KEY_FIFO_T s_tKey;/* 按键FIFO变量,结构体 */
  好了按键FIFO的结构体数据类型就定义完了,很简单吧!  2.将键值写入FIFO
  既然结构体都定义好了,接着就是往这个FIFO的数组中写入数据,也就是按键的键值,用来模拟按键的动作了。  /* ********************************************************** * 函 数 名: KEY_FIFO_Put * 功能说明: 将1个键值压入按键FIFO缓冲区。可用于模拟一个按键。 * 形    参:  _KeyCode : 按键代码 * 返 回 值: 无 ********************************************************** */ void KEY_FIFO_Put(uint8_t _KeyCode) {  s_tKey.Buf[s_tKey.Write] = _KeyCode;   if (++s_tKey.Write  >= KEY_FIFO_SIZE)  {   s_tKey.Write = 0;  } }
  函数的主要功能就是将按键代码 _KeyCode 写入到FIFO中,而这个FIFO就是我们定义结构体的这个数组成员,每写一次,就是每调用一次KEY_FIFO_Put() 函数,写指针write就++ 一次,也就是向后移动一个空间,如果FIFO空间写满了,也就是s_tKey.Write >= KEY_FIFO_SIZE ,Write会被重新赋值为 0。 3.从FIFO读出键值
  有写入键值当然就有读出键值。  /* *********************************************************** * 函 数 名: KEY_FIFO_Get * 功能说明: 从按键FIFO缓冲区读取一个键值。 * 形    参: 无 * 返 回 值: 按键代码 ************************************************************ */ uint8_t KEY_FIFO_Get(void) {  uint8_t ret;   if (s_tKey.Read == s_tKey.Write)  {   return KEY_NONE;  }  else  {   ret = s_tKey.Buf[s_tKey.Read];    if (++s_tKey.Read >= KEY_FIFO_SIZE)   {    s_tKey.Read = 0;   }   return ret;  } }
  如果写指针和读出的指针相等,那么返回值就为0,表示按键缓冲区为空,所有的按键时间已经处理完毕。如果不相等就说明FIFO的缓冲区不为空,将Buf中的数读出给 ret 变量。同样,如果FIFO空间读完了,没有缓存了,也就是s_tKey.Read >= KEY_FIFO_SIZE ,Read也会被重新赋值为 0。按键的键值定义在key.h 文件,下面是具体内容: typedef enum {  KEY_NONE = 0,   /* 0 表示按键事件 */   KEY_1_DOWN,    /* 1键按下 */  KEY_1_UP,    /* 1键弹起 */  KEY_1_LONG,    /* 1键长按 */   KEY_2_DOWN,    /* 2键按下 */  KEY_2_UP,    /* 2键弹起 */  KEY_2_LONG,    /* 2键长按 */   KEY_3_DOWN,    /* 3键按下 */  KEY_3_UP,    /* 3键弹起 */  KEY_3_LONG,    /* 3键长按 */ }KEY_ENUM;
  点击获取1V1嵌入式学习规划,现在还送100G精选学习资料嵌入式物联网开发学习咨询
  必须按次序定义每个键的按下、弹起和长按事件,即每个按键对象占用 3 个数值。 推荐使用枚举enum, 不用#define 的原因是便于新增键值,方便调整顺序。使用{ } 将一组相关的定义封装起来便于理解。编译器也可帮我们避免键值重复。 4.按键检测程序
  上面说了如何将按键的键值存入和读出FIFO,但是既然是按键操作,就肯定涉及到按键消抖处理,还有按键的状态是按下还是弹起,是长按还是短按。所以为了以示区分,我们用还需要给每一个按键设置很多参数,就需要再定义一个结构体 KEY_T ,让每个按键对应1个全局的结构体变量。 typedef struct {  /* 下面是一个函数指针,指向判断按键手否按下的函数 */  uint8_t (*IsKeyDownFunc)(void); /* 按键按下的判断函数,1表示按下 */   uint8_t  Count;   /* 滤波器计数器 */  uint16_t LongCount;  /* 长按计数器 */  uint16_t LongTime;  /* 按键按下持续时间, 0表示不检测长按 */  uint8_t  State;   /* 按键当前状态(按下还是弹起) */  uint8_t  RepeatSpeed; /* 连续按键周期 */  uint8_t  RepeatCount; /* 连续按键计数器 */ }KEY_T;
  在key.c 中定义 s_tBtn 结构体数组变量。 static KEY_T   s_tBtn[3] = {0};
  每个按键对象都分配一个结构体变量,这些结构体变量以数组的形式存在将便于我们简化程序代码行数。因为我的硬件有3个按键,所以这里的数组元素为3。使用函数指针 IsKeyDownFunc 可以将每个按键的检测以及组合键的检测代码进行统一管理。
  因为函数指针必须先赋值,才能被作为函数执行。因此在定时扫描按键之前,必须先执行一段初始化函数来设置每个按键的函数指针和参数。这个函数是 void KEY_Init(void) 。 void KEY_Init(void) {  KEY_FIFO_Init();  /* 初始化按键变量 */  KEY_GPIO_Config();  /* 初始化按键硬件 */ }
  下面是 KEY_FIFO_Init 函数的定义: static void KEY_FIFO_Init(void) {  uint8_t i;   /* 对按键FIFO读写指针清零 */  s_tKey.Read = 0;  s_tKey.Write = 0;   /* 给每个按键结构体成员变量赋一组缺省值 */  for (i = 0; i < HARD_KEY_NUM; i++)  {   s_tBtn[i].LongTime = 100;/* 长按时间 0 表示不检测长按键事件 */   s_tBtn[i].Count = 5/ 2; /* 计数器设置为滤波时间的一半 */   s_tBtn[i].State = 0;/* 按键缺省状态,0为未按下 */   s_tBtn[i].RepeatSpeed = 0;/* 按键连发的速度,0表示不支持连发 */   s_tBtn[i].RepeatCount = 0;/* 连发计数器 */  }  /* 判断按键按下的函数 */  s_tBtn[0].IsKeyDownFunc = IsKey1Down;  s_tBtn[1].IsKeyDownFunc = IsKey2Down;  s_tBtn[2].IsKeyDownFunc = IsKey3Down; }
  我们知道按键会有机械抖动,你以为按键按下就是低电平,其实在按下的一瞬间会存在机械抖动,如果不做延时处理,可能会出错,一般如果按键检测到按下后再延时50ms检测一次,如果还是检测低电平,才能说明按键真正的被按下了。反之按键弹起时也是一样的。所以我们程序设置按键滤波时间50ms, 因为代码每10ms扫描一次按键,所以按键的单位我们可以理解为10ms,滤波的次数就为5次。这样只有连续检测到50ms状态不变才认为有效,包括弹起和按下两种事件,即使按键电路不做硬件滤波(没有电容滤波),该滤波机制也可以保证可靠地检测到按键事件。
  判断按键是否按下,用一个 HAL_GPIO_ReadPin 就可以搞定。 static uint8_t IsKey1Down(void)  {  if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4) == GPIO_PIN_RESET)    return 1;  else    return 0; } static uint8_t IsKey2Down(void)  {  if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET)    return 1;  else    return 0; }  static uint8_t IsKey3Down(void)  {  if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == GPIO_PIN_RESET)    return 1;  else    return 0; }
  下面是 KEY_GPIO_Config 函数的定义,这个函数就是配置具体的按键GPIO的,就不需要过多的解释了。 static void KEY_GPIO_Config(void) {   GPIO_InitTypeDef GPIO_InitStructure;    /* 第1步:打开GPIO时钟 */  __HAL_RCC_GPIOE_CLK_ENABLE();    /* 第2步:配置所有的按键GPIO为浮动输入模式(实际上CPU复位后就是输入状态) */  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;      /* 设置输入 */  GPIO_InitStructure.Pull = GPIO_NOPULL;                 /* 上下拉电阻不使能 */  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;  /* GPIO速度等级 */    GPIO_InitStructure.Pin = GPIO_PIN_4;  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);    GPIO_InitStructure.Pin = GPIO_PIN_3;  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);    GPIO_InitStructure.Pin = GPIO_PIN_2;  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); } 5.按键扫描
  按键扫描函数 KEY_Scan() 每隔 10ms 被执行一次。RunPer10ms 函数在 systick 中断服务程序中执行。 void RunPer10ms(void) {  KEY_Scan(); }  void KEY_Scan(void) {  uint8_t i;  for (i = 0; i < HARD_KEY_NUM; i++)  {   KEY_Detect(i);  } } /*
  每隔10ms所有的按键GPIO均会被扫描检测一次。 KEY_Detect 函数实现如下: static void KEY_Detect(uint8_t i) {  KEY_T *pBtn;   pBtn = &s_tBtn[i];  if (pBtn->IsKeyDownFunc())  {//这个里面执行的是按键按下的处理   if (pBtn->Count < KEY_FILTER_TIME)   {//按键滤波前给 Count 设置一个初值    pBtn->Count = KEY_FILTER_TIME;   }   else if(pBtn->Count < 2 * KEY_FILTER_TIME)   {//实现 KEY_FILTER_TIME 时间长度的延迟    pBtn->Count++;   }   else   {    if (pBtn->State == 0)    {     pBtn->State = 1;      /* 发送按钮按下的消息 */     KEY_FIFO_Put((uint8_t)(3 * i + 1));    }     if (pBtn->LongTime > 0)    {     if (pBtn->LongCount < pBtn->LongTime)     {      /* 发送按钮持续按下的消息 */      if (++pBtn->LongCount == pBtn->LongTime)      {       /* 键值放入按键FIFO */       KEY_FIFO_Put((uint8_t)(3 * i + 3));      }     }     else     {      if (pBtn->RepeatSpeed > 0)      {       if (++pBtn->RepeatCount >= pBtn->RepeatSpeed)       {        pBtn->RepeatCount = 0;        /* 长按键后,每隔10ms发送1个按键 */        KEY_FIFO_Put((uint8_t)(3 * i + 1));       }      }     }    }   }  }  else  {//这个里面执行的是按键松手的处理或者按键没有按下的处理   if(pBtn->Count > KEY_FILTER_TIME)   {    pBtn->Count = KEY_FILTER_TIME;   }   else if(pBtn->Count != 0)   {    pBtn->Count--;   }   else   {    if (pBtn->State == 1)    {     pBtn->State = 0;      /* 发送按钮弹起的消息 */     KEY_FIFO_Put((uint8_t)(3 * i + 2));    }   }   pBtn->LongCount = 0;   pBtn->RepeatCount = 0;  } }
  这个函数还是比较难以理解的,主要是结构体的操作。所以好好学习结构体,不要见了结构体就跑。
  分析:首先读取相应按键的结构体地址赋值给结构体指针变量pBtn ,因为程序里面每个按键都有自己的结构体,只有通过这个方式才能对具体的按键进行操作。(在前面我们使用软件定时器时也使用了这中操作,在滴答定时器的中断服务函数中)。  static KEY_T s_tBtn[3];//程序里面每个按键都有自己的结构体,有三个按键 KEY_T *pBtn;//定义一个结构体指针变量pBtn pBtn = &s_tBtn[i];//将按键的结构体地址赋值给结构体指针变量pBtn
  然后接着就是给按键滤波前给Count设置一个初值,前面说按键初始化的时候已经设置了Count =5/2。然后判断是否按下的标志位,如果按键按下了,这里就将其设置为 1,如果没有按下这个变量的值就会一直是 0。这里可能不理解是就是按键按下发送的键值是 3 * i + 1 。按键弹起发送的键值是3 * i + 2 ,按键长按发送的键值是3 * i + 3 。也就是说按键按下发送的键值是1和4和7 。按键弹起发送的键值是2和5和8 ,按键长按发送的键值是3和6和9 。看下面这个枚举enum你就明白了。 typedef enum {  KEY_NONE = 0,   /* 0 表示按键事件 */   KEY_1_DOWN,    /* 1键按下 */  KEY_1_UP,    /* 1键弹起 */  KEY_1_LONG,    /* 1键长按 */   KEY_2_DOWN,    /* 2键按下 */  KEY_2_UP,    /* 2键弹起 */  KEY_2_LONG,    /* 2键长按 */   KEY_3_DOWN,    /* 3键按下 */  KEY_3_UP,    /* 3键弹起 */  KEY_3_LONG,    /* 3键长按 */   }KEY_ENUM; 7.试验演示int main(void) {  uint8_t KeyCode;/* 按键代码 */  KEY_Init();  while (1)  {     /* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用KEY_FIFO_Get读取键值即可。 */   KeyCode = KEY_FIFO_Get(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */   if (KeyCode != KEY_NONE)   {    switch (KeyCode)    {     case KEY_DOWN_K1:   /* K1键按下 */      printf("K1键按下r ");      break;     case KEY_UP_K1:    /* K1键弹起 */      printf("K1键弹起r ");      break;     case KEY_DOWN_K2:   /* K2键按下 */      printf("K2键按下r ");      break;     case KEY_UP_K2:    /* K2键弹起 */      printf("K2键弹起r ");      break;     case KEY_DOWN_K3:   /* K3键按下 */      printf("K3键按下r ");      break;     case KEY_UP_K3:    /* K3键弹起 */      printf("K3键弹起r ");      break;             default:      /* 其它的键值不处理 */      break;    }      }  } }
  不知道学妹看懂没,没看懂就多看几遍。代码例程已上传至Gitee。  https://gitee.com/zhiguoxin/Wechat-Data.git原文作者:果果小师弟
  原文标题:一个学妹写的按键检测函数把我秀翻了!
  原文链接:https://mp.weixin.qq.com/s/JKa99sPD8iVkvxL1Rwv6nA

心上立起一枚太阳,相信世间所有的温暖,都是与人为善的心意当你内心走向良善时,你将停止批评别人和对别人的批评产生反弹。如果你对一颗长满苹果的树木丢石头,掉下来的就只会是苹果,不管谁丢都一样。一个真正良善的人,不管你对他怎么样,他显现出来的奔驰,因螺栓相关问题再次召回,我们需要了解什么?日前,梅赛德斯奔驰(中国)汽车销售有限公司根据缺陷汽车产品召回管理条例和缺陷汽车产品召回管理条例实施办法的要求,向国家市场监督管理总局备案了召回计划,计划召回以下车辆。一自2022徐向前元帅的三条遗嘱中央为何只采用了一条文史真布衣元帅徐向前一生以低调谦逊简朴廉洁等优秀品格著称于世,这缘自他矢志不渝追求真理,坚持共产主义信仰不动摇,朴素而执着。如果说敬业守拙的素质彪炳千秋的功业高风亮节的品格是布衣元接连被岸田羞辱,尹锡悦还坚持对日本大妥协,能成功吗?我认为应该通过一场大妥协,面向未来地解决问题。近日,韩国方面公布了尹锡悦对韩日关系的最新表态。为了推动韩日和解,让韩国早日融入美国的印太圈子,尹锡悦可谓是煞费苦心。不过从日本方面的细节满分!火箭迎利好消息,伊森身材大走样,三大联赛大展拳脚北京时间8月31日,根据休斯顿火箭最新消息,目前已经有大部分球员自发开启休赛期的特训,其中就包括了杰伦格林贾巴里史密斯伊森泰泰华盛顿戈登等球员,在细节方面,确实火箭这批年轻球员太让AC米兰多亏有位好门将,联赛不败金身险些被克星打破要论近几年意甲赛场上AC米兰惧怕的对手,亚特兰大算一个,萨索洛也一样应该是榜上有名,这支有着意甲小巴萨别称的球队虽然整体战绩称不上惊艳,但每每遇到AC米兰的时候,他们总能有好的发挥胡安兄弟助西班牙夺冠,NBA却很失意!威少有进军娱乐圈潜质在欧锦赛决赛中,西班牙队力克法国队夺冠,同时这也是他们第四次捧起冠军奖杯。不仅如此,西班牙男篮自2006年来已经在三大国际大赛中赢得12枚奖牌,其中4枚欧锦赛金牌2枚银牌和1枚铜牌篮坛多消息汇总,欧锦赛西班牙夺冠,郭艾伦完成续约回归辽宁北京时间2022年9月20日,我们继续关注篮坛最新资讯。欧锦赛随着西班牙夺冠也画上了圆满的句号,埃尔南戈麦斯获得MVP殊荣,德国战胜波兰获得第三名。欧锦赛官宣最佳阵容,其中包括施罗中小学语文现代文阅读教程(下)张士连作文指导连载第五章理清说明顺序第一百零九课理清说明的逻辑顺序网络图片逻辑顺序,又叫事理顺序。说明事理的说明文,适于采用逻辑顺序。所谓的逻辑顺序,也就是按照事物内部的联系,或者人们认识事物的规律泰达新材成北交所首例IPO被否案例交易所指出三大关键问题21世纪经济报道记者雷晨实习生黎雨辰北京报道9月19日,根据北交所上市委2022年第43次审议会议结果,安徽泰达新材料股份有限公司(下称泰达新材)IPO上会被否,成为北交所首家上会长沙大火,烧出一个摩天大楼真相文熊猫的熊长沙大火,触目惊心。幸好疏散及时,事故没有造成人员伤亡,但相信看过现场视频的人,都会感到无比后怕,在明火扑灭后,偌大的一座大楼,变得残破不堪了。公开信息显示,此次起火的长
福利!全民乡音诵读大赛送购书卡,还有荣誉证书拿一段温暖的家乡乡音,诵读着自己喜欢的诗篇,也传递着自己最真诚的新年愿景。由湖南新华书店集团与潇湘晨报联合发起的港家乡话,读家乡书新华书店杯全民乡音诵读大赛正在如火如荼地举行中,在网手写福字庆新春新年到,手写万家福字,与大家一起庆祝新春啦!海关发布在这里祝福所有的粉丝和网友们新年大吉,万事顺遂,兔年行大运!同沐春风花满地,共迎新岁喜盈门。天津新港海关祝大家新春快乐,兔年大吉我,80后毁容女孩,北漂11年身家千万,学历和容貌真不是最重要的这是我们讲述的第1471位真人故事一夜回到解放前。老陈望着眼前的一大堆货物,一边叹气一边说道。2014年,因为生意失败,我先生老陈亏损了200万,还欠了100多万的债务,一度陷入颓我90后,当了3年空姐,发现工资没想象中高,连口臭都会被投诉这是我们讲述的第1462位真人故事我是Dani黑珍珠Dani,90后。我练过跆拳道,后来成为一名芭蕾舞老师,一个月能挣一万多。可是,我却厌倦了这一成不变的生活,在机缘巧合下,很轻松剧情反转!曝李铁已全招供,信息或指向背后更高层前段时间媒体人李平康透露李铁落网60天左右,基本没供出什么人来,这个消息当时被曝出时,引起了较大的争议。那个时候我们分析过李铁要么就是不知道供谁出来,要么就是想保护背后的大鱼。但根2023中国网络视听年度盛典唱响同根同源中华情,声生不息展现动人羁绊古今如一龙凤凰,黑眼黑发真善良先人是炎黄,子孙血一样大年初三,奋进新征程2023中国网络视听年度盛典(以下简称盛典)上线播出,在任贤齐陈小春林峯张淇杨丞琳刘惜君等歌手的走心演绎下,新春走基层丨摆进了夜市成了供货商一家土特产小店的年终总结新华社长沙1月25日电题摆进了夜市成了供货商一家土特产小店的年终总结新华社记者周勉从除夕到大年初三这短短几天,湖南省益阳市南县乌嘴乡罗文村村民刘丹陈英夫妇的土特产小店一共卖出了10美国前副总统彭斯私宅发现十几份机密文件据美国有线电视新闻网(CNN)当地时间1月24日援引多名知情人士报道,美国前副总统迈克彭斯的律师上周在彭斯位于印第安纳州的家中发现了大约十几份被标记为机密的文件,他已将这些机密记录看无名爸妈被黄磊二次圈粉,不当厨子的帅哥才是好演员随着电影无名的上映观众口碑陆续出炉,好评如潮。评论中说的最多的就是带感。的确,走心的拍摄,反转的剧情,唯美的镜头,动人的演技,叠加起来,就是一部出彩的优质电影,无名做到了!而且,纵若是美国彻底撕破伪装,敢联合北约硬刚俄罗斯吗自俄罗斯在乌克兰展开特别军事行动以来,战斗已经持续了三百多天。在这三百多天的战斗中,俄罗斯并没有像预想中那样快速拿下基辅,彻底解决乌克兰问题,反而在乌克兰打成了持久战,让全世界都感奇葩又搞笑网友们的春节咋和我的不一样?视频加载中又是一年春节,我们带着礼物备足年货,领着爱人和孩子踏上了返乡回家的旅途。和亲友们久别重逢开怀畅饮放声歌唱欢快玩耍之时又发生了很多奇葩搞笑的意外难忘时刻。孙儿喊爷爷给他磕头