搜索
bottom↓
回复: 22

向大家请教一个编程方法

[复制链接]

出0入0汤圆

发表于 2014-8-22 21:20:08 | 显示全部楼层 |阅读模式
我正在设计一个测温系统,用的18B20,测温没什么问题,问题在我的mcu上要接14路18B20,编程上就出现难题:
如果测一路,可以先定义一路IO口:
define DQ p1.0;
然后在函数里读写:
        void init(){DQ=...}
        int8 Read(){DQ=...}
现在要接14路,而单片机的IO口又不能用参数传递,这怎么处理?
我现在只能想到这样:
先挨个定义IO口
define DQ1 p1.0;
define DQ2 p1.1;
...
define DQ14 p2.7;
再在函数里判断
        void init(int8 index)
        {
                select(index)
                        case 1: DQ1...
                        case 2: DQ2...
                        ......
                        case 14: DQ14...
        }
还要在其它函数里都这么写。
可是这么写也太过繁琐,我想应该有更好的解决方法吧,只是我想不到,希望大家指点。

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

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

出0入0汤圆

发表于 2014-8-22 21:28:55 | 显示全部楼层
判断那个io的语句写成个函数不就行了。。。
另外,单片机里有select这个函数吗?看来是自己孤陋寡闻了

出0入0汤圆

 楼主| 发表于 2014-8-22 21:43:08 | 显示全部楼层
写成函数也不过包装一下好看一点啊,有没有更好的方法?
不是select,是switch,select是vb里的,写叉了

出0入0汤圆

发表于 2014-8-22 21:57:43 | 显示全部楼层
多简单啊,,,定义unsigned char 变量,在最低层的读函数中传进去,,,最底层的函数,swich判断

出0入0汤圆

发表于 2014-8-22 22:38:30 | 显示全部楼层
据说18B20可以再一个IO上接无数个,只是需要先读取18B20内部的ID,在进行判断,耗时比较久。

出0入0汤圆

发表于 2014-8-22 22:43:01 | 显示全部楼层
d底层直接用PIO(&&)(||)~mask 就好了吧

出0入0汤圆

发表于 2014-8-23 09:54:24 | 显示全部楼层
typedef struct {}

出0入0汤圆

发表于 2014-8-23 10:03:36 | 显示全部楼层
网上搜的
<p>可以的,但是一般性不这么用,不是所有的编译器都支持sfr(本质是地址)的传递。</p> <p>你可以使用这样的东西:(这是我写的AVR类库)</p> void SETB(PORT port,unsigned char bit);//其他的源代码举一反三吧<p>记得定义:</p> #define PORT enum PORT
//方便输入
#define setb SETB
#define clrb CLRB
#define getb GETB
PORT{
PA,
PB,
PC,
PD
};<p>Port和bit的本质都是寄存器,一个是byte寻址一个是bit寻址而已,千万不要以为bit寻址就一定快,往往是byte要快一些。</p> <p>附上源代码:</p> <p>gpio.h</p> #ifndef AVR_GPIO_H
#define AVR_GPIO_H
#define PORT enum PORT
//方便输入
#define setb SETB
#define clrb CLRB
#define getb GETB
PORT{
//PA,
PB,
PC,
PD
};
extern void SETB(PORT port,unsigned char bit);
//相应端口置1,并设置为输出
extern void CLRB(PORT port,unsigned char bit);
//相应端口置0,并设置为输出
extern unsigned char GETB(PORT port,unsigned char bit);
//相应端口设置为输入并读取,返回0xff(1)与0x00(0),异常返回0xf0
extern void SETD(PORT port,unsigned char bit);
//相应端口设置为输出
extern void CLRD(PORT port,unsigned char bit);
//相应端口设置为输入
#endif<p>gpio.c</p> #include"inc.h"

void SETB(PORT port,unsigned char bit){
if(bit&lt;=7){
switch(port){
//case PA:
//DDRA|=(1&lt;&lt;bit);
//PORTA|=(1&lt;&lt;bit);
//break;
//use in Mega16
case PB:
DDRB|=(1&lt;&lt;bit);
PORTB|=(1&lt;&lt;bit);
break;
case PC:
DDRC|=(1&lt;&lt;bit);
PORTC|=(1&lt;&lt;bit);
break;
case PD:
DDRD|=(1&lt;&lt;bit);
PORTD|=(1&lt;&lt;bit);
break;
}
}
}

void CLRB(PORT port,unsigned char bit){
if(bit&lt;=7){
switch(port){
//case PA:
//DDRA&amp;=(1&lt;&lt;bit);
//PORTA&amp;=(0xff-(1&lt;&lt;bit));
//break;
//use in Mega16
case PB:
DDRB|=(1&lt;&lt;bit);
PORTB&amp;=(0xff-(1&lt;&lt;bit));
break;
case PC:
DDRC|=(1&lt;&lt;bit);
PORTC&amp;=(0xff-(1&lt;&lt;bit));
break;
case PD:
DDRD|=(1&lt;&lt;bit);
PORTD&amp;=(0xff-(1&lt;&lt;bit));
break;
}
}
}

unsigned char GETB(PORT port,unsigned char bit){
unsigned return_value=0;
if(bit&lt;=7){
switch(port){
//case PA:
//DDRA|=(0xff-(1&lt;&lt;bit));
//return_value=PINA&amp;(1&lt;&lt;bit);
//break;
//use in Mega16
case PB:
DDRB|=(0xff-(1&lt;&lt;bit));
return_value=PINB&amp;(1&lt;&lt;bit);
break;
case PC:
DDRC|=(0xff-(1&lt;&lt;bit));
return_value=PINC&amp;(1&lt;&lt;bit);
break;
case PD:
DDRD|=(0xff-(1&lt;&lt;bit));
return_value=PIND&amp;(1&lt;&lt;bit);
break;
}
if(return_value==0){
return(0x00);
}else{
return(0xff);
}
}
return(0xf0);
}

void SETD(PORT port,unsigned char bit){
if(bit&lt;=7){
switch(port){
//case PA:
//DDRA|=(1&lt;&lt;bit);
//break;
//use in Mega16
case PB:
DDRB|=(1&lt;&lt;bit);
break;
case PC:
DDRC|=(1&lt;&lt;bit);
break;
case PD:
DDRD|=(1&lt;&lt;bit);
break;
}
}
}

void CLRD(PORT port,unsigned char bit){
if(bit&lt;=7){
switch(port){
//case PA:
//DDRA|=(0xff-(1&lt;&lt;bit));
//break;
//use in Mega16
case PB:
DDRB|=(0xff-(1&lt;&lt;bit));
break;
case PC:
DDRC|=(0xff-(1&lt;&lt;bit));
break;
case PD:
DDRD|=(0xff-(1&lt;&lt;bit));
break;
}
}
}

出0入0汤圆

发表于 2014-8-23 10:21:44 | 显示全部楼层
5楼正解,速率上满足的话,总线模式读取 应该来说最合适

出0入4汤圆

发表于 2014-8-23 10:22:27 | 显示全部楼层
一个IO可以挂很多18b20,人家早就给你想好解决方案了。

出0入0汤圆

发表于 2014-8-23 10:26:25 | 显示全部楼层
3个方案,皆可
1、推荐你用1个IO口,然后把这些18B20都串在一起,根据地址找
2、如果你对单总线组网比较头疼,可以做个切换电路,每次选中一路,然后直接操作
3、单片机IO够用的情况下,每一路占一个IO口,至于代码,非常简单,把IO的位置作为参数传入即可,读写代码只要写一遍即可

出0入0汤圆

发表于 2014-8-23 10:27:25 | 显示全部楼层
另外具体IO口选择不需要lz位的无趣的switch语句,C语言位操作即可,给你一段别的程序做参考:
oid HuXi_up(uint IO_Bit)
{
unsigned char i,mask;
mask=1;
mask = _crol_(1,IO_Bit)

for(pwm_low=1;pwm_low<CYCLE;pwm_low++)
{
P1 = P1 & (~ mask);
duty=0;
while(duty<=pwm_low);
P1 = P1 ^ mask;
duty=0;
while(duty<=(CYCLE-pwm_low));
}
}

出0入0汤圆

发表于 2014-8-23 13:45:29 | 显示全部楼层
这个不错,之前我也这样干过,后来自己琢磨了下精简了下

出0入0汤圆

发表于 2014-8-23 14:12:33 | 显示全部楼层
楼主,我做过类似的用电子开关切换 最多可以支持36个通道,只占用8个IO,同时支持sht21和sht11

出0入0汤圆

发表于 2014-8-23 14:26:56 | 显示全部楼层
set PIO(u8 IO,u8 BitMsk)
{
    switch(IO){
        case 0:
        P0 |= BitMsk;
        break;
        case 1:...
}
}

出0入0汤圆

发表于 2014-8-24 23:23:19 | 显示全部楼层
javabean 发表于 2014-8-23 10:26
3个方案,皆可
1、推荐你用1个IO口,然后把这些18B20都串在一起,根据地址找
2、如果你对单总线组网比较头 ...

给楼主提供另一种思路,14个IO口同周期操作,一个周期搞定,不用切换。

出0入0汤圆

 楼主| 发表于 2014-8-25 20:46:40 | 显示全部楼层
谢谢各位的热情解答!
首先,51的IO是不能当参数传递的,所以上面有些方法行不通,avr能不能行我不知道;
其次关于组网,我每个通道做单总线上面都挂了大概30个器件,整个主板要接400多个;
现在只能想到用形如 P1||mask 即对8个IO一组操作的方法简便一点,本质上和单个赋值是一样的。
不知道我想得对不对。

出0入0汤圆

 楼主| 发表于 2014-8-25 20:50:00 | 显示全部楼层
wxty 发表于 2014-8-24 23:23
给楼主提供另一种思路,14个IO口同周期操作,一个周期搞定,不用切换。

一个周期完成时序来不及吧

出0入0汤圆

 楼主| 发表于 2014-8-25 20:51:27 | 显示全部楼层
meirenai 发表于 2014-8-23 14:12
楼主,我做过类似的用电子开关切换 最多可以支持36个通道,只占用8个IO,同时支持sht21和sht11 ...

别光说不练啊

出0入0汤圆

 楼主| 发表于 2014-8-25 20:52:38 | 显示全部楼层
mcu5i51 发表于 2014-8-23 14:26
set PIO(u8 IO,u8 BitMsk)
{
    switch(IO){

这是我目前采用的方法!

出0入0汤圆

 楼主| 发表于 2014-8-25 20:54:13 | 显示全部楼层
javabean 发表于 2014-8-23 10:27
另外具体IO口选择不需要lz位的无趣的switch语句,C语言位操作即可,给你一段别的程序做参考:
oid HuXi_up( ...

参考!谢谢!

出0入0汤圆

发表于 2014-8-25 21:00:28 | 显示全部楼层
sdf159372008 发表于 2014-8-22 22:38
据说18B20可以再一个IO上接无数个,只是需要先读取18B20内部的ID,在进行判断,耗时比较久。 ...

嗯,赞同。

出0入0汤圆

发表于 2014-8-25 21:59:21 | 显示全部楼层
nandi 发表于 2014-8-25 20:50
一个周期完成时序来不及吧

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

本版积分规则

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

GMT+8, 2024-7-23 10:32

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

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