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) 不能光看美女不回复啊~ 可以.但麻烦一点.. 可以.但麻烦一点.. 楼上两位都说说思路,亮亮代码呀,新手求教 led_data写成函数,可能慢点 哇
楼主那么多小姨子啊
这个只是你建立字模的时候把字库表设置好了就可以啦 其实有一个软件,可以自定义io生成字模的。回家给你找找。小姨子我都收了~~ 点击此处下载 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为要显示的数在码表中的位置 楼上老许思路是对的但代码是错的 这样会比较慢,可以这样加快速度。
void led_data_out(unsigned char a)
{
P3 ^= (P3 ^ a) & 0x0f;
P1 ^= (P1 ^ a) & 0xf0;
} 51哦可不是AVR呵呵顶楼上 这种二次异或,没有中间过渡突变...
对P3和P1的赋值,各只有一次... 我..怎么没看出老许的错在哪里... 看来小姨子送的值啊,谢谢各位大侠赐教,小弟明白啦~~ 呵呵,光看小姨子,没细看要求给楼主设陷阱了,改过来:
void led_data_out(unsigned char a)
{
P3 ^= (P3 ^ a) & 0xf0;
a &= 0x0f;
P1 ^= (P1 ^ (a<<4|a)) & 0x87;
}
每个口只写一次,应该不会产生过渡突变或尖峰。 许工所言甚是,是我考虑得不够严谨,当端口被取样到再输出这段时间内,如果端口状态被外界改变,就会出错。或者这段时间内刚好发生中断,中断程序改变断口状态,也会造成错误。
最要命的是这种BUG非常隐蔽,出错的概率极低,调试时几乎不可能发现。但一旦应用到实际上去,有那么巧合的话,后果将不堪设想。幸好许工在这里指出,否则...... 【19楼】 xuyiyi 许意义
p1.0 , p1.1 ...... 等端口命名应用大写,楼主用小写,我也用小写,本想让他自已修正的。
看来我已经忘得差不多啊..哈哈. 再次思考许工提及的问题,发现【18楼】的程序并不会出现错误。问题的关键聚集到这条指条,“XRL P3,A”,这是一个 读-修改-写 的过程,在执行这条指令时,首先读入P3,问题来了,这个“读”究竟是读入P3口的“输入状态”寄存器,还是读入P3口的“输出状态”寄存器呢?,如果是前者,那么程序就会引起错误,如果是后者,程序就能正常。我认为MCU内核中是以后者方式运作,即读入P3口的输出状态寄存器,为了验证这个观点,用Proteus仿真了一下,证实了这个想法。同理,“ANL P3,A” “ORL P3,A”这两条指令也符合这种情况,否则,想用“ANL P3,#0FH”来保持低4位输出状态不变的方法也不成立。 占座学习~~~IO果然很深奥啊 题不会,小姨子收下了。 不好意思,眼里只有美女了,没看到楼主提的问题 【26楼】 xuyiyi 许工大概看漏了回写前有一个低位清零的操作,如果先对A低四位清零,然后"读入-修改-回写",确实会出现上述的错误,但现在的次序是"读入-修改-清低位-回写",这样就避免了此过程中IO状态改变引起的错误。借用20楼的图说明一下,看看我的理解是否仍存在误区。如果仍是错误,那么到手的小姨子不敢再收了。
http://cache.amobbs.com/bbs_upload782111/files_17/ourdev_467296.JPG
(原文件名:未命名.JPG) 针对楼主的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; // 再改变要变高的位
} 楼主家中姨子怎么这么多呢?小心身体了 新手路过学习 void LedDataOut(uchar dat)
{
..........//关闭所有位显示
P1 &= 0x78;
P1 |= dat&0x87; //送数
P3 &= 0x0f;
P3 |= dat&0xf0;
.........//开启相关位显示
} 【33楼】 xuyiyi 许工言重了,讨论有益,你考虑问题的严谨性与周全性我们后辈得跟着慢慢学。 楼上这种方法是最稳妥的,直接写成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;
} 小姨不错./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
36楼跟37楼的执行时间是一样的,所以37楼并没有优化运行速度,只是写法好写一点,不容易出错。
MOVC,ACC.7 1T
MOVLED_A,C 2T
共3T
-------------------
RLCA 1T
MOVLED_A,C 2T
共3T 最普通的51
AT89S51 很有意思的讨论啊,谢谢各位的发言啊,尤其是许工和cowboy的讨论,很受益,OUR_AVR真是一个很好的坛子 受益,正在找这个 MARK 51IO MARK! MARK! 好贴,特别是许工和牛仔的分析,精辟啊 精辟
许工和牛仔的分析,精辟啊 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 签名 看到高人较量,顺便也看看别人的小姨子哦 新手路过学习 新手路过学习 mark mark 学习 mark 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;} \
}
这样应该也能实现 学习 新手记号 好帖,记号一下, 冲着老许他们的讨论,MARK下。 MARK! 暂时看不懂,还是支持一下高手的辩论. 在keil c51中试验了下38楼的程序,通不过,需要将temp及其下的位变量定义为全局变量才行。
其中有个笔误:
LedDataOut(uchar dat)
{
…
temp=data;
…
}
^_^ mark!!!!!!
页:
[1]