打印
[PIC®/AVR®/dsPIC®产品]

天梯 之 从零开始玩转PIC

[复制链接]
楼主: 程序匠人
手机看帖
扫描二维码
随时随地手机跟帖
61
程序匠人|  楼主 | 2007-12-29 12:24 | 只看该作者 回帖奖励 |倒序浏览

几天没关照,已经60多楼了啊。呵呵

使用特权

评论回复
62
兰天白云| | 2007-12-29 12:39 | 只看该作者

旋转时钟,XWJ不做了?

使用特权

评论回复
63
xwj| | 2007-12-29 13:40 | 只看该作者

谁说不做了?

只是暂时没空做罢了

使用特权

评论回复
64
龙飞天下| | 2007-12-29 16:16 | 只看该作者

我喜欢把程序下载到芯片在调试

说白了,不是仿真调试,就是产品测试了。
只是在些程序的时候,一个模块一个模块的做。

使用特权

评论回复
65
wujieflash| | 2007-12-30 20:52 | 只看该作者

求助

韦老师能提供个16F877给我学习一下吗
听说初学用这个比较好

使用特权

评论回复
66
xieyuanbin| | 2007-12-30 22:11 | 只看该作者

杀毒软件搞怪吧?

我用瑞星,好像没碰到这种问题哦。试试安装时把微软的杀毒软件,或其他杀毒软件关闭。或者你看看有没有MSXML2这个XP补丁,卸载掉看看

使用特权

评论回复
67
程序匠人|  楼主 | 2007-12-30 22:26 | 只看该作者

呵呵,多谢 xieyuanbin 指点

果然是防火墙作怪!搞定了

使用特权

评论回复
68
韦广远| | 2008-1-2 09:11 | 只看该作者

To wujieflash:可以,请MSN或者Email联系我

wujieflash 发表于 2007-12-30 20:52 PIC 单片机 ←返回版面 
66楼: 求助 
韦老师能提供个16F877给我学习一下吗
听说初学用这个比较好
 
 

使用特权

评论回复
69
fzj| | 2008-1-2 09:43 | 只看该作者

给发个PROTEUS的TP上来,嘿嘿

我觉得这个软件学习新的几款MCU不错

使用特权

评论回复
70
程序匠人|  楼主 | 2008-1-2 21:55 | 只看该作者

再次遭遇非典:位变量的定义与引用?看来要再次请教hotpower

再次遭遇非典:位变量的定义与引用?看来要再次请教hotpower。

先看看匠人的程序:

//--------------------------------------------------------
//重新命名数据类型
//--------------------------------------------------------
typedef unsigned char    tU08;            //unsigned 8 

//=================
//位结构类型定义
//定义一个位结构,结构名=BIT_F
//=================
typedef struct  {
    unsigned b0 : 1;                        //结构元素表
        unsigned b1 : 1;                                  
        unsigned b2 : 1;                                  
        unsigned b3 : 1;                                  
        unsigned b4 : 1;                                  
        unsigned b5 : 1;                                  
        unsigned b6 : 1;                                  
        unsigned b7 : 1;                                  
} BIT_F;                           //结构类型

//=================
//联合定义
//定义一个联合,联合名=FLAG_union
//=================
typedef union {
    BIT_F     oneBit;        
    tU08    allBits;    
}FLAG_union;                

//--------------------------------------------------------

//
FLAG_union     PORTC_TEMP;    //PORTC 口输出临时缓冲区

#define        PORTC_TMP    PORTC_TEMP.allBits
#define        LED00_TMP    PORTC_TEMP.oneBit.b3;

//--------------------------------------------------------
//接下来两条是程序中的指令
//--------------------------------------------------------

PORTC_TMP = 0 ;                    //不报错
PORTC_TEMP.oneBit.b3 = 1 ;                //不报错
LED00_TMP = 1 ;                    //报错(Error[195] H:picclolk_01clock.c 224 : expression syntax) 

//--------------------------------------------------------
请注意红色字体部分,该语句应该是等效于绿色字体的吧?但是编译就是通不过?

上网查了一下,居然发现hotpower早在2004年已经修炼过此非典**了。看来要再次请教hotpower。把你的脑髓贡献一下吧……

使用特权

评论回复
71
平常人| | 2008-1-2 22:19 | 只看该作者

试试加个括号,突然发现多了个分号,倒塌了~~~

#define        LED00_TMP    (PORTC_TEMP.oneBit.b3)

使用特权

评论回复
72
程序匠人|  楼主 | 2008-1-2 22:30 | 只看该作者

谢平常人提醒,果然是分号惹祸

用ASM用惯了,偶然用C,最大的问题,就是出在这个不起眼的分号上。经常被忽视。呵呵

使用特权

评论回复
73
程序匠人|  楼主 | 2008-1-3 21:09 | 只看该作者

“*3”算法的实现。嘿嘿,看看谁更傻?

今天的故事源于一个“*3”算法的实现,匠人想了解一下编译器是如何处理“* 3”的动作的,于是写了几种不同的c语言写法。交给编译器去编译,看看谁更傻?结果很有趣,如下:


371:                       //写法1(这种方法,需要调用乘法,没效率!)
372:                       S_LINE = 3 * TIME_S ;
  079C    3003     MOVLW 0x3
  079D    00F1     MOVWF 0x71
  079E    0833     MOVF 0x33, W
  079F    120A     BCF 0xa, 0x4
  07A0    118A     BCF 0xa, 0x3
  07A1    2777     CALL 0x777       (注意看这里,居然调用了乘法函数!)
  07A2    00AC     MOVWF 0x2c
373:               
374:                       //写法2(与方法1等效,也需要调用乘法,没效率!)
375:                       S_LINE = TIME_S + TIME_S + TIME_S ;
  07A3    3003     MOVLW 0x3
  07A4    00F1     MOVWF 0x71
  07A5    0833     MOVF 0x33, W
  07A6    120A     BCF 0xa, 0x4
  07A7    118A     BCF 0xa, 0x3
  07A8    2777     CALL 0x777       (注意看这里,居然调用了乘法函数!)
  07A9    00AC     MOVWF 0x2c
376:               
377:                       //写法3(也需要调用乘法,没效率!)
378:                       S_LINE = (TIME_S << 1) + TIME_S ;
  07AA    3003     MOVLW 0x3
  07AB    00F1     MOVWF 0x71
  07AC    0833     MOVF 0x33, W
  07AD    120A     BCF 0xa, 0x4
  07AE    118A     BCF 0xa, 0x3
  07AF    2777     CALL 0x777       (注意看这里,居然调用了乘法函数!)
  07B0    120A     BCF 0xa, 0x4
  07B1    118A     BCF 0xa, 0x3
  07B2    00AC     MOVWF 0x2c
379:               
380:                       //写法4(这种写法,编译结果居然比前两种方法更精简?)
381:                       S_LINE = TIME_S ;
  07B3    0833     MOVF 0x33, W
  07B4    00AC     MOVWF 0x2c
382:                       S_LINE = S_LINE + TIME_S ;
  07B5    0833     MOVF 0x33, W
  07B6    07AC     ADDWF 0x2c, F
383:                       S_LINE = S_LINE + TIME_S ;
  07B7    07AC     ADDWF 0x2c, F
384:               
385:                       //写法5(没想到吧?这样写居然最精简!)
386:                       S_LINE = 2 * TIME_S  ;
  07B8    0733     ADDWF 0x33, W
  07B9    00AC     MOVWF 0x2c
387:                       S_LINE = S_LINE + TIME_S ;
  07BA    0833     MOVF 0x33, W
  07BB    07AC     ADDWF 0x2c, F

使用特权

评论回复
74
程序匠人|  楼主 | 2008-1-3 22:15 | 只看该作者

另一个优化的例子


---------------------------------------------------------------------------------------------------
看来,在写c语言过程中,优化工作还得人工干预一下才好.
下面是另一个优化的例子: 
---------------------------------------------------------------------------------------------------
----------------------------------------写法1: 
382:                   H_LINE = TIME_H / 2 * 15 + TIME_M / 4 ;  //时针定位="时"/2*15+"分"/4
  078D    300F     MOVLW 0xf
  078E    00F1     MOVWF 0x71
  078F    1003     BCF 0x3, 0
  0790    0C30     RRF 0x30, W
  0791    120A     BCF 0xa, 0x4
  0792    118A     BCF 0xa, 0x3
  0793    2768     CALL 0x768         (注意看这里,居然调用了乘法函数!)
  0794    120A     BCF 0xa, 0x4
  0795    118A     BCF 0xa, 0x3
  0796    00F0     MOVWF 0x70
  0797    0831     MOVF 0x31, W
  0798    00F1     MOVWF 0x71
  0799    1003     BCF 0x3, 0
  079A    0CF1     RRF 0x71, F
  079B    1003     BCF 0x3, 0
  079C    0C71     RRF 0x71, W
  079D    0770     ADDWF 0x70, W
  079E    00A4     MOVWF 0x24

----------------------------------------写法2: 
383:               
384:                   i = TIME_H / 2 ;
  079F    1003     BCF 0x3, 0
  07A0    0C30     RRF 0x30, W
  07A1    00C1     MOVWF 0x41
385:                   j = i * 4 - i ;
  07A2    00F0     MOVWF 0x70
  07A3    1003     BCF 0x3, 0
  07A4    0DF0     RLF 0x70, F
  07A5    1003     BCF 0x3, 0
  07A6    0D70     RLF 0x70, W
  07A7    00F0     MOVWF 0x70
  07A8    0841     MOVF 0x41, W
  07A9    0270     SUBWF 0x70, W
  07AA    00C0     MOVWF 0x40
386:                   i = TIME_M / 4 ;
  07AB    0831     MOVF 0x31, W
  07AC    00F0     MOVWF 0x70
  07AD    1003     BCF 0x3, 0
  07AE    0CF0     RRF 0x70, F
  07AF    1003     BCF 0x3, 0
  07B0    0C70     RRF 0x70, W
  07B1    00C1     MOVWF 0x41
387:                   H_LINE = j - i ;    //时针定位="时"/2*15+"分"/4
  07B2    0240     SUBWF 0x40, W
  07B3    00A4     MOVWF 0x24

 

使用特权

评论回复
75
machunshui| | 2008-1-4 13:36 | 只看该作者

关键是能化简成2的倍数

H_LINE = TIME_H / 2 * 15 + TIME_M / 4 ;

H_LINE = TIME_H / 2 * (16-1)+ TIME_M / 4 ;

H_LINE = TIME_H *8 -TIME_H / 2+ TIME_M / 4 ;

H_LINE = (TIME_H << 3) -(TIME_H >> 1)+ (TIME_M >>2) ;

全是2的倍数,用C作左右移相加.
不写成移位,编译器应该会自动把乘除2的倍数的操作变成移位操作

使用特权

评论回复
76
兰天白云| | 2008-1-4 21:52 | 只看该作者

PIC的东西就这么怪

*2,*4等不调用乘法

<<2,<<4却调用乘法

使用特权

评论回复
77
machunshui| | 2008-1-5 09:03 | 只看该作者

绝对是移位,不可能调用乘法

#include <pic.h>

int main()
{
    unsigned char a;
    
    unsigned char b;
    
    b = (a<<2);
}

看看picc的编译结果,绝对是移位,不可能调用乘法.

_main
;    _a assigned to ?a_main+0
_main$a    set    ?a_main
;    _b assigned to ?a_main+1
_main$b    set    ?a_main+1
    line    9
;main.c: 5: unsigned char a;
    bcf    3,5
    bcf    3,6    ;carry unused
    movf    ?a_main,w
    movwf    btemp
    bcf    3,0
    rlf    btemp
    bcf    3,0
    rlf    btemp,w
    movwf    ?a_main+1
    line    10
;main.c: 10: }

使用特权

评论回复
78
程序匠人|  楼主 | 2008-1-5 20:38 | 只看该作者

回machunshui:也不尽然,picc太智能了,有时会自作聪明的。

比如: S_LINE = (TIME_S << 1) + TIME_S
匠人是希望编译器先做左移,再做加法。
结果,picc太“智能”了,自作聪明地把公式转化为:S_LINE = TIME_S * 3,了,结果聪明反被聪明误。
请看:

377:                       //写法3(也需要调用乘法,没效率!)
378:                       S_LINE = (TIME_S << 1) + TIME_S ;
  07AA    3003     MOVLW 0x3
  07AB    00F1     MOVWF 0x71
  07AC    0833     MOVF 0x33, W
  07AD    120A     BCF 0xa, 0x4
  07AE    118A     BCF 0xa, 0x3
  07AF    2777     CALL 0x777       (注意看这里,居然调用了乘法函数!)
  07B0    120A     BCF 0xa, 0x4
  07B1    118A     BCF 0xa, 0x3
  07B2    00AC     MOVWF 0x2c

使用特权

评论回复
79
hotpower| | 2008-1-5 20:41 | 只看该作者

搞个间距试试

S_LINE = (TIME_S << 1);
//...................
//...................
//...................
//...................
//...................
S_LINE += TIME_S;

使用特权

评论回复
80
鼎兴科技| | 2008-1-5 21:14 | 只看该作者

我觉得PIC挺好的,原来一直用AVR现在转了,感觉不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则