EDN首页   博客首页

7

关于投票
AVR微秒级与毫秒级精确延时

/*******************************************************************

                             微秒级精确延时(ICC)

*******************************************************************/

include <iom8v.h>
/*======================================
 微秒级精确延时函数,晶振8M:          
 Delay = 0.125 *((tt*4-1)+9)微秒
 其中9包括了调用方的 r16 赋值 1t
 rcall 3t    nop 1t   ret 4t
 brne指令在当判断条件不成立时是单周期
 最后一次判断只有1个周期,补一个nop
 简化计算 = 0.5tt + 1 (us)
======================================*/
void shortdelay(unsigned char tt)
{
        asm("_L2: subi R16,1"); 
        asm(" nop")
        asm(" brne _L2");
        asm(" nop");
        asm(" ret");
}

void main()
{
        shortdelay( 18 );
        while(1)        {
                shortdelay( 48 );
        }
}

 

/************************************************************************

                                        毫秒级精确延时(ICC)

*************************************************************************/

#include<iom8v.h>

#define xtal 8 //以MHz为单位,不同的系统时钟要修改。

void delay_1ms(void)
{
uint i;
for(i=0;i<(unsigned int)(xtal*143-2);i++);
}


void delay_ms(uint num)
{
uint i;
for(i=0;i<num;i++) delay_1ms();
}

void main(void)
{
DDRB=0xff;
PORTB=0x00;

while(1)
{
delay_ms(100);
PORTB^=0xff;
}
}

 

系统分类: 单片机
用户分类: 侃单片机
标签: AVR 精确延时
来源: 原创
发表评论 阅读全文(2379) | 回复(1)

4

关于投票
AVR的两种位操作的比较(位域方式和移位宏方式)

AVR的两种位操作的比较(位域方式和移位宏方式)

测试环境如下:
硬件:AT90S2313
软件:    WiinAVR gcc3.3   -Os级优化(最小size)。


说明:
    由于AVR不支持位操作,所以必须通过软件来实现。下面对我所知道的两种方法进行一个简单的比较。
    1、位域方式。先定义一个位域,
            typedef struct _bit_struct
            {
                unsigned char bit0 : 1 ;
                unsigned char bit1 : 1 ;
                unsigned char bit2 : 1 ;
                unsigned char bit3 : 1 ;
                unsigned char bit4 : 1 ;
                unsigned char bit5 : 1 ;
                unsigned char bit7 : 1 ;
                unsigned char bit6 : 1 ;
            }bit_field;
        再用一个宏    ,来指向要操作的位。
             #define LED             GET_BITFIELD(PORTB).bit0
             #define BUTTON      GET_BITFIELD(PINB).bit7
        使用时只需要直接赋值即可:如LED =     0 ,LED = 1,  或者直接判断 LED==0    ,    LED ==1.
        这种方法类似C51中的位操作。直接。
    2、位移宏方式。主要有三个.
                #define Set_Bit(val, bitn)    (val |=(1<<(bitn)))
                #define Clr_Bit(val, bitn)     (val&=~(1<<(bitn)))
                #define Get_Bit(val, bitn)    (val &(1<<(bitn)) )
         三个分别用来设置某一位,清除某一位,取某一位的值.
           使用方法为.Set_Bit(PORTA,3);   Clr_Bit(PORTB,2);   Get_Bit(val,5);
    3、测试程序.
       说明,假设PORTB.7接按纽,PORTB.0 接LED
       测试程序完成如下操作。
 
       当BUTTON == 0时 ,LED输出1 否则输出0,
       这样的目的是即测试了输入,又测试了输出1和输出0,相对全面一点。  C代码如下.

                // testled.c     测试AVR的位操作.
                // 这是gcc;如是其它编译器,请修改。
                #include <avr/io.h>

                // 定义一个寄存器(Register)或端口(Port)的八个位
                typedef struct _bit_struct
                {
                    unsigned char bit0 : 1 ;
                    unsigned char bit1 : 1 ;
                    unsigned char bit2 : 1 ;
                    unsigned char bit3 : 1 ;
                    unsigned char bit4 : 1 ;
                    unsigned char bit5 : 1 ;
                    unsigned char bit7 : 1 ;
                    unsigned char bit6 : 1 ;
                }bit_field;

                  //定义一个宏,用来得到每一位的值
                #define GET_BITFIELD(addr) (*((volatile  bit_field *) (addr)))

                //定义每一个位
                #define LED         GET_BITFIELD(PORTB).bit0
                #define BUTTON      GET_BITFIELD(PINB).bit7


                #define Set_Bit(val, bitn)    (val |=(1<<(bitn)))
                #define Clr_Bit(val, bitn)    (val&=~(1<<(bitn)))
                #define Get_Bit(val, bitn)    (val &(1<<(bitn)) )

                int main( void )
                {
                    DDRB = 0x41;   //配置PB0为输出,PB7为输入
                    if ( BUTTON==0 )     LED = 1; else LED = 0;
                    //if(!Get_Bit(PINB,7) )  Set_Bit(PORTB,0);    else Clr_Bit(PORTB,0);
                    while(1);
                }
      //     ----------------------        end         -----------------------------
    4、测试过程。
       a.先使用位域方式。
       主程序中使用 if ( BUTTON==0 )     LED = 1; else LED = 0;
       结果如下:
                     int main( void )
                    {
                      4a:    cf ed           ldi    r28, 0xDF    ; 223
                      4c:    d0 e0           ldi    r29, 0x00    ; 0
                      4e:    de bf           out    0x3e, r29    ; 62
                      50:    cd bf           out    0x3d, r28    ; 61
                        DDRB = 0x41;      //配置PB0为输出,PB7为输入
                      52:    81 e4           ldi    r24, 0x41    ; 65
                      54:    87 bb           out    0x17, r24    ; 23
                        if ( BUTTON==0 )     LED = 1; else LED = 0;
                      56:    86 b3           in    r24, 0x16    ; 22
                      58:    e8 2f           mov    r30, r24
                      5a:    ff 27           eor    r31, r31
                      5c:    80 81           ld    r24, Z
                      5e:    86 fd           sbrc    r24, 6
                      60:    07 c0           rjmp    .+14         ; 0x70
                      62:    88 b3           in    r24, 0x18    ; 24
                      64:    e8 2f           mov    r30, r24
                      66:    ff 27           eor    r31, r31
                      68:    80 81           ld    r24, Z
                      6a:    81 60           ori    r24, 0x01    ; 1
                      6c:    80 83           st    Z, r24
                      6e:    06 c0           rjmp    .+12         ; 0x7c
                      70:    88 b3           in    r24, 0x18    ; 24
                      72:    e8 2f           mov    r30, r24
                      74:    ff 27           eor    r31, r31
                      76:    80 81           ld    r24, Z
                      78:    8e 7f           andi    r24, 0xFE    ; 254
                      7a:    80 83           st    Z, r24
                        while(1);
                      7c:    ff cf           rjmp    .-2          ; 0x7c

main函数共52Bytes.其中,从lst文件看得出:main函数的初始化用了4条指令,8Bytes. 最后一句while(1);用了1条指令2Bytes.( for循环和do-while也是)
         DDRB="0x41用了2条指令4Bytes". 计算一下:52-8-4-2=38Bytes,即if ( BUTTON==0 )     LED = 1; else LED = 0; 这句用了19条指令38Bytes. (居然运用了3个寄存器白r24,r30,r31,和一个Z,代码真是苦涩,,我看不懂,准备以后作代码加密用:).  )
       b.使用移位宏方式。
       将 if ( BUTTON==0 )     LED = 1; else LED = 0;  换为等效的     if(!Get_Bit(PINB,7) )  Set_Bit(PORTB,0);    else Clr_Bit(PORTB,0);

       结果,main函数仅24Bytes.其它代码一样,略去. 所以,上面这句代码仅用了24-14=10Bytes ,5条指令。生成的代码如下:
              56:    b7 99           sbic    0x16, 7    ; 22
              58:    02 c0           rjmp    .+4          ; 0x5e
              5a:    c0 9a           sbi    0x18, 0    ; 24
              5c:    01 c0           rjmp    .+2          ; 0x60
              5e:    c0 98           cbi    0x18, 0    ; 24
    5. 菜论:鱼和熊掌。
      由于AVR可以对I/O脚进行sbic,sbi,cbi,这样的位操作,所以使用I/O脚操作时,移位宏可以产生高效的代码。
      例如,要实现上面的几个简单的指令,为了实现LED=1这样的类似C51的sbit的效果,我必须多付出(38-10=28Bytes)的代价。

    6......
        对于I/O脚,可以产生这样高效的代码,是因为有sbi和cbi这样的指令,那么对于一般的变量,又如何呢?................

 

 

系统分类: 软件开发
用户分类: 侃单片机
标签: AVR 位操作
来源: 无分类
发表评论 阅读全文(1261) | 回复(0)

4

关于投票
ADuC845最小系统及代码下载

ADuC845是高性能51内核的单片机,能兼容标准的51代码,应用起来也跟51很相近。例如,使用内部ROM时,把/EA脚拉高等等。只要是熟悉普通51单片机,就可以轻松上手。

下面是我使用的ADuC845的最小系统原理图:

点击看大图

把代码(HEX文件)下载到ADuC845去:

ADuC845的代码下载很方便,只要一个RS232的串口便可。它是通过串口ISP的。

你可以到ADI公司的网站上下载ISP软件。
http://www.analog.com/en/content/0,2886,762%255F%252D1%255F66633,00.html
把滚动条拉到最底下,那个WSD 6.7 (Windows Serial Downloader V6.7)就是了。

下面介绍串口ISP流程:

1.打开ISP软件:

点击看大图

2.配置ISP软件

点击看大图

3、把ADuC845的TxD脚与RxD脚通过RS232与PC机的连接好,ADuC845的/PSEN脚接到地,按RESET重启。

4、点击ISP软件的download,在弹出的小对话框中,选择你要下载的HEX文件,然后按确定。不用几秒就可以完成ISP下载。

点击看大图

5、如果弹出如下界面,请检查你的ADuC845系统的电源,连接,晶振设置是否,管脚设置是否正确。

点击看大图

系统分类: 单片机
用户分类: 侃单片机
标签: ADuC845
来源: 原创
发表评论 阅读全文(2436) | 回复(4)

4

关于投票
使用KEILUV3开发高性能单片机ADuC845

       ADuC845是ADI公司新推出的嵌有单指令周期8052闪存MCU、带两路24位Σ 一AA/D、双
l2位D/A以及两个灵活脉宽调制输出的高性能24位数据采集与处理系统芯片。该芯片的数据处
理速度达12 MIPS,且设计简单,噪声低,非常适用于精密仪器仪表。

      下面是ADUC845的管脚图:

                                                点击看大图

      这是它的官方资料:

                      rar

    下面介绍用KEIL UV3写ADuC845的代码:

      新建一个工程

    点击看大图

                       

    输入工程名,保存

 点击看大图

  选择CPU类型--->Analog   Devices  -->ADuC845,按确定

点击看大图           

开始写代码,先新建一个新的文本区,点下图红色按钮。

点击看大图

写完代码,保存为.c文件

点击看大图

把c文件添加到你的工程中:

点击看大图

                                            点击看大图

配置编译选项:

点击看大图

开始编译,链接:

点击看大图

在你的工程文件夹可以找到生成的HEX文件了:

点击看大图

系统分类: 单片机
用户分类: 侃单片机
标签: ADuC845
来源: 原创
发表评论 阅读全文(1289) | 回复(0)

2

关于投票
8051的汇编控制指令占用字节执行周期列表
8051 INSTRUCTION SET

1.Arithmetic operations:
   
    Mnemonic            Byte    Cyc
    ADD   A,@Ri 1 1
    ADD   A,Rn 1 1        
    ADD   A,direct 2 1        
    ADD   A,#data 2 1        
    ADDC  A,@Ri 1 1           
    ADDC  A,Rn 1 1     
    ADDC  A,direct 2 1           
    ADDC  A,#data 2 1     
    SUBB  A,@Ri 1 1     
    SUBB  A,Rn 1 1     
    SUBB  A,direct 2 1     
    SUBB  A,#data 2 1     
    INC   A 1 1
    INC   @Ri 1 1
    INC   Rn 1 1
    INC   DPTR 1 1
    INC   direct 2 1
    INC   direct 2 1
    DEC   A 1 1
    DEC   @Ri 1 1
    DEC   Rn 1 1
    DEC   direct 2 1
    MUL    AB 1 4
    DIV   AB 1 4
    DA      A 1 1

2.Logical opreations:
    ANL   A,@Ri 1 1
    XRL   A,@Ri 1 1
    ANL   A,Rn 1 1
    XRL   A,Rn 1 1
    ANL   A,direct          2 1
    XRL   A,direct   2 1
    ANL   A,#data          2 1   
    XRL   A,#data          2 1
    ANL   direct,A   2 1   
    XRL   direct,A          2 1
    ANL   direct,#data 3 2
    XRL   direct,#data 3 2
    ORL   A,@Ri 1 1
    CLR   A 1 1
    ORL   A,Rn 1 1
    CPL   A 1 1
    ORL   A,direct  2 1    
     RL   A 1 1
    ORL   A,#data 2 1
    RLC   A 1 1
    ORL   direct,A 2 1  
    RR   A 1 1
    ORL   direct,#data 3 2
    RRC   A 1 1
    SWAP  A 1 1

3.Data transfer:
    Mnemonic            Byte Cyc
    MOV   A,@Ri 1 1
    MOV   DPTR,#data16 3 2
    MOV   A,Rn 1 1
    MOVC  A,@A+DPTR 1 2
    MOV   A,direct          2 1   
    MOVC  A,@A+PC          1 2
    MOV   A,#data          2 1    
    MOVX  A,@Ri 1 2
    MOV   @Ri,A 1 1
    MOVX  A,@DPTR          1 2
    MOV   @Ri,direct 2 2   
    MOVX  @Ri,A 1 2
    MOV   @Ri,#data 2 1   
    MOVX  @DPTR,A          1 2
    MOV   Rn,A 1 1    
    PUSH  direct          2 2
    MOV   Rn,direct 2 2    
    POP   direct          2 2
    MOV   Rn,#data          2 1  
    XCH   A,@Ri 1 1
    MOV   direct,A     2 1   
    XCH   A,Rn 1 1
    MOV   direct,@Ri 2 2   
    XCH   A,direct   2 1
    MOV   direct,Rn 2 2   
    XCHD  A,@Ri 1 1
    MOV   direct,direct     3 2
    MOV   direct,#data 3 2

4.Boolean variable manipulation:
    Mnemonic            Byte Cyc
    CLR   C 1 1
    ANL   C,bit 2 2
    SETB  C 1 1
    ANL   C,/bit          2 2
    CPL   C 1 1  
   ORL   C,bit 2 2
    CLR   bit 2 1
    ORL   C,/bit          2 2
    SETB  bit 2 1  
   MOV   C,bit 2 1
    CPL   bit 2 1  
   MOV   bit,C 2 2

5.Program and machine control:
    Mnemonic            Byte Cyc
    NOP 1 1
    JZ    rel 2 2
    RET 1 2
    JNZ   rel 2 2
    RETI          1 2  
    JC    rel 2 2
    ACALL addr11          2 2   
    JNC   rel 2 2
    AJMP  addr11     2 2     
    JB    bit,rel          3 2
    LCALL addr16          3 2   
    JNB   bit,rel          3 2
    LJMP  addr16          3 2  
    JBC   bit,rel          3 2
    SJMP  rel 2 2  
   CJNE  A,direct,rel 3 2
    JMP   @A+DPTR          1 2
    CJNE  A,#data,rel 3 2
    DJNZ  Rn,rel          2 2  
   CJNE  @Ri,#data,rel 3 2
    DJNZ  direct,rel 3 2  
   CJNE  Rn,#data,rel 3 2
系统分类: 单片机
用户分类: 侃单片机
标签: 8051指令
来源: 转贴
发表评论 阅读全文(754) | 回复(0)
Total , Page /