搜索
bottom↓
回复: 56

对结构体的理解:从STM32的库函数到51

  [复制链接]

出0入0汤圆

发表于 2014-4-8 23:08:20 | 显示全部楼层 |阅读模式
本帖最后由 磊磊映画 于 2014-4-8 23:16 编辑

1.对STM32的库函数学习了一段时间,之前一直都是51,还有AVR,别的没接触过,AVR上都没用用到结构体
所以以前用C语言都是很简单的,直到32上,涉及到了结构体,看了很多遍,理解的都不是很透彻,所以今天写了这个代码,很简单
通过结构体初始化51单片机的定时器1通过串口发送数据 0x7f 程序可用
2.从初始化51串口的角度看,这个程序是没有意义的,但是对于刚从51转到STM32的应该有帮助吧//STM32中的结构体基本是这么用的
3.程序写的不好,很简单,主要是理解结构体,我感觉他很复杂,用STM32的库感觉吃力
4.STM32中为什么用结构体的原因在这里没有说:主要是结构体方便后续扩充变量,因为函数指向的是结构体的首地址。而不是增加传递函数的个数
5.欢迎大神指导,大家一起交流学习!
  1. #include <reg52.h>

  2. #define u8 unsigned char
  3. #define u16 unsigned int

  4. /****************************
  5. 一。把我们要初始化的变量比作是车
  6. 把变量的值比作是货物
  7. 使用结构体就是为了把货物装入车中。
  8. 1.定义了一个结构体Com ,注意结构体属于用户自定义的变量类型     //准备好车
  9. 2.为了把货整齐的装入车中,定义了一个Com类型的结构体uart             //准备好货
  10. 3.Com就是车,uart其实是货物,到这应该明白点了                                             
  11. 4.最后一步把货物装到车中                                                                                     //把货物装到车中
  12. 通过函数void Com_Value(Com* msg)实现
  13. 二。关于结构体的基础知识
  14. 1.结构体可以是不同种变量的组合
  15. 2.①可以通过结构体变量名字.成员名  引用成员变量
  16.   ②可以通过结构体指针—>成员变量    引用成员变量



  17. ******************************/
  18. /*
  19. author:zhanglei
  20. time:2014-4-8 21:38:50
  21. explain: 定义名字是Com的结构体
  22. */
  23. typedef struct
  24. {
  25.    u8 scon;
  26.    u8 pcon;
  27.    /*
  28.    1.结构体变量列表
  29.    2.变量可以是不同的类型
  30.    */
  31.    u8 ren;
  32.    u8 tmod;
  33.    u8 th;
  34.    u8 tl;
  35.    u8 tr;

  36. } Com;
  37. void delayms(unsigned char i)
  38. {
  39.     unsigned char j;
  40.     for(;i>0;i--)
  41.         {
  42.           for(j=0;j<200;j++);
  43.         }




  44. }
  45. /*
  46. 函数名:Com_Value
  47. 注意:在入口参数中,定义了Com结构体指针 msg
  48. */

  49. void Com_Value(Com* msg)
  50. {
  51.    SCON=msg->scon;                //串口方式1
  52.    PCON=msg->pcon;                     //SMOD=0
  53.    REN=msg->ren;                     //允许接收
  54.    TMOD=msg->tmod;                //定时器1定时方式2
  55.    TH1=msg->th;                //11.0592M 9600波特率
  56.    TL1=msg->tl;
  57.    TR1=msg->tr;                  //启动定时器  

  58. }
  59. /*
  60. function:初始化串口
  61. 定义Com类型的结构体uart
  62. 并初始化结构体内的变量

  63. */

  64. void Com_Init(void)
  65. {

  66.     Com uart;
  67.     uart.scon=0x40;                //串口方式1
  68.     uart.pcon=0;                     //SMOD=0
  69.     uart.ren=1;                //定时器1定时方式2
  70.     uart.tmod=0x20;
  71.     uart.th=0xfd;                //11.0592M 9600波特率
  72.     uart.tl=0xfd;
  73.     uart.tr=1;                  //启动定时器   
  74.         Com_Value(&uart);  //初始化定时器1
  75. }



  76. void main(void)
  77. {

  78.         Com_Init();//初始化串口
  79.         while(1)
  80.         {

  81.           SBUF=0x7f;
  82.       while(TI==0);
  83.       TI=0;
  84.           delayms(100);


  85.         }






  86. }
复制代码

出0入0汤圆

发表于 2014-4-8 23:11:04 | 显示全部楼层
答对了,用上了结构体,说明C进了一步,再把结构体无限套下去,结构体套自己,父套子,子套孙;再搞搞函数指针,满屏指针飞,满屏结构体指针指来指去!说明你已经非人了;

:)

出0入0汤圆

 楼主| 发表于 2014-4-8 23:13:56 | 显示全部楼层
kinsno 发表于 2014-4-8 23:11
答对了,用上了结构体,说明C进了一步,再把结构体无限套下去,结构体套自己,父套子,子套孙;再搞搞函数 ...

嘿嘿 ,我就是个刚入门的硬件工程师  学习学习

出0入0汤圆

发表于 2014-4-9 08:22:30 | 显示全部楼层
  1. unsigned char read_key_n(void)
  2. {
  3.         static unsigned char key_state = 0, key_time = 0;
  4.         unsigned char key_press, key_return = 0;

  5.         key_press = key_input;                                // 读按键I/O电平
  6.         switch (key_state)
  7.         {
  8.                 case key_state_0:                                // 按键初始态
  9.                         if (!key_press) key_state = key_state_1;        // 键被按下,状态转换到键确认态
  10.                         break;
  11.                 case key_state_1:                                // 按键确认态
  12.                         if (!key_press)
  13.             {
  14.                 key_state = key_state_2;        // 按键仍按下,状态转换到计时1
  15.                 key_time = 0;                                // 清另按键时间计数器
  16.             }
  17.                         else
  18.                             key_state = key_state_0;        // 按键已抬起,转换到按键初始态
  19.                         break;
  20.                 case key_state_2:
  21.                         if (key_press)
  22.             {
  23.                 key_state = key_state_0;        // 按键已释放,转换到按键初始态
  24.                 key_return = 1;                        // 输出"1"
  25.                         }
  26.                         else if (++key_time >= 200)                // 按键时间计数
  27.                         {
  28.                                 key_state = key_state_3;        // 按下时间>1s,状态转换到计时2
  29.                                 key_time = 0;                                // 清按键计数器
  30.                                 key_return = 2;                        // 输出"2"
  31.                         }
  32.                         break;
  33.                 case key_state_3:
  34.                         if (key_press)
  35.                         {
  36.                 key_state = key_state_0; //按键已释放,转换到按键初始态
  37.                         }
  38.             break;
  39.         }       
  40.     return key_return;
  41. }
复制代码


嘿嘿,按也试试代码是怎么弄进去的

出0入0汤圆

发表于 2014-4-9 08:23:07 | 显示全部楼层
靠,爽极了

出0入0汤圆

发表于 2014-4-9 08:27:23 | 显示全部楼层
指针,队列,表,树,内存管理。。。

出0入0汤圆

发表于 2014-4-9 09:02:54 | 显示全部楼层
对于代码空间小的单片机还是老实用直接寄存器操作吧,免得代码空间不足.

出0入0汤圆

 楼主| 发表于 2014-4-9 11:37:29 | 显示全部楼层
cqfeiyu 发表于 2014-4-9 09:02
对于代码空间小的单片机还是老实用直接寄存器操作吧,免得代码空间不足.

恩恩 主要是有51基础的用来研究结构体

出0入0汤圆

 楼主| 发表于 2014-4-9 11:39:33 | 显示全部楼层
Excellence 发表于 2014-4-9 08:27
指针,队列,表,树,内存管理。。。

状态机  ucos2   你说的这些我都听说过还不会用,现在正从结构体入手,进一步学习 ,求指导!

出0入0汤圆

发表于 2014-4-12 14:51:13 | 显示全部楼层
不懂饿。

出0入0汤圆

发表于 2014-4-12 15:12:27 | 显示全部楼层
我也是刚接触,感觉很吃力

出0入0汤圆

发表于 2014-4-12 16:13:29 | 显示全部楼层
STM32的结构体意味其实更加深远,不仅仅是把东西塞到结构体里面了。

出0入0汤圆

 楼主| 发表于 2014-4-12 17:12:01 | 显示全部楼层
dongfo 发表于 2014-4-12 16:13
STM32的结构体意味其实更加深远,不仅仅是把东西塞到结构体里面了。

就像正点原子刘军在书中说的,结构体的有点不只是容易扩充变量,优点还有很多啊   我感觉结构体深不可测啊

出0入0汤圆

发表于 2014-4-12 20:28:58 | 显示全部楼层
指针是个好东西

出0入0汤圆

发表于 2014-4-13 09:53:34 | 显示全部楼层
不错,看看Linux的内核,各种的链表,枚举

出0入0汤圆

 楼主| 发表于 2014-4-13 15:47:10 | 显示全部楼层
caiseyuzhou 发表于 2014-4-13 09:53
不错,看看Linux的内核,各种的链表,枚举

哦 ,好的,1.linux跟我写的这些都是相通的吗?
               2.openwrt   你听过吗 我不知道它能干什么或者说我还不了解服务器能干什么?对于单片机来说
谢谢!

出0入0汤圆

发表于 2014-4-13 17:34:15 | 显示全部楼层
谁说内存小就不能用结构体了?
又不是所有的东西都要调到内存里面去,反正配置信息写到最后只有const才是有意义的,为啥要写到内存里面?

出0入0汤圆

发表于 2014-4-13 23:32:58 | 显示全部楼层
error_dan 发表于 2014-4-13 17:34
谁说内存小就不能用结构体了?
又不是所有的东西都要调到内存里面去,反正配置信息写到最后只有const才是有 ...

就是,只占用了代码空间。

出0入0汤圆

 楼主| 发表于 2014-11-3 16:33:54 | 显示全部楼层
xiaobendan 发表于 2014-4-9 08:22
嘿嘿,按也试试代码是怎么弄进去的

状态机啊,厉害啊

出0入0汤圆

发表于 2014-11-3 17:18:06 | 显示全部楼层

哈哈,是拷贝的论坛上的,说实话,我还真没有用过这段代码,不过我用的,也差不多是类似的

出0入0汤圆

 楼主| 发表于 2014-11-3 17:22:27 | 显示全部楼层
xiaobendan 发表于 2014-11-3 17:18
哈哈,是拷贝的论坛上的,说实话,我还真没有用过这段代码,不过我用的,也差不多是类似的 ...

对于状态机与ucos2 如何结合使用,你能讲讲吗?   用代码功能是不是感觉高大上了

出0入0汤圆

发表于 2014-11-3 17:29:53 | 显示全部楼层
磊磊映画 发表于 2014-11-3 17:22
对于状态机与ucos2 如何结合使用,你能讲讲吗?   用代码功能是不是感觉高大上了 ...

UCOS没用过,目前都是小东西,全部是裸奔的了
代码功能很好,漂亮,清晰,易读

出0入0汤圆

发表于 2014-11-4 22:29:23 来自手机 | 显示全部楼层
楼主分析很到位,赞一个

出0入0汤圆

 楼主| 发表于 2014-11-5 09:37:14 | 显示全部楼层
fancyboy 发表于 2014-11-4 22:29
楼主分析很到位,赞一个

谢谢,我觉得给51转型stm32的人看最适合了

出0入0汤圆

发表于 2014-11-5 11:33:54 | 显示全部楼层
楼主写的结构体很通俗易懂,确实是51升级STM32必走的

出0入0汤圆

 楼主| 发表于 2014-11-5 12:48:24 | 显示全部楼层
nanoha2009 发表于 2014-11-5 11:33
楼主写的结构体很通俗易懂,确实是51升级STM32必走的

谢谢

出0入0汤圆

发表于 2014-11-6 15:57:09 | 显示全部楼层
写得非常好,谢谢

出0入0汤圆

 楼主| 发表于 2014-11-6 19:52:38 | 显示全部楼层
xqn2012 发表于 2014-11-6 15:57
写得非常好,谢谢

共同学习,共同进步

出0入0汤圆

发表于 2014-11-6 21:16:38 | 显示全部楼层
楼主的学习方法值得借鉴

出0入0汤圆

 楼主| 发表于 2014-11-6 22:58:25 | 显示全部楼层
proc 发表于 2014-11-6 21:16
楼主的学习方法值得借鉴

搞软件的就喜欢封装,封装库 API

出0入0汤圆

发表于 2014-11-7 08:54:57 | 显示全部楼层
本帖最后由 slzm40 于 2014-11-7 08:56 编辑

再用上联合体,枚举等,代码封封装性更进一步了。
在飞上指针,函数指针,结构体指针,就更爽了
再来队列,树,栈,链表。我觉得还是看高端的源码好。比如接近51的,Zstack, ucos2等, 学习很多的。

个人觉得,小RAM的还是直接操作好。 大的RAM,随便上,封装越好,层次分明,看的也明白

出0入0汤圆

发表于 2014-11-13 11:40:19 | 显示全部楼层
对像我这种刚从51转STM32的人   相当有用

出0入0汤圆

 楼主| 发表于 2014-11-13 11:43:28 | 显示全部楼层
四驱兄弟 发表于 2014-11-13 11:40
对像我这种刚从51转STM32的人   相当有用

谢谢,是啊,我当时转的时候也很纠结,什么都不懂,如果当时我能看到这些,应该也会好很多,至少脉络清晰了

出0入0汤圆

发表于 2014-11-18 23:36:10 | 显示全部楼层
mark 结构体.....

出0入0汤圆

发表于 2015-1-7 15:06:08 | 显示全部楼层
LZ 看了对结构体了解了不少  收下了

出0入0汤圆

发表于 2015-8-30 12:18:05 | 显示全部楼层
收获良多  非常感谢

出0入0汤圆

 楼主| 发表于 2015-8-30 12:41:03 | 显示全部楼层
xofun 发表于 2015-8-30 12:18
收获良多  非常感谢

谢谢,共同学习共同进步

出0入0汤圆

发表于 2015-8-30 15:20:15 | 显示全部楼层
stm32配合了每个外设的连续寄存器地址,库函数中的结构体用得很巧妙。
楼主加油,,,

出0入0汤圆

发表于 2015-8-31 09:10:29 | 显示全部楼层
楼主这种比喻很好懂  

出0入0汤圆

 楼主| 发表于 2015-8-31 10:28:34 | 显示全部楼层
tt98 发表于 2015-8-31 09:10
楼主这种比喻很好懂

之前遇到过一个大师,把模电讲的深入浅出,让我收益匪浅

出0入0汤圆

发表于 2015-8-31 12:46:29 | 显示全部楼层
感觉楼主的举得例子没有我理解的好,可能每个人理解不同吧,呵呵...

出0入0汤圆

发表于 2015-8-31 23:22:27 | 显示全部楼层
一直害怕指针和结构体之类的我,不知下面的理解对不对?
用了typedef之后,Com就是个定义的结构体类型名,而不是结构体变量名吧?后边的uart才是声明的 Com类型的结构体变量。

出0入0汤圆

 楼主| 发表于 2015-9-1 09:23:50 | 显示全部楼层
chengyang79 发表于 2015-8-31 23:22
一直害怕指针和结构体之类的我,不知下面的理解对不对?
用了typedef之后,Com就是个定义的结构体类型名, ...

对的,结构体是C语言中,用户自定义的变量类型。Com就是自定义的结构体类型   uart是声明的结构体变量,通过"."或“->”访问的是结构体变量的成员

出0入0汤圆

发表于 2015-9-13 22:20:07 | 显示全部楼层
磊磊牛逼,我才刚接触STM32。

出0入0汤圆

 楼主| 发表于 2015-9-13 22:23:29 | 显示全部楼层
WM_CH 发表于 2015-9-13 22:20
磊磊牛逼,我才刚接触STM32。

long time no  see  51搞懂了,32不是问题

出0入0汤圆

发表于 2015-9-13 22:26:40 | 显示全部楼层
磊磊映画 发表于 2015-8-31 10:28
之前遇到过一个大师,把模电讲的深入浅出,让我收益匪浅

什么大师,哪个?

出0入0汤圆

 楼主| 发表于 2015-9-13 22:46:40 | 显示全部楼层
WM_CH 发表于 2015-9-13 22:26
什么大师,哪个?

有一次参加培训遇到的一个老师,石家庄铁道大学电子系的吴秋瑞教授 讲东西深入浅出,受益匪浅

出0入0汤圆

发表于 2015-9-14 15:59:27 | 显示全部楼层
感谢楼主的分享1

出0入0汤圆

发表于 2016-10-9 20:38:43 | 显示全部楼层
好家伙。不错,不错!

出50入0汤圆

发表于 2016-10-9 20:52:51 来自手机 | 显示全部楼层
多谢分享

出0入0汤圆

发表于 2018-2-15 23:29:44 | 显示全部楼层
多谢分享

出20入0汤圆

发表于 2018-3-15 13:15:11 | 显示全部楼层
楼主威武,本人正在从51转STM32,正在看HAL库。

出0入0汤圆

发表于 2018-4-20 22:05:41 | 显示全部楼层
结构体很难理解,谢谢楼主

出20入0汤圆

发表于 2018-5-3 21:45:51 | 显示全部楼层
感谢楼主无私分享

出0入0汤圆

发表于 2018-5-3 22:01:34 | 显示全部楼层
写的不错。
但是提醒楼主一点,结构体也好、直接寄存器操作也好,这些都只是工具而已,单纯的炫技不见得能带来多大的收益,有时工具掌握不好反而会带来额外的麻烦,适度就好。
另外,代码的核心目标是实现功能、稳定运行,而不是代码多炫目,特别是在一些功能比较简单的系统上。
一点拙见。

出0入0汤圆

发表于 2018-7-31 09:17:55 | 显示全部楼层
本帖最后由 YUZH282 于 2018-7-31 09:28 编辑

楼主你好,void Com_Value(Com* msg)这个函数是如何调用的,调用时void Com_Value(?)问号里写什么?请解答一下好吗?我在用,老说我的类型不对。找到问题了,基础不扎实呀,void Com_Value(&uart)

出0入0汤圆

 楼主| 发表于 2018-7-31 09:54:00 | 显示全部楼层
YUZH282 发表于 2018-7-31 09:17
楼主你好,void Com_Value(Com* msg)这个函数是如何调用的,调用时void Com_Value(?)问号里写什么?请解答 ...

函数注释那写着呢    Com类型的结构体指针 msg  
/*
函数名:Com_Value
注意:在入口参数中,定义了Com结构体指针 msg
*/
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-18 16:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表