Обсуждаем контроллеры компании Atmel.
Ответить

Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.

Вс сен 12, 2021 19:06:20

Сделал ШИМ на Т1 в режиме 8. Если останавливаю таймер разрядами CS12, CS11 и CS10 в момент когда на ноге OC1A высокий уровень, то на низкий уровень ногу переключить уже не получается. Почему? И как это сделать?

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вс сен 12, 2021 19:24:29

Либо битами FOC, либо отключить ногу от компаратора.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Пн сен 13, 2021 10:32:23

Потому что вы остановили таймер, но не отключили его. Ноги ШИМ все еще управляются значением счетчика. Если хотите отсоединить их, настройте COM1A1 или подобные

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Пн сен 13, 2021 13:23:29

Получается отключить таймер от ноги, но тогда при повторном подключении ШИМ начинает работать с того места, на котором была отключена нога от таймера. Т.е. отключили на высоком уровне на ноге, включается с высокого уровня на ноге и наоборот. Пытаюсь сбросить счетчик регистром TCNT1, но не помогает.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Пн сен 13, 2021 14:02:18

перед включением таймера нужно еще сбросить предделитель этого таймера. тогда таймер начнет работу сначала, а не с места остановки.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Пн сен 13, 2021 14:12:28

перед включением таймера нужно еще сбросить предделитель этого таймера

Предделитель ОДИН на ВСЕ таймеры!
Поэтому если у одного таймера предделитель на 8, а у другого на 64, то сбрасывая предделитель по первому таймеру, до второго может не дойти ни одного тика!

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вт сен 14, 2021 02:48:35

Когда настроен шим, и пин мк настроен как выход таймера, его состояние зависит от состояния таймера. Чтобы управлять пином мк, нужно отвязать пин мк от таймера.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вт сен 14, 2021 08:29:38

parovoZZ, так ты даже не знаешь, сколько предделителей в АТмега8.
общий предделитель только у таймера0 и таймера1. у таймера2 отдельный предделитель.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вт сен 14, 2021 09:59:06

Фраза
предделитель этого таймера

говорит об однозначности суждения.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вт сен 14, 2021 13:16:58

parovoZZ писал(а):Предделитель ОДИН на ВСЕ таймеры!
ну, твое-то высказывание вообще безграмотное.
а у таймера1 вполне конкретный предделитель, и я говорил именно о нем.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вт сен 14, 2021 13:57:52

Предделитель таймеров T0 и T1 сбрасывается битом PSR10, предделитель таймера T2 сбрасывается битом PSR2. Регистр - SFIOR.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вт сен 14, 2021 15:30:14

Вот и отлично, что почитал даташит. :)

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Пт сен 17, 2021 21:17:14

Starichok51 писал(а):перед включением таймера нужно еще сбросить предделитель этого таймера. тогда таймер начнет работу сначала, а не с места остановки.

В режиме "8" Т1 считает сначала в прямом, а потом в обратном направлении. А можно как-то после останова счетчика и записи в него (TCNT1) нового значения задать счетчику еще направление счета?

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Пт сен 17, 2021 22:53:21

не знаю, не пробовал.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Сб сен 18, 2021 17:44:58

задать счетчику еще направление счета?

читай даташит.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вс сен 19, 2021 20:56:05

У меня первый импульс получается в 2 раза короче, если ШИМ установить как неинвертированную и сбрасывать счетчик в 0. Если ШИМ инвертировать и установить начальную позицию TCNT1 в непосредственной близости от OCR1A (режим таймера "8"), то в зависимости от направления счета, при котором таймер был остановлен, мы получим различный результат при повторном запуске таймера. Либо это будет высокий уровень, либо это будет пауза перед высоким уровнем. Пока не придумал как решить эту особенность, чтобы ШИМ после останова таймера всегда начиналась с полноценного импульса.
Последний раз редактировалось Kalisnik Пн сен 20, 2021 09:12:25, всего редактировалось 3 раз(а).

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вс сен 19, 2021 21:48:24

а ты сделал сброс предделителя перед повторным запуском?

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Пн сен 20, 2021 12:39:52

Да, при отключении таймера делаю так:
Код:
SFIOR |= (1<<PSR10);


Добавлено after 3 hours 34 minutes 44 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
Хотя странно, комментирую эту строчку и ни чего не меняется. Может я как-то неправильно предделитель сбрасываю?
Спойлер
Код:
/*******************************************************

Chip type               : ATmega8A
Program type            : Application
AVR Core Clock frequency: 1,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*******************************************************/

#include <mega8.h>

// Declare your global variables here
int schetchik = 0;

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
   
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=Out Bit0=In
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (1<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=0 Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=P Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (1<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=(0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: Ph. & fr. cor. PWM top=ICR1
// OC1A output: Inverted PWM
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 2 s
// Output Pulse(s):
// OC1A Period: 2 s Width: 1 s
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (0<<WGM12) | (0<<CS12) | (1<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x3D;
ICR1L=0x09;
OCR1AH=0x1E;
OCR1AL=0x84;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<TOIE0);

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: Off
GICR|=(0<<INT1) | (1<<INT0);
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (1<<ISC00);
GIFR=(0<<INTF1) | (1<<INTF0);

// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
SFIOR=(0<<ACME);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Global enable interrupts
//#asm("sei")

while (1)
      {
      // Place your code here
          if(PIND.2 == 0 && schetchik == 1){
            schetchik = 0;
            TCCR1A|=(1<<COM1A1) | (1<<COM1A0);
            TCCR1B|=(1<<CS11) | (1<<CS10);
          }else if(schetchik == 0 && PIND.2 == 1){
            schetchik = 1;
            TCCR1B&=~((1<<CS11) | (1<<CS10));
            TCCR1A&=~((1<<COM1A1) | (1<<COM1A0));
            TCNT1 = 0x1E83;
            SFIOR |= (1<<PSR10);
          }
      }
}

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Пн сен 20, 2021 18:59:48

предделитель нужно сбрасывать перед запуском таймера, а не при его остановке.
иначе к повторному запуску предделитель окажется в неизвестном состоянии.

Re: Atmega8, ШИМ - низкий уровень на выводе после остановки

Вт сен 21, 2021 13:15:52

Сделал сброс предделителя перед запуском Т1, ни чего не поменялось. А как сбросить предделитель Т1 на ассемблере? Может дело в Си...
Ответить