当前位置:   article > 正文

Keil + STM32学习嵌入式数据结构-01_stm32 数据结构

stm32 数据结构

 视频链接

初识数据结构,十天搞定嵌入式数据结构_哔哩哔哩_bilibili

课程目的

学会嵌入式经常使用的数据结构

具备基础知识 

具有C语言基础结构体、指针、内存(malloc))

具有数据结构的基础知识,因此提及到的基础知识比较少

嵌入式数据结构的实现基本上基于结构体 ,在FreeRTOS的源码中体现的很清楚,基本上都是结构体,或者为了描述一个东西(数据)的属性时(数据元素--数据的基本单位)你需要使用结构体,比如学生的成绩、排名、姓名等

学习方法

以分析FreeRTOS中内部存在的数据结构来学习嵌入式数据结构,数据结构在操作系统中体现的淋漓尽致,因此当你分析完FreeRTOS中数据结构的算法后,你就具备了嵌入式数据结构的基础。嵌入式的数据结构内容不是特别的多,因为有些数据结构很少使用到

代码量决定你的能力提升范围

数据结构的作用

让数据的处理更加高效、灵活,使用起来更方便,为了满足更多的情况

数据的逻辑结构

线性、层次、网状,其实就是分线性和非线性结构(按照前趋数和后继数分类的),我们常见的并且使用最多的是线性结构(线性表、栈、队列)

数据的存储结构

如何把数据存储在内存(把内存想象成一个房子的房间)中,连续存储(数组-房间号连续)、非连续数组(链表--房间号不连续---用地址/指针建立连接)

数据结构意义

1:提高编程能力

2:提高程序的复用性、维护性、可读性

3:程序 = 数据结构 + 算法

什么是数据结构

数据结构 = 数据 + 结构(逻辑和存储)

数据和数据元素

 

 比如下面的属性就是数据元素,为了描述数据

 顺序存储

缺点:插入和删除不方便

优点:查找方便

根据处理的问题进行选择性的使用存储方式

 上图亮点在typedef int data_t中,因为我们的数据类型可以改变

last表示数组长度

顺序存储的使用

1:代码分层处理,把顺序存储分成.c和.h文件,如果别人需要使用我们的写的文件,我们给的是.h和.so文件(动态库)(由.c编译的二进制文件,防止别人知道源码实现,这个操作很常见,比如你不知道printf的源码时如何实现的,你只能打开stdio.h而不存在stdio.c)

2:在写代码的时候,要有代码架构思想,为了提高我们的代码复用性,可以很方便的给别人使用或者换一个场景也能很快使用

在C语言中,一般使用数组(结构体数组)表示顺序存储。因此我们使用结构体数组来点亮我们想要的LED灯---需要借助FreeRTOS的动态内存分配

  1. typedef struct Class LED_t ;
  2. #define N 5 //表示能装多少个LED灯
  3. struct Class
  4. {
  5. uint8_t Num;
  6. uint32_t RCC_CLOCK;
  7. GPIO_TypeDef * GPIOX;
  8. uint16_t GPIO_Pin;
  9. GPIOMode_TypeDef GPIO_Mode;
  10. GPIOSpeed_TypeDef GPIO_Speed;
  11. BitAction BitVal; //赋值电平
  12. const char *str;
  13. };
  14. typedef struct
  15. {
  16. LED_t LED_Data[N];
  17. uint16_t len;
  18. }sqlsitLED, *sqlinkLED;

顺序数组的操作

  1. /*
  2. * 创建顺序表
  3. */
  4. sqlinkLED List_Create()
  5. {
  6. sqlinkLED class;
  7. class = (sqlinkLED)pvPortMalloc(sizeof(sqlsitLED));
  8. if( class == NULL )
  9. {
  10. printf("List_Create is fail\r\n");
  11. return NULL;
  12. }
  13. else
  14. {
  15. printf("List_Create is sucess\r\n");
  16. memset(class->LED_Data , 0 , sizeof(LED_t)*N);
  17. class->len = 0;
  18. return class;
  19. }
  20. }
  21. /*
  22. * 清空顺序表 0--失败 1--成功
  23. */
  24. uint8_t Clear_List( sqlinkLED class )
  25. {
  26. if( class == NULL )
  27. return 0;
  28. memset(class->LED_Data , 0 , sizeof(LED_t)*N);
  29. class->len = 0;
  30. return 1;
  31. }
  32. /*
  33. * 判断顺序表是否为空 1--空 0--不为空
  34. */
  35. uint8_t List_empty( sqlinkLED class )
  36. {
  37. if(class->len == 0)
  38. return 1;
  39. return 0;
  40. }
  41. /*
  42. * 判断顺序表的长度
  43. */
  44. uint8_t List_length( sqlinkLED class )
  45. {
  46. if(class != NULL )
  47. {
  48. return class->len;
  49. }
  50. }

创建LED灯顺序表

  1. sqlinkLED LED;
  2. LED = List_Create();
  3.     if(LED == NULL )
  4.     {
  5.         printf("create list is fail\r\n");
  6.     }
  7.     else
  8.     {
  9.         printf("create list is sucess\r\n");
  10.     }

LED灯顺序表赋值

功能行驶函数

  1. void Give_ListValue( sqlinkLED class,uint8_t index )
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure;
  4. RCC_APB2PeriphClockCmd(class->LED_Data[index].RCC_CLOCK, ENABLE);
  5. GPIO_InitStructure.GPIO_Pin = class->LED_Data[index].GPIO_Pin;
  6. GPIO_InitStructure.GPIO_Mode = class->LED_Data[index].GPIO_Mode ;
  7. GPIO_InitStructure.GPIO_Speed = class->LED_Data[index].GPIO_Speed;
  8. GPIO_Init( class->LED_Data[index].GPIOX, &GPIO_InitStructure);
  9. GPIO_WriteBit(class->LED_Data[index].GPIOX, class->LED_Data[index].GPIO_Pin, class->LED_Data[index].BitVal);
  10. printf("%s\r\n",class->LED_Data[index].str);
  11. }
  1. LED->LED_Data[1].GPIOX = GPIOD;
  2. LED->LED_Data[1].BitVal = 0;
  3. LED->LED_Data[1].GPIO_Pin = GPIO_Pin_2;
  4. LED->LED_Data[1].GPIO_Mode = GPIO_Mode_Out_PP;
  5. LED->LED_Data[1].GPIO_Speed = GPIO_Speed_50MHz;
  6. LED->LED_Data[1].Num = 1;
  7. LED->LED_Data[1].str = "LED1";
  8. LED->LED_Data[1].RCC_CLOCK = RCC_APB2Periph_GPIOD;
  9. LED->len = 2;

 点亮LED

改变LED->LED_Data[1].BitVal 的值即可熄灭和点亮LED

Give_ListValue(LED, 1);

为其他数组赋值

  1. LED->LED_Data[0] = LED->LED_Data[1];
  2. printf("S%s\r\n",LED->LED_Data[1].str);

清零数组

 memset(&(LED->LED_Data[1]) , 0 , sizeof(LED_t));  

插入led数组

  1. /*
  2. * 插入一个LED_t类型的变量插入在数组中去,你需要考虑数组是否满了-插入位置是否合法---插入形式
  3. * pos是位置从1开始
  4. */
  5. uint8_t List_Insert( sqlinkLED class, LED_t led, uint8_t pos )
  6. {
  7. uint8_t i;
  8. //先判断有没有位置
  9. if(class->len == N)
  10. return 1; //表示满了
  11. //判断pos的值是否符合
  12. if(N < pos ) //不符合,没有这个数组下标
  13. return 1;
  14. //判断pos的值是否是最后一个
  15. if(N == pos)
  16. {
  17. class->LED_Data[pos-1] = led;
  18. class->len++;
  19. return 0;
  20. }
  21. //移动,空出pos的位置
  22. for( i=class->len-1;i>=pos;i--)
  23. class->LED_Data[i] = class->LED_Data[i-1] ;
  24. class->len++;
  25. return 0;
  26. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/219897
推荐阅读
相关标签
  

闽ICP备14008679号