sosingle 发表于 2009-8-3 15:25:01

C51中8位数据能组成一个字节吗,送小姨子咯

还是用实例说明一下,
8段数码管,数据口分别是a,b,c,d,e,f,g,h为了布线方便,并没有接在同一个IO口上
实际是这样对应的
a---p1.0
b---p1.1
c---p1.2
d---p1.7
e---p3.4
f---p3.5
g---p3.6
h---p3.7

请问送数据的时候该怎么送呢?
不能像以前接同一个IO口那样,直接 led_data = 0x80; 了

请赐教~

送上小姨子

http://cache.amobbs.com/bbs_upload782111/files_17/ourdev_466827.jpg
__@~~ (原文件名:9000_1248748811W5D5.jpg)

sosingle 发表于 2009-8-3 16:33:41

不能光看美女不回复啊~

hyz_avr 发表于 2009-8-3 16:34:30

可以.但麻烦一点..

shinehjx 发表于 2009-8-3 16:36:37

可以.但麻烦一点..

sosingle 发表于 2009-8-3 16:42:16

楼上两位都说说思路,亮亮代码呀,新手求教

Forever.c 发表于 2009-8-3 16:45:14

led_data写成函数,可能慢点

mingyuexin1981 发表于 2009-8-3 16:47:11


楼主那么多小姨子啊
这个只是你建立字模的时候把字库表设置好了就可以啦

mingyuexin1981 发表于 2009-8-3 16:49:53

其实有一个软件,可以自定义io生成字模的。回家给你找找。小姨子我都收了~~

little_Monkey 发表于 2009-8-3 16:58:05

点击此处下载 ourdev_466863.rar(文件大小:183K) (原文件名:LED-encode.rar)
用上面的软件取模,然后写个函数就可以了,开头定义一下各段的接口
void sendled_data(unsigned char i)
{
        unsigned char j;
        j=leddata;
        Led_a=j&0x01;
        Led_b=j&0x02;
        Led_c=j&0x04;
        Led_d=j&0x08;
        Led_e=j&0x10;
        Led_f=j&0x20;
        Led_g=j&0x40;
        Led_dp=j&0x80;
}
其中i为要显示的数在码表中的位置

shinehjx 发表于 2009-8-3 17:38:36

楼上老许思路是对的但代码是错的

cowboy 发表于 2009-8-3 17:38:53

这样会比较慢,可以这样加快速度。

void led_data_out(unsigned char a)
{
P3 ^= (P3 ^ a) & 0x0f;
P1 ^= (P1 ^ a) & 0xf0;
}

wear778899 发表于 2009-8-3 17:41:51

51哦可不是AVR呵呵顶楼上

snoopyzz 发表于 2009-8-3 18:35:23

这种二次异或,没有中间过渡突变...
对P3和P1的赋值,各只有一次...

hyz_avr 发表于 2009-8-3 18:40:48

我..怎么没看出老许的错在哪里...

sosingle 发表于 2009-8-3 19:45:41

看来小姨子送的值啊,谢谢各位大侠赐教,小弟明白啦~~

cowboy 发表于 2009-8-3 20:06:44

呵呵,光看小姨子,没细看要求给楼主设陷阱了,改过来:
void led_data_out(unsigned char a)
{
P3 ^= (P3 ^ a) & 0xf0;
a &= 0x0f;
P1 ^= (P1 ^ (a<<4|a)) & 0x87;
}

每个口只写一次,应该不会产生过渡突变或尖峰。

cowboy 发表于 2009-8-3 22:08:50

许工所言甚是,是我考虑得不够严谨,当端口被取样到再输出这段时间内,如果端口状态被外界改变,就会出错。或者这段时间内刚好发生中断,中断程序改变断口状态,也会造成错误。
最要命的是这种BUG非常隐蔽,出错的概率极低,调试时几乎不可能发现。但一旦应用到实际上去,有那么巧合的话,后果将不堪设想。幸好许工在这里指出,否则......

hyz_avr 发表于 2009-8-3 22:19:46

【19楼】 xuyiyi 许意义

p1.0 , p1.1 ...... 等端口命名应用大写,楼主用小写,我也用小写,本想让他自已修正的。



看来我已经忘得差不多啊..哈哈.

cowboy 发表于 2009-8-4 01:06:50

再次思考许工提及的问题,发现【18楼】的程序并不会出现错误。问题的关键聚集到这条指条,“XRL P3,A”,这是一个 读-修改-写 的过程,在执行这条指令时,首先读入P3,问题来了,这个“读”究竟是读入P3口的“输入状态”寄存器,还是读入P3口的“输出状态”寄存器呢?,如果是前者,那么程序就会引起错误,如果是后者,程序就能正常。我认为MCU内核中是以后者方式运作,即读入P3口的输出状态寄存器,为了验证这个观点,用Proteus仿真了一下,证实了这个想法。同理,“ANL P3,A” “ORL P3,A”这两条指令也符合这种情况,否则,想用“ANL P3,#0FH”来保持低4位输出状态不变的方法也不成立。

sosingle 发表于 2009-8-4 07:42:42

占座学习~~~IO果然很深奥啊

tage 发表于 2009-8-4 08:44:55

题不会,小姨子收下了。

Alexkey 发表于 2009-8-4 08:58:55

不好意思,眼里只有美女了,没看到楼主提的问题

cowboy 发表于 2009-8-4 09:33:00

【26楼】 xuyiyi 许工大概看漏了回写前有一个低位清零的操作,如果先对A低四位清零,然后"读入-修改-回写",确实会出现上述的错误,但现在的次序是"读入-修改-清低位-回写",这样就避免了此过程中IO状态改变引起的错误。借用20楼的图说明一下,看看我的理解是否仍存在误区。如果仍是错误,那么到手的小姨子不敢再收了。
http://cache.amobbs.com/bbs_upload782111/files_17/ourdev_467296.JPG
(原文件名:未命名.JPG)

shinehjx 发表于 2009-8-4 09:33:06

针对楼主的IO分配情况写的
void led_data_out(unsigned char a)
{
P1 &= (a << 4) | 0x7F & (a | 0xF8);   // 先改变要变低的位
P1 |= (a << 4) & 0x80 | (a & 0x07);   // 再改变要变高的位
P3 &= a | 0x0F;               // 先改变要变低的位
P3 |= a & 0xF0;               // 再改变要变高的位
}

yuzhou211 发表于 2009-8-4 09:49:09

楼主家中姨子怎么这么多呢?小心身体了

r166 发表于 2009-8-4 10:13:05

新手路过学习

hkap 发表于 2009-8-4 10:52:42

void LedDataOut(uchar dat)
{
..........//关闭所有位显示
P1 &= 0x78;
P1 |= dat&0x87; //送数
P3 &= 0x0f;
P3 |= dat&0xf0;
.........//开启相关位显示
}

cowboy 发表于 2009-8-4 11:06:43

【33楼】 xuyiyi 许工言重了,讨论有益,你考虑问题的严谨性与周全性我们后辈得跟着慢慢学。

bbs2009 发表于 2009-8-4 11:21:58

bbs2009 发表于 2009-8-4 11:52:22

hkap 发表于 2009-8-4 12:00:30

楼上这种方法是最稳妥的,直接写成C51函数即可
//引脚定义
sbit LED_A    =   P1^0;
sbit LED_B    =   P1^1;
sbit LED_C    =   P1^2;
sbit LED_D    =   P1^7;
sbit LED_E    =   P3^4;
sbit LED_F    =   P3^5;
sbit LED_G    =   P3^6;
sbit LED_H    =   P3^7;

void LedDataOut(uchar dat)
{
uchar bdata temp;
sbit a = temp^0;
sbit b = temp^1;
sbit c = temp^2;
sbit d = temp^3;
sbit e = temp^4;
sbit f = temp^5;
sbit g = temp^6;
sbit h = temp^7;

temp = data;

LED_A = a;
LED_B = b;
LED_C = c;
LED_D = d;
LED_E = e;
LED_F = f;
LED_G = g;
LED_H = h;

}

hsztc 发表于 2009-8-4 12:06:17

小姨不错./emotion/em185.gif

我也遇到过这样的问题,51还算简单,AVR就罗嗦了,这是我写的AVR解决办法。

http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3489398&bbs_page_no=1&search_mode=3&search_text=hsztc&bbs_id=9999

hsztc 发表于 2009-8-4 12:35:21

36楼跟37楼的执行时间是一样的,所以37楼并没有优化运行速度,只是写法好写一点,不容易出错。

MOVC,ACC.7   1T
MOVLED_A,C   2T

共3T
-------------------
RLCA         1T
MOVLED_A,C   2T

共3T

bbs2009 发表于 2009-8-4 12:47:51

hsztc 发表于 2009-8-4 13:42:18

最普通的51

AT89S51

sosingle 发表于 2009-8-4 18:30:47

很有意思的讨论啊,谢谢各位的发言啊,尤其是许工和cowboy的讨论,很受益,OUR_AVR真是一个很好的坛子

z7001 发表于 2009-11-26 07:07:40

受益,正在找这个

eduhf_123 发表于 2009-11-26 08:29:55

MARK 51IO

380121850 发表于 2009-11-26 10:46:17

MARK!

380121850 发表于 2009-11-26 10:46:19

MARK!

ju748 发表于 2010-1-1 15:12:43

好贴,特别是许工和牛仔的分析,精辟啊

ggddll 发表于 2010-1-1 15:19:40

精辟
许工和牛仔的分析,精辟啊

311711 发表于 2010-1-4 14:53:13

uchar bdata LCD_DATA; // 液晶BD0~BD7
sbitLCD_DATA_D0=LCD_DATA^0;   
sbitLCD_DATA_D1=LCD_DATA^1;
sbitLCD_DATA_D2=LCD_DATA^2;
sbitLCD_DATA_D3=LCD_DATA^3;   
sbitLCD_DATA_D4=LCD_DATA^4;
sbitLCD_DATA_D5=LCD_DATA^5;
sbitLCD_DATA_D6=LCD_DATA^6;
sbitLCD_DATA_D7=LCD_DATA^7;

#defineLCD_DATA_D0 P0^3   
#defineLCD_DATA_D1 P0^4
#defineLCD_DATA_D2 P0^5
#defineLCD_DATA_D3 P0^6   
#defineLCD_DATA_D4 P0^7
#defineLCD_DATA_D5 P2^0
#defineLCD_DATA_D6 P2^1
#defineLCD_DATA_D7 P2^2

sw821025 发表于 2010-1-4 17:16:16

签名

lv998127 发表于 2010-1-4 17:53:57

看到高人较量,顺便也看看别人的小姨子哦

lxbeiming 发表于 2010-1-5 11:03:43

新手路过学习

lxbeiming 发表于 2010-1-5 11:04:14

新手路过学习

liumaojun_cn 发表于 2010-1-5 12:43:38

mark

liumaojun_cn 发表于 2010-1-5 12:44:02

mark

xdpj 发表于 2010-1-8 23:51:53

学习

D.lovers 发表于 2010-1-9 14:44:54

mark

xiaojian 发表于 2010-1-9 22:05:19

void led_data_out(unsigned char a)
{
    if(a&0x01){P1.0=1;} else { P1.0=0;}\
    if(a&0x02){P1.1=1;} else { P1.1=0;}    \
    if(a&0x04){P1.2=1;} else { P1.2=0;}    \
    if(a&0x08){P1.3=1;} else { P1.3=0;}    \
    if(a&0x10){P3.4=1;} else { P3.4=0;}    \
    if(a&0x20){P3.5=1;} else { P3.5=0;}    \
    if(a&0x40){P3.6=1;} else { P3.6=0;}    \
    if(a&0x80){P3.7=1;} else { P3.7=0;}    \
}
这样应该也能实现

nbanba 发表于 2010-1-30 15:44:09

学习

lm4766 发表于 2010-1-30 16:31:02

新手记号

5555555555 发表于 2010-1-30 17:37:38

好帖,记号一下,

writer15 发表于 2010-1-30 20:28:11

冲着老许他们的讨论,MARK下。

XMLK 发表于 2010-2-2 21:32:35

MARK!

wuqihuihaoo 发表于 2010-2-7 22:26:45

暂时看不懂,还是支持一下高手的辩论.

arbol 发表于 2010-2-8 17:40:25

在keil c51中试验了下38楼的程序,通不过,需要将temp及其下的位变量定义为全局变量才行。
其中有个笔误:
LedDataOut(uchar dat)
{

temp=data;

}
^_^

ang727 发表于 2012-3-26 10:26:28

mark!!!!!!
页: [1]
查看完整版本: C51中8位数据能组成一个字节吗,送小姨子咯