搜索
bottom↓
回复: 9

请教C51 sbit定义的变量通过函数参数传递进函数内部的问题

[复制链接]

出0入0汤圆

发表于 2018-11-10 19:08:50 | 显示全部楼层 |阅读模式
本帖最后由 mangolu 于 2018-11-10 19:09 编辑

如题,是一个74HC595传送数据的函数,如下面:
  1. /** 定义DS数据端口连接 */
  2. sbit HC595_DS                = P2 ^ 1;
  3. /** 定义SH_CP移位时钟端口连接 */
  4. sbit HC595_SH_CP        = P2 ^ 0;

  5. /** 定义ST_CP锁存时钟端口连接 */
  6. sbit HC595_ST_CP        = P2 ^ 2;

  7. /** 定义DS输出低电平的方法 */
  8. #define HC595_DS_LOW                (HC595_DS = 0)
  9. /** 定义DS输出高电平的方法 */
  10. #define HC595_DS_HIGH                (HC595_DS = 1)
  11. /** 定义SH_CP输出低电平的方法 */
  12. #define HC595_SH_CP_LOW                (HC595_SH_CP = 0)
  13. /** 定义SH_CP输出高电平的方法 */
  14. #define HC595_SH_CP_HIGH        (HC595_SH_CP = 1)
  15. /** 定义ST_CP输出低电平的方法 */
  16. #define HC595_ST_CP_LOW                (HC595_ST_CP = 0)
  17. /** 定义ST_CP输出高电平的方法 */
  18. #define HC595_ST_CP_HIGH        (HC595_ST_CP = 1)

  19. void HC595_Send_Data(unsigned char ucData) {
  20.     unsigned char ucI;

  21.     for(ucI = 0; ucI < 8; ucI ++) {
  22.         HC595_SH_CP_LOW;

  23.         HC595_DS = (ucData & 0x80);

  24.         HC595_SH_CP_HIGH;
  25.         ucData <<= 1;
  26.     }

  27. }
复制代码


因为我这个发送函数直接把sbit定义的HC595_DS、HC595_SH等引脚包含在里面,当我的系统中要使用两组以上的74HC595总线时,我这个函数就要重装写过。我现在想要实现的功能是在函数的参数里添加一个变量比如:
  1. void HC595_Send_Data(PORT *port, unsigned char ucData)
复制代码

这样通过PORT这个参数,把sbit定义的引脚传替进去。但是试了几种方法,sbit这个他定义出来的又不是什么具体的变量,无法传进去。请教大家,谁有比较好的解决方法?还是只能一个总线写一个函数才能解决?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2018-11-10 19:15:15 来自手机 | 显示全部楼层
不是间接寻址,无法传递的哦!

出0入0汤圆

 楼主| 发表于 2018-11-10 19:19:52 | 显示全部楼层
XA144F 发表于 2018-11-10 19:15
不是间接寻址,无法传递的哦!

那给个思路,谢谢了

出0入442汤圆

发表于 2018-11-10 19:25:36 | 显示全部楼层
mangolu 发表于 2018-11-10 19:19
那给个思路,谢谢了

这个貌似无解,只能对每组bit专门写代码。因为位操作是单独的指令(例如51的位设位清,AVR的Read-Modify-Write,都是单独的指令,不可以动态配置)。你要是非要调,只能写成端口和mask,然后手动读,位操作,写。时间增加4倍以上。

出0入0汤圆

发表于 2018-11-10 19:38:24 来自手机 | 显示全部楼层
定义好所有引脚,port 定义为组号,函数内部if...else区分

出0入0汤圆

 楼主| 发表于 2018-11-10 19:53:09 | 显示全部楼层
本帖最后由 mangolu 于 2018-11-10 19:55 编辑
wye11083 发表于 2018-11-10 19:25
这个貌似无解,只能对每组bit专门写代码。因为位操作是单独的指令(例如51的位设位清,AVR的Read-Modify- ...


本来我是想这样传递:
  1. typedef struct {
  2.     unsigned int DS_Port;
  3.     unsigned char DS_Pin;
  4.     unsigned int SH_CP_Port;
  5.     unsigned char SH_CP_Pin;
  6. } HC595_PORT;


  7. void HC595_Send_Data(HC595_PORT *port,unsigned char ucData) {
  8.     unsigned char ucI;

  9.     /** 从高字节开始,依次传送数据 */
  10.     for(ucI = 0; ucI < 8; ucI ++) {
  11.         /** 移位时钟先设置为低电平 */
  12.         port -> SH_CP_Port &= ~(1 << (port -> SH_CP_Pin));

  13.         /** 输出电平方法1 */
  14.         if(ucData & 0x80) {
  15.             port -> DS_Port |= (1 << (port -> DS_Pin));
  16.         } else {
  17.             port -> DS_Port &= ~(1 << (port -> DS_Pin));
  18.         }

  19.         /** 移位时钟从低变为高,上升沿锁存DS数据进移位寄存器 */
  20.         port -> SH_CP_Port |= (1 << (port -> SH_CP_Pin));

  21.         ucData <<= 1;        /** 从最高位开始传输,向左移位 */
  22.     }

  23. }


  24. HC595_PORT port;

  25. port.DS_Port = P2;
  26. port.DS_Pin = 1;
  27. port.SH_CP_Port = P2;
  28. port.SH_CP_Pin = 0;

  29. HC595_Send_Data(&port,0x80);
  30. HC595_Send_Store();
复制代码


但是实现不了,不懂上面我这个程序有没有错误。可能也是P2这样的端口是用sfr这个指令定义的。不懂有什么方法可以用指针通过地址直接操作端口吗?

出0入0汤圆

 楼主| 发表于 2018-11-10 19:54:29 | 显示全部楼层
helloshi 发表于 2018-11-10 19:38
定义好所有引脚,port 定义为组号,函数内部if...else区分

那样就是把所有代码写一遍,我也在想如果实现不了,就全写出来,用预编译做个开关就行。但是太麻烦了

出0入442汤圆

发表于 2018-11-10 20:33:09 | 显示全部楼层
mangolu 发表于 2018-11-10 19:53
本来我是想这样传递:

位操作是单独的指令,不是可以动态生成的变量。所以不能直接传递。这个无解,也许有大牛能做出来。我是在义愤用if()else()去做的。

出0入0汤圆

 楼主| 发表于 2018-11-10 20:35:49 | 显示全部楼层
wye11083 发表于 2018-11-10 20:33
位操作是单独的指令,不是可以动态生成的变量。所以不能直接传递。这个无解,也许有大牛能做出来。我是在 ...


谢谢了,看来我也只能照着ifelse打一遍了

出0入0汤圆

发表于 2018-11-11 11:07:42 | 显示全部楼层
#define H595_0_PORT P2
.....       H595_0_PIN    0x01
...
H595_0_PORT |= H595_0_PIN;
...

没有位操作的不是这样吗,多了1-2条指令,要比if...else之类的快些
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-24 06:21

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

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