Hani Kanaan
Hani Kanaan

Reputation: 1

PWM output always 0 on proteus (using atmega328p and assembly on microchip studio to write the code)

i am currently trying to setup a servo motor on a proteus circuit using a PWM signal (TCR0) on the atmega328p , i went through several manual books to setup the bits in the TCCR0A and TCCR0B registers and the duty cycle value on OCR0A and expect an output on the OCR0A port.


.INCLUDE "M328PDEF.INC"
.ORG 0x00

 SBI DDRD , 6 // port D6 output for PWM 
 
 LOOP:
 CALL TESTN
 CALL delay
 JMP LOOP
TESTN:  
    LDI R20 , 127 //duty cycle value (50%)
    STS OCR0A , R20 // duty cycle on OCR0A
    LDI R17 , 0b10000011
    STS TCCR0A , R17 //Non-Inverting Fast PWM mode 3 using OCRA 
    LDI R18 , 0b00000001
    STS TCCR0B , R18 //No-Prescalar
    //LDS R20 , OCR0A // trying to output on port D6 but maybe doesnt matter
    //OUT PORTD , R20
    

delay:
    LDI R16 , 1
        L0: LDI R17 , 1
            L1: LDI R18 , 20
                L2: DEC R18
                    BRNE L2
                    DEC R17
                    BRNE L1
                    DEC R16
                    BRNE L0
                    RET

proteus circuit results

Can anyone tell me what i am missing ? Any help is appreciated ,thanks in advance

I expected to receive a signal on portD,6 which will result in a movement of the servo but the output is always 0 on that port (not sure why other ports have output values without actually defining anything regarding them) Edit : if anyone knows a good compiler from C to avr assembly it would be appreciated.

Upvotes: 0

Views: 339

Answers (2)

Hani Kanaan
Hani Kanaan

Reputation: 1

Turns out i needed prescaling since the atmega32p has 18MHz processor speed which wont provide the 20ms duration signal needed by a servo motor. I used 8 prescaling (TCCR0B = 0b00000100) and adjust the angle through the OCR0A values.

Upvotes: 0

AterLux
AterLux

Reputation: 4654

It would be much simpler if you write the code in C and then look at the disassembly.

Note: Timer0 registers (TCCR0A, TCCR0B, OCR0A etc) are in the lower range of I/O-registers and can be accessed both by memory access operations (like STS, LDS) using their memory address, and also can be accessed by IN and OUT operations, using their I/O-register number.

How your constant are declared? For example, if TCCR0A equals to 0x44, then it is a memory address, and STS should be used. But if it equals to 0x24 then it is IO-register number and OUT should be used instead.

Also, there is no ret at the end of TESTN in your code

Upvotes: 0

Related Questions