对结构体的理解:从STM32的库函数到51
本帖最后由 磊磊映画 于 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.欢迎大神指导,大家一起交流学习!
#include <reg52.h>
#define u8 unsigned char
#define u16 unsigned int
/****************************
一。把我们要初始化的变量比作是车
把变量的值比作是货物
使用结构体就是为了把货物装入车中。
1.定义了一个结构体Com ,注意结构体属于用户自定义的变量类型 //准备好车
2.为了把货整齐的装入车中,定义了一个Com类型的结构体uart //准备好货
3.Com就是车,uart其实是货物,到这应该明白点了
4.最后一步把货物装到车中 //把货物装到车中
通过函数void Com_Value(Com* msg)实现
二。关于结构体的基础知识
1.结构体可以是不同种变量的组合
2.①可以通过结构体变量名字.成员名引用成员变量
②可以通过结构体指针—>成员变量 引用成员变量
******************************/
/*
author:zhanglei
time:2014-4-8 21:38:50
explain: 定义名字是Com的结构体
*/
typedef struct
{
u8 scon;
u8 pcon;
/*
1.结构体变量列表
2.变量可以是不同的类型
*/
u8 ren;
u8 tmod;
u8 th;
u8 tl;
u8 tr;
} Com;
void delayms(unsigned char i)
{
unsigned char j;
for(;i>0;i--)
{
for(j=0;j<200;j++);
}
}
/*
函数名:Com_Value
注意:在入口参数中,定义了Com结构体指针 msg
*/
void Com_Value(Com* msg)
{
SCON=msg->scon; //串口方式1
PCON=msg->pcon; //SMOD=0
REN=msg->ren; //允许接收
TMOD=msg->tmod; //定时器1定时方式2
TH1=msg->th; //11.0592M 9600波特率
TL1=msg->tl;
TR1=msg->tr; //启动定时器
}
/*
function:初始化串口
定义Com类型的结构体uart
并初始化结构体内的变量
*/
void Com_Init(void)
{
Com uart;
uart.scon=0x40; //串口方式1
uart.pcon=0; //SMOD=0
uart.ren=1; //定时器1定时方式2
uart.tmod=0x20;
uart.th=0xfd; //11.0592M 9600波特率
uart.tl=0xfd;
uart.tr=1; //启动定时器
Com_Value(&uart);//初始化定时器1
}
void main(void)
{
Com_Init();//初始化串口
while(1)
{
SBUF=0x7f;
while(TI==0);
TI=0;
delayms(100);
}
} 答对了,用上了结构体,说明C进了一步,再把结构体无限套下去,结构体套自己,父套子,子套孙;再搞搞函数指针,满屏指针飞,满屏结构体指针指来指去!说明你已经非人了;
:) kinsno 发表于 2014-4-8 23:11
答对了,用上了结构体,说明C进了一步,再把结构体无限套下去,结构体套自己,父套子,子套孙;再搞搞函数 ...
嘿嘿 ,我就是个刚入门的硬件工程师学习学习 unsigned char read_key_n(void)
{
static unsigned char key_state = 0, key_time = 0;
unsigned char key_press, key_return = 0;
key_press = key_input; // 读按键I/O电平
switch (key_state)
{
case key_state_0: // 按键初始态
if (!key_press) key_state = key_state_1; // 键被按下,状态转换到键确认态
break;
case key_state_1: // 按键确认态
if (!key_press)
{
key_state = key_state_2; // 按键仍按下,状态转换到计时1
key_time = 0; // 清另按键时间计数器
}
else
key_state = key_state_0; // 按键已抬起,转换到按键初始态
break;
case key_state_2:
if (key_press)
{
key_state = key_state_0; // 按键已释放,转换到按键初始态
key_return = 1; // 输出"1"
}
else if (++key_time >= 200) // 按键时间计数
{
key_state = key_state_3; // 按下时间>1s,状态转换到计时2
key_time = 0; // 清按键计数器
key_return = 2; // 输出"2"
}
break;
case key_state_3:
if (key_press)
{
key_state = key_state_0; //按键已释放,转换到按键初始态
}
break;
}
return key_return;
}
嘿嘿,按也试试代码是怎么弄进去的 靠,爽极了 指针,队列,表,树,内存管理。。。 对于代码空间小的单片机还是老实用直接寄存器操作吧,免得代码空间不足. cqfeiyu 发表于 2014-4-9 09:02
对于代码空间小的单片机还是老实用直接寄存器操作吧,免得代码空间不足.
恩恩 主要是有51基础的用来研究结构体 Excellence 发表于 2014-4-9 08:27
指针,队列,表,树,内存管理。。。
状态机ucos2 你说的这些我都听说过还不会用,现在正从结构体入手,进一步学习 ,求指导! 不懂饿。 我也是刚接触,感觉很吃力 STM32的结构体意味其实更加深远,不仅仅是把东西塞到结构体里面了。 dongfo 发表于 2014-4-12 16:13
STM32的结构体意味其实更加深远,不仅仅是把东西塞到结构体里面了。
就像正点原子刘军在书中说的,结构体的有点不只是容易扩充变量,优点还有很多啊 我感觉结构体深不可测啊 指针是个好东西 不错,看看Linux的内核,各种的链表,枚举 caiseyuzhou 发表于 2014-4-13 09:53
不错,看看Linux的内核,各种的链表,枚举
哦 ,好的,1.linux跟我写的这些都是相通的吗?
2.openwrt 你听过吗 我不知道它能干什么或者说我还不了解服务器能干什么?对于单片机来说
谢谢! 谁说内存小就不能用结构体了?
又不是所有的东西都要调到内存里面去,反正配置信息写到最后只有const才是有意义的,为啥要写到内存里面? error_dan 发表于 2014-4-13 17:34
谁说内存小就不能用结构体了?
又不是所有的东西都要调到内存里面去,反正配置信息写到最后只有const才是有 ...
就是,只占用了代码空间。 xiaobendan 发表于 2014-4-9 08:22
嘿嘿,按也试试代码是怎么弄进去的
状态机啊,厉害啊 磊磊映画 发表于 2014-11-3 16:33
状态机啊,厉害啊
哈哈,是拷贝的论坛上的,说实话,我还真没有用过这段代码,不过我用的,也差不多是类似的 xiaobendan 发表于 2014-11-3 17:18
哈哈,是拷贝的论坛上的,说实话,我还真没有用过这段代码,不过我用的,也差不多是类似的 ...
对于状态机与ucos2 如何结合使用,你能讲讲吗? 用代码功能是不是感觉高大上了 磊磊映画 发表于 2014-11-3 17:22
对于状态机与ucos2 如何结合使用,你能讲讲吗? 用代码功能是不是感觉高大上了 ...
UCOS没用过,目前都是小东西,全部是裸奔的了
代码功能很好,漂亮,清晰,易读 楼主分析很到位,赞一个 fancyboy 发表于 2014-11-4 22:29
楼主分析很到位,赞一个
谢谢,我觉得给51转型stm32的人看最适合了 楼主写的结构体很通俗易懂,确实是51升级STM32必走的 nanoha2009 发表于 2014-11-5 11:33
楼主写的结构体很通俗易懂,确实是51升级STM32必走的
谢谢{:smile:} 写得非常好,谢谢 xqn2012 发表于 2014-11-6 15:57
写得非常好,谢谢
共同学习,共同进步 楼主的学习方法值得借鉴 proc 发表于 2014-11-6 21:16
楼主的学习方法值得借鉴
搞软件的就喜欢封装,封装库 API
。
本帖最后由 slzm40 于 2014-11-7 08:56 编辑再用上联合体,枚举等,代码封封装性更进一步了。
在飞上指针,函数指针,结构体指针,就更爽了
再来队列,树,栈,链表。我觉得还是看高端的源码好。比如接近51的,Zstack, ucos2等, 学习很多的。
个人觉得,小RAM的还是直接操作好。 大的RAM,随便上,封装越好,层次分明,看的也明白 对像我这种刚从51转STM32的人 相当有用 四驱兄弟 发表于 2014-11-13 11:40
对像我这种刚从51转STM32的人 相当有用
谢谢,是啊,我当时转的时候也很纠结,什么都不懂,如果当时我能看到这些,应该也会好很多,至少脉络清晰了 mark 结构体..... LZ 看了对结构体了解了不少收下了 收获良多非常感谢 xofun 发表于 2015-8-30 12:18
收获良多非常感谢
谢谢,共同学习共同进步 stm32配合了每个外设的连续寄存器地址,库函数中的结构体用得很巧妙。
楼主加油,,, 楼主这种比喻很好懂{:titter:} tt98 发表于 2015-8-31 09:10
楼主这种比喻很好懂
之前遇到过一个大师,把模电讲的深入浅出,让我收益匪浅 感觉楼主的举得例子没有我理解的好,可能每个人理解不同吧,呵呵... 一直害怕指针和结构体之类的我,不知下面的理解对不对?
用了typedef之后,Com就是个定义的结构体类型名,而不是结构体变量名吧?后边的uart才是声明的 Com类型的结构体变量。 chengyang79 发表于 2015-8-31 23:22
一直害怕指针和结构体之类的我,不知下面的理解对不对?
用了typedef之后,Com就是个定义的结构体类型名, ...
对的,结构体是C语言中,用户自定义的变量类型。Com就是自定义的结构体类型 uart是声明的结构体变量,通过"."或“->”访问的是结构体变量的成员 磊磊牛逼,我才刚接触STM32。 WM_CH 发表于 2015-9-13 22:20
磊磊牛逼,我才刚接触STM32。
long time nosee51搞懂了,32不是问题 磊磊映画 发表于 2015-8-31 10:28
之前遇到过一个大师,把模电讲的深入浅出,让我收益匪浅
什么大师,哪个? WM_CH 发表于 2015-9-13 22:26
什么大师,哪个?
有一次参加培训遇到的一个老师,石家庄铁道大学电子系的吴秋瑞教授 讲东西深入浅出,受益匪浅 感谢楼主的分享1 好家伙。不错,不错! 多谢分享 多谢分享 楼主威武,本人正在从51转STM32,正在看HAL库。 结构体很难理解,谢谢楼主
感谢楼主无私分享 写的不错。
但是提醒楼主一点,结构体也好、直接寄存器操作也好,这些都只是工具而已,单纯的炫技不见得能带来多大的收益,有时工具掌握不好反而会带来额外的麻烦,适度就好。
另外,代码的核心目标是实现功能、稳定运行,而不是代码多炫目,特别是在一些功能比较简单的系统上。
一点拙见。
本帖最后由 YUZH282 于 2018-7-31 09:28 编辑
楼主你好,void Com_Value(Com* msg)这个函数是如何调用的,调用时void Com_Value(?)问号里写什么?请解答一下好吗?我在用,老说我的类型不对。找到问题了,基础不扎实呀,void Com_Value(&uart) YUZH282 发表于 2018-7-31 09:17
楼主你好,void Com_Value(Com* msg)这个函数是如何调用的,调用时void Com_Value(?)问号里写什么?请解答 ...
函数注释那写着呢 Com类型的结构体指针 msg
/*
函数名:Com_Value
注意:在入口参数中,定义了Com结构体指针 msg
*/
页:
[1]