打印
[AVR单片机]

请教大家一个关于AVR-GCC的问题

[复制链接]
2998|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yuzhuen|  楼主 | 2007-12-23 12:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好,我的开发环境是AVR-STUDIO4.13 + WINAVR,M16L芯片,目前在做一个PWM输出程序,自认为对PWM各个寄存器对值已经了解得很透彻,但程序下载后PWM就是不按照我的意思运行,用来用软件仿真发现是AVR-GCC的问题,我的初始代码如下:
    //快速PWM模式
    DDRD |= _BV(PD5);
    
    TCCR1A = 0x00;
    TCCR1B = 0x00; //stop
    
    TCNT1L = 0x00;

    TCNT1H = 0x00; //
    
    OCR1AL = 0X00;
    OCR1AH = 0XFC;
    
    //TIMSK = TIMSK | 0X10;
    
    TCCR1A = 0x43;
    TCCR1B = 0x19; //start

软件仿真中看到初始化后各寄存器的值如下:

OCR1AH = 0X00
OCR1AL = 0X00

其它相关寄存器内空正确

请问大家能告诉我是在做地方出错吗?
谢谢!

相关帖子

沙发
jjl3| | 2007-12-23 13:42 | 只看该作者

对于16位寄存器应该先写入高位字节

试下:
OCR1AH = 0XFC;
OCR1AL = 0X00;

使用特权

评论回复
板凳
源于兴趣| | 2007-12-23 16:09 | 只看该作者

占座

使用特权

评论回复
地板
yuzhuen|  楼主 | 2007-12-23 22:56 | 只看该作者

数据手册上说应该先写低字节,再写高字节

因为在写低字节的同时,监时寄存器的内容会写入高字节.但是我看AVR-GCC编译后的汇编语言是这样的:
void timer1_init(void)
{
 1c2:    cf 93           push    r28
 1c4:    df 93           push    r29
 1c6:    cd b7           in    r28, 0x3d    ; 61
 1c8:    de b7           in    r29, 0x3e    ; 62
    
    DDRD |= _BV(PD5);
 1ca:    80 91 31 00     lds    r24, 0x0031
 1ce:    80 62           ori    r24, 0x20    ; 32
 1d0:    80 93 31 00     sts    0x0031, r24
    
    TCCR1A = 0x00;
 1d4:    10 92 4f 00     sts    0x004F, r1
    TCCR1B = 0x00; //start
 1d8:    10 92 4e 00     sts    0x004E, r1
    
    TCNT1L = 0x00;
 1dc:    10 92 4c 00     sts    0x004C, r1
    TCNT1H = 0x00; //REG = 65536 - (Fosc/分频)/Fobj)
 1e0:    10 92 4d 00     sts    0x004D, r1
    
    //OCR1AL = 0X00;
    //OCR1AH = 0X00;
    
    //OCR1AL = 0XFF;
    //OCR1AH = 0XEF;
    OCR1A = 0XEFff;
 1e4:    8f ef           ldi    r24, 0xFF    ; 255
 1e6:    9f ee           ldi    r25, 0xEF    ; 239
 1e8:    90 93 4b 00     sts    0x004B, r25
 1ec:    80 93 4a 00     sts    0x004A, r24
    
    ICR1L = 0XFF;
 1f0:    8f ef           ldi    r24, 0xFF    ; 255
 1f2:    80 93 46 00     sts    0x0046, r24
    ICR1H = 0XFF;
 1f6:    8f ef           ldi    r24, 0xFF    ; 255
 1f8:    80 93 47 00     sts    0x0047, r24

    TCCR1A = 0x82;
 1fc:    82 e8           ldi    r24, 0x82    ; 130
 1fe:    80 93 4f 00     sts    0x004F, r24
    TCCR1B = 0x19; //start
 202:    89 e1           ldi    r24, 0x19    ; 25
 204:    80 93 4e 00     sts    0x004E, r24
    
    TIMSK = TIMSK | 0X10;
 208:    80 91 59 00     lds    r24, 0x0059
 20c:    80 61           ori    r24, 0x10    ; 16
 20e:    80 93 59 00     sts    0x0059, r24
 212:    df 91           pop    r29
 214:    cf 91           pop    r28
 216:    08 95           ret

00000218 <disable_timer1>:
}

很明显编译后汇编是先写高字节再写低字节.
以上这一段代码是快速PWM模式14,比较匹配时OC1A清零,在TOP时置位.

程序将OCR1A赋值:0XEFFF,但是软件仿真是,执行OCR1A = 0XEFFF后,
OCR1A寄存器的值为0x01ff,真不明白错在哪里?

OC1A引脚也没有输入想象中的波形,匹配中断可以正常产生,不知哪里出错,请大家帮忙!

使用特权

评论回复
5
athlon64fx| | 2007-12-23 23:46 | 只看该作者

当作16位寄存器直接赋值:

OCR1A = 0x1234;

使用特权

评论回复
6
yuzhuen|  楼主 | 2007-12-23 23:56 | 只看该作者

发现新问题!

赋值时先赋高字节,后低字节是没问题的,但当工作模式变为PWM14时也就是
TCCR1A = 0x82;
TCCR1B = 0x19; 
时,OCR1A马上变回0x0x01ff,而且我发现在该模式下OCR1A最大值是0X01FF
反正关于PWM的问题我也没搞清楚,正在不断做实验,有什么问题会来和大家交流,也希望各位高手能帮帮我. 

使用特权

评论回复
7
yuzhuen|  楼主 | 2007-12-24 12:29 | 只看该作者

问题得到解决,所有问题都不是AVR-GCC的错!

大家好,以上所说的问题解决了,实际上AVR-GCC编译没问题,问题出在AVR-STUDIO的软件仿真上,软件仿真是对OCR1AH,OCR1L,ICR1读回的数据不正确,误导了我,同时的的"示波器"也有问题,我用声卡44KHz的采集通道,用COLD EDIT做波形显示,频率高一点的波形无能为力,最终导致我浪费了大家不少时间,实在抱歉!

使用特权

评论回复
8
hotpower| | 2007-12-24 12:33 | 只看该作者

~~~

使用特权

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

本版积分规则

40

主题

70

帖子

0

粉丝