搜索
bottom↓
回复: 67

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

[复制链接]

出0入0汤圆

发表于 2009-8-3 15:25:01 | 显示全部楼层 |阅读模式
还是用实例说明一下,
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; 了

请赐教~

送上小姨子


__@~~ (原文件名:9000_1248748811W5D5.jpg)

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

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

出0入0汤圆

 楼主| 发表于 2009-8-3 16:33:41 | 显示全部楼层
不能光看美女不回复啊~

出0入0汤圆

发表于 2009-8-3 16:34:30 | 显示全部楼层
可以.但麻烦一点..

出0入0汤圆

发表于 2009-8-3 16:36:37 | 显示全部楼层
可以.但麻烦一点..

出0入0汤圆

 楼主| 发表于 2009-8-3 16:42:16 | 显示全部楼层
楼上两位都说说思路,亮亮代码呀,新手求教

出0入0汤圆

发表于 2009-8-3 16:45:14 | 显示全部楼层
led_data写成函数,可能慢点

出0入0汤圆

发表于 2009-8-3 16:47:11 | 显示全部楼层

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

出0入0汤圆

发表于 2009-8-3 16:49:53 | 显示全部楼层
其实有一个软件,可以自定义io生成字模的。回家给你找找。小姨子我都收了~~

出0入0汤圆

发表于 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为要显示的数在码表中的位置

出0入0汤圆

发表于 2009-8-3 17:38:36 | 显示全部楼层
楼上老许思路是对的但代码是错的

出0入0汤圆

发表于 2009-8-3 17:38:53 | 显示全部楼层
这样会比较慢,可以这样加快速度。

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

出0入0汤圆

发表于 2009-8-3 17:41:51 | 显示全部楼层
51哦  可不是  AVR  呵呵  顶楼上

出0入0汤圆

发表于 2009-8-3 18:35:23 | 显示全部楼层
这种二次异或,没有中间过渡突变...
对P3和P1的赋值,各只有一次...

出0入0汤圆

发表于 2009-8-3 18:40:48 | 显示全部楼层
我..怎么没看出老许的错在哪里...

出0入0汤圆

 楼主| 发表于 2009-8-3 19:45:41 | 显示全部楼层
看来小姨子送的值啊,谢谢各位大侠赐教,小弟明白啦~~

出0入0汤圆

发表于 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;
}

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

出0入0汤圆

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

出0入0汤圆

发表于 2009-8-3 22:19:46 | 显示全部楼层
【19楼】 xuyiyi 许意义

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



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

出0入0汤圆

发表于 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位输出状态不变的方法也不成立。

出0入0汤圆

 楼主| 发表于 2009-8-4 07:42:42 | 显示全部楼层
占座学习~~~IO果然很深奥啊

出0入0汤圆

发表于 2009-8-4 08:44:55 | 显示全部楼层
题不会,小姨子收下了。

出0入0汤圆

发表于 2009-8-4 08:58:55 | 显示全部楼层
不好意思,眼里只有美女了,没看到楼主提的问题

出0入0汤圆

发表于 2009-8-4 09:33:00 | 显示全部楼层
【26楼】 xuyiyi 许工大概看漏了回写前有一个低位清零的操作,如果先对A低四位清零,然后"读入-修改-回写",确实会出现上述的错误,但现在的次序是"读入-修改-清低位-回写",这样就避免了此过程中IO状态改变引起的错误。借用20楼的图说明一下,看看我的理解是否仍存在误区。如果仍是错误,那么到手的小姨子不敢再收了。

(原文件名:未命名.JPG)

出0入0汤圆

发表于 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;               // 再改变要变高的位
}

出0入0汤圆

发表于 2009-8-4 09:49:09 | 显示全部楼层
楼主家中姨子怎么这么多呢?小心身体了

出0入0汤圆

发表于 2009-8-4 10:13:05 | 显示全部楼层
新手路过学习

出0入0汤圆

发表于 2009-8-4 10:52:42 | 显示全部楼层
void LedDataOut(uchar dat)
{
  ..........  //关闭所有位显示
  P1 &= 0x78;
  P1 |= dat&0x87; //送数
  P3 &= 0x0f;
  P3 |= dat&0xf0;
  .........  //开启相关位显示
}

出0入0汤圆

发表于 2009-8-4 11:06:43 | 显示全部楼层
【33楼】 xuyiyi 许工言重了,讨论有益,你考虑问题的严谨性与周全性我们后辈得跟着慢慢学。
头像被屏蔽

出0入0汤圆

发表于 2009-8-4 11:21:58 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
头像被屏蔽

出0入0汤圆

发表于 2009-8-4 11:52:22 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 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;
  
}

出0入0汤圆

发表于 2009-8-4 12:06:17 | 显示全部楼层
小姨不错

我也遇到过这样的问题,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

出0入0汤圆

发表于 2009-8-4 12:35:21 | 显示全部楼层
36楼跟37楼的执行时间是一样的,所以37楼并没有优化运行速度,只是写法好写一点,不容易出错。

MOV  C,ACC.7   1T
MOV  LED_A,C   2T

共3T
-------------------
RLC  A         1T
MOV  LED_A,C   2T

共3T
头像被屏蔽

出0入0汤圆

发表于 2009-8-4 12:47:51 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2009-8-4 13:42:18 | 显示全部楼层
最普通的51

AT89S51

出0入0汤圆

 楼主| 发表于 2009-8-4 18:30:47 | 显示全部楼层
很有意思的讨论啊,谢谢各位的发言啊,尤其是许工和cowboy的讨论,很受益,OUR_AVR真是一个很好的坛子

出0入0汤圆

发表于 2009-11-26 07:07:40 | 显示全部楼层
受益,正在找这个

出0入0汤圆

发表于 2009-11-26 08:29:55 | 显示全部楼层
MARK 51IO

出0入0汤圆

发表于 2009-11-26 10:46:17 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2009-11-26 10:46:19 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2010-1-1 15:12:43 | 显示全部楼层
好贴,特别是许工和牛仔的分析,精辟啊

出0入0汤圆

发表于 2010-1-1 15:19:40 | 显示全部楼层
精辟
许工和牛仔的分析,精辟啊

出0入0汤圆

发表于 2010-1-4 14:53:13 | 显示全部楼层
uchar bdata LCD_DATA; // 液晶BD0~BD7
sbit  LCD_DATA_D0=  LCD_DATA^0;   
sbit  LCD_DATA_D1=  LCD_DATA^1;
sbit  LCD_DATA_D2=  LCD_DATA^2;
sbit  LCD_DATA_D3=  LCD_DATA^3;   
sbit  LCD_DATA_D4=  LCD_DATA^4;
sbit  LCD_DATA_D5=  LCD_DATA^5;
sbit  LCD_DATA_D6=  LCD_DATA^6;
sbit  LCD_DATA_D7=  LCD_DATA^7;

#define  LCD_DATA_D0 P0^3   
#define  LCD_DATA_D1 P0^4  
#define  LCD_DATA_D2 P0^5  
#define  LCD_DATA_D3 P0^6     
#define  LCD_DATA_D4 P0^7  
#define  LCD_DATA_D5 P2^0
#define  LCD_DATA_D6 P2^1
#define  LCD_DATA_D7 P2^2

出0入0汤圆

发表于 2010-1-4 17:16:16 | 显示全部楼层
签名

出0入0汤圆

发表于 2010-1-4 17:53:57 | 显示全部楼层
看到高人较量,顺便也看看别人的小姨子哦

出0入0汤圆

发表于 2010-1-5 11:03:43 | 显示全部楼层
新手路过学习

出0入0汤圆

发表于 2010-1-5 11:04:14 | 显示全部楼层
新手路过学习

出0入0汤圆

发表于 2010-1-5 12:43:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-5 12:44:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-8 23:51:53 | 显示全部楼层
学习

出0入4汤圆

发表于 2010-1-9 14:44:54 | 显示全部楼层
mark

出0入0汤圆

发表于 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;}    \
}
这样应该也能实现

出0入0汤圆

发表于 2010-1-30 15:44:09 | 显示全部楼层
学习

出50入0汤圆

发表于 2010-1-30 16:31:02 | 显示全部楼层
新手记号

出0入0汤圆

发表于 2010-1-30 17:37:38 | 显示全部楼层
好帖,记号一下,

出0入0汤圆

发表于 2010-1-30 20:28:11 | 显示全部楼层
冲着老许他们的讨论,MARK下。

出0入0汤圆

发表于 2010-2-2 21:32:35 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2010-2-7 22:26:45 | 显示全部楼层
暂时看不懂,还是支持一下高手的辩论.

出0入0汤圆

发表于 2010-2-8 17:40:25 | 显示全部楼层
在keil c51中试验了下38楼的程序,通不过,需要将temp及其下的位变量定义为全局变量才行。
其中有个笔误:
LedDataOut(uchar dat)
{

temp=data;

}
^_^

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-24 02:20

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

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