ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
26 ноября
68512 Топик полностью
AVR (11.09.2006 23:39, просмотров: 1) ответил GM на Так вот же он -->
В Вашем коде не хватает самой малости - самого кода. Изворачиваться больше не нужно, вот Вам то, что называют полным кодом Я не поленился накопипастить из двух мест и добавить двойную буферизацию для получения Phase and Frequency Correct PWM. Вот это - собственно 256-зубый ШИМ. Безвозвратно тратится 26 регистров из 32, R2..R25 - уставка ШИМ, R1 (tmp) - рабочий, R2 (pwm) - пила ШИМа. Таймер в режиме CTC - Clear On Compare (реинициализация и сброс флага автоматические):
;Один шаг пилы ШИМ - ISR таймера
t0isr:
	in	stsav,SREG	;Сохраняем статус. STSAV - общий для всех невложенных прерываний
 
	inc	pwm		;Добавляем очередной зуб к пиле ШИМ
	breq	reinit_PWM	;Загружаем новые значения уставок в начале каждого нового цикла ШИМ
 
	cp	r2,pwm		;Перенос=1 при Rx <= PWM		;Те же 2 такта на канал, что и у ПИКа
	rol	tmp		;Вдвигаем перенос в рабочий регистр	;
	cp	r3,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r4,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r5,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r6,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r7,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r8,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r9,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
 
	out	PORTA,tmp	;Выставляем ноги PWM 1..8
 
	cp	r10,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r11,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r12,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r13,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r14,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r15,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r16,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r17,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
 
	out	PORTB,tmp	;Выставляем ноги PWM 9..16
 
	cp	r18,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r19,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r20,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r21,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r22,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r23,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r24,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр
	cp	r25,pwm		;Перенос=1 при Rx <= PWM
	rol	tmp		;Вдвигаем перенос в рабочий регистр

PWM_reti: 
	out	PORTC,tmp	;Выставляем ноги PWM 17..24
 
	out	SREG,stsav	;Восстанавливаем статус
 
	reti

;Загрузка новых значений уставок и обнуление ШИМ-выходов в начале каждого нового цикла ШИМ
reinit_PWM:
	lds	r2,PWM_array+0	;Копируем 24 уставки из RAM в рабочие регистры ШИМ
	lds	r3,PWM_array+1
	lds	r4,PWM_array+2
	lds	r5,PWM_array+3
	lds	r6,PWM_array+4
	lds	r7,PWM_array+5
	lds	r8,PWM_array+6
	lds	r9,PWM_array+7

	lds	r10,PWM_array+8
	lds	r11,PWM_array+9
	lds	r12,PWM_array+10
	lds	r13,PWM_array+11
	lds	r14,PWM_array+12
	lds	r15,PWM_array+13
	lds	r16,PWM_array+14
	lds	r17,PWM_array+15

	lds	r18,PWM_array+16
	lds	r19,PWM_array+17
	lds	r20,PWM_array+18
	lds	r21,PWM_array+19
	lds	r22,PWM_array+20
	lds	r23,PWM_array+21
	lds	r24,PWM_array+22
	lds	r25,PWM_array+23

	clr	tmp

	out	PORTA,tmp	;Обнуляем ноги PWM 1-8
	out	PORTB,tmp	;Обнуляем ноги PWM 9-16
	rjmp	PWM_reti	;Обнуляем ноги PWM 17-24, используя хвост общей ISR, и выходим из ISR


;Процедура приема-разбора-раздачи уставок - ISR приема UART
;Формат команды - 2 байта (байт номера канала + байт уставки этого канала)
;Байт номера канала опознается по одновременно принятому UARTом 9-му биту (parity) = 1
;Буфер уставок (PWM_array) для удобства располагаем в самом начале RAM (с адреса 0x0100)
;или выравниваем по модулю 256
UARTrxISR:
        push    tmp             ;Сохраняем регистр, не сохраняем статус - он не затронется
 
        lds	tmp,UCSRB0	;Смотрим, что пришло - номер канала ШИМ или данные
        sbrs    UCSRB,RXB80	;
        rjmp    set_data
 
;set_addr:
        lds	tmp,UDR0         ;Читаем пришедший номер канала ШИМ из UART, сбрасываем флаг приема
        sts     PWMchan,tmp    	;Сохраняем его в ОЗУ
 
        pop     tmp             ;Восстанавливаем регистр
        reti            ;21 такт (1.05 мкс) вместе со входом при приеме номера канала
 
set_data:
        push    xl              ;Сохраняем регистр
        push    xh              ;Сохраняем регистр
 
        lds	tmp,UDR0	;Читаем пришедшую уставку из UART, сбрасываем флаг приема
        lds     xl,PWMchan	;Загружаем LSB указателя массива ШИМ
	cpi	xl,24		;Проверка границ массива
	brsh	PWM_err		;Игнорируем команду, если номер канала больше 23
        ldi     xh,high(PWM_arrray)	;Загружаем MSB указателя массива ШИМ
 
        st      x,tmp           ;Записываем уставку в буфер нужного канала ШИМ

PWM_err: 
        pop     xh              ;Восстанавливаем регистр
        pop     xl              ;Восстанавливаем регистр
        pop     tmp             ;Восстанавливаем регистр
        reti		;34 такта (1.7 мкс) вместе со входом при приеме уставки канала

;Итого 21+34=55 тактов, или 2.75 мкс на канал, или 2.75*24=66 мкс на все 24 канала
1. Накладные расходы по регистрам - 26 байт: 24 рабочих ШИМ, tmp и pwm. По RAM - 25 байт (буфер уставок ШИМ PWM_array[24] для двойной буферизации - обеспечения Phase and Frequency Correct PWM, и 1 байт указателя канала - PWMchan) 2. Накладные расходы по времени (вход-выход ISR, инкремент пилы, 4 вывода в порт, сохранение-восстановление статуса) - 18 тактов, или 18/24 = +0.75 такта к каждому каналу, что дает 18+(24*2)= 66 тактов на ISR или 2.75 такта на канал. При 100% загрузке 20-МИПСового АВРа (ATMega164/324/644) ТОЛЬКО этой задачей достижимая частота каждого из 24 каналов 256-ступенчатого ШИМ составит 20 МГЦ/66*256=1183 ГЦ. 3. Если для обновления уставок использовать UART, то для передачи всех 24-х двухбайтовых команд за 1 цикл ШИМ UART должен работать со скоростью не менее 576 КБод (при Fcy=20 MHZ можно с запасом выбрать 625 КБод). Все 24 уставки будут приняты, декодированы и розданы за 24*55=1320 тактов, или 66 мкс. При 100% загрузке 20-МИПСового АВРа (ATMega164/324/644) обеими задачами достижимая частота каждого из 24 каналов 256-ступенчатого ШИМ составит 20 МГЦ/((66*256)+1320)=1098 ГЦ. И вот теперь будьте добры привести в таком же полном и обсчитанном виде Ваш код. Подразумевается прием и формирование 24-х совершенно новых произвольных уставок ШИМ за один период, как это сделано у меня. Производительностью ШИМ будет считаться достигнутая частота ШИМ при 100% загрузке 20-МИПСового АВР класса ATMega164/324/664 всеми необходимыми задачами последовательно в едином цикле - прием по UART и дешифрация 24-х двухбайтовых команд, сортировка, формирование 24-х бит-массивов ШИМ, формирование 24-х сигналов ШИМ на 24-х выводах МК. А байки про огромную коммерческую ценность Вашего шедевра оставьте, пожалуйста, для другой аудитории - здесь, как видите, не прокатило, и придется Вам отдуваться бесплатно