Декодер ШИМ на Atmel AVR

0хCB
От пользователя timsa™
три канала.
газ, руль, коробка скоростей
но идут каждый по своему отдельному проводку.

теперь понятно. вот получил контроллер длительности каналов и посчитал их значения, дальше чего с ними делать? чего дергать/крутить/выдавать и куда?
0
timsa™
От пользователя FGV
чего дергать/крутить/выдавать и куда?


в первом проекте тупо включать светодиодные фары, мигать поворотниками и т.д.

дальше видно будет :-)
0
Мoзгoпрaв и мoзгoвeд©
От пользователя ITihonov
нет, я вобще планировал не PIC16F делать, но случайно увидал даташит на STM32F102/103 и он я вам скажу, по встроенной переферии и цене гораздо больше устраивает. :-)

а если надо что-то мелкое, то мне нравится pic10f200. опять же - ценой.

от avr стало подташнивать после сношания с usb в atmega32u4. даташит - полный шит. ну и с перефереией там херня какая-то, например долбанутое ограничение на конфигурацию мультиплексора в дифференциальном режиме с усилителем.


Я уже третий большой проект заканчиваю на стмках, пересели на них иза атмела - с его сроками...

да и хмеги тоже еще то удовольствие конфигурировать...
рекомендую так же посмотреть на стмки 8, там перефирия такая же как 32 серии, но ядро 8 бит, цена в два раза дешевше, эт минимум

От пользователя ITihonov
да нифига, он есть у:

ATtiny2313
ATtiny24
ATtiny44
ATtiny84
ATtiny261
ATtiny461
ATtiny861
ATtiny48
ATtiny88
ATtiny24A
ATtiny44A
ATtiny10
ATtiny4
ATtiny5
ATtiny9
ATtiny261A
ATtiny461A
ATtiny861A
ATtiny2313A
ATtiny4313
ATtiny167
ATtiny87
ATtiny20
ATtiny40

тут больше чем 8 ног...
0
0хCB
От пользователя timsa™
в первом проекте тупо включать светодиодные фары, мигать поворотниками и т.д.

тада тини13 хватит (ессли три оставшихся ноги хватит)

От пользователя timsa™
дальше видно будет

тут на ченить более большое переползать придется
0
От пользователя timsa™
просто я не пробовал работать с прерываниями на С.
щас как раз изучаю этот момент. может действительно будет проще.

вполне даже просто. подключаешь библиотеку и все. обработка прерывания - просто отдельной функцией с именем прерывания. по прерыванию вызывается эта функция.. и все

[Сообщение изменено пользователем 21.04.2011 10:55]
1 / 0
От пользователя FGV
тока у тини 10 icp помоему всетаки нету


я ж не из головы говорю. зашел на сайт микрочипа, там табличко, в ней графа Input Capture. :-)

http://www.atmel.com/dyn/products/param_table.asp?...
0
От пользователя Мозгоправ и мозговед
тут больше чем 8 ног...


Ну.... ATtiny4/5/9/10 в UDFN-8 есть, как раз восемь ног. Либо SOT23-6, вобще шесть.

другой вопрос, что это не DIP и промэлектроника их не возит.

[Сообщение изменено пользователем 21.04.2011 13:21]
0
От пользователя FGV
вот получил контроллер длительности каналов и посчитал их значения, дальше чего с ними делать? чего дергать/крутить/выдавать и куда?

Куда-куда..............в шим и на выход :-D
0
0хCB
От пользователя ITihonov
Я ж не из головы говорю. зашел на сайт микрочипа, там табличко, в ней графа Input Capture.

ага, разобрался. старые у мну пдфки были :-)
написано почему то тини 10/11/12/13... хз откуда
0
Мoзгoпрaв и мoзгoвeд©
От пользователя mainroot
вполне даже просто. подключаешь библиотеку и все. обработка прерывания - просто отдельной функцией с именем прерывания. по прерыванию вызывается эта функция.. и все


void PCINT0_ISR( void ) //можно так, там по разному можно )
{
unsigned char *pTemp;
fastTemp.word = ((PIN_HALL & hallMask)>>1); // Read Hall, Mask Pins, shift to use as pointer offset

pTemp = pDrvPattern + fastTemp.word;

PORT_MC = *(pTemp); //Change drive levels on high side

TCCR0A = *(pTemp + PATTERN_COM0_OFFSET); // Reconfigure output compare operation for T0
TCCR2A = *(pTemp + PATTERN_COM2_OFFSET); // Reconfigure output compare operation for T2
count--;
}
0
Мoзгoпрaв и мoзгoвeд©
ну или так:

ISR(TIMER2_OVF_vect)
{
//TCNT2 = (unsigned char)~tout; //Reload timer
flag = flag|(1<<timer0set);
if(flag&(1<<RX))
{
// if(srxd.buff[0]==eeprom.MCUADDR)
{
flag = (flag&(~(1<<RX)));
flag = flag|(1<<CMD);
srxd.len = srxd.index-1;
srxd.index = 0;
TCNT2 = 0;
}
}
}

ISR(USART0_TX_vect)
{
if (stxd.len>1)
{
UDR = stxd.buff[stxd.index];
stxd.index++;
stxd.len--;
}
}
0
timsa™
Сильно не смейтесь. Попытался решить задачу "в лоб". Еще не проверял.

Исходник:
#include <avr/io.h>
#include <avr/iom32.h>
#include <avr/interrupt.h>
#include <util/delay.h>

// 3 входа шим
#define	THROTTLE_PWM	1	// PB1
#define	STEERING_PWM	2	// PB2
#define	GEAR_PWM		3	// PB3
// 6 выходов на индикаторы
#define	LEFT_LIGHT		0	// PA0
#define	RIGHT_LIGHT		1	// PA1
#define	FWD_LIGHT		2	// PA2
#define	REAR_LIGHT		3	// PA3
#define	DAY_LIGHT		4	// PA4
#define	STOP_LIGHT		5	// PA5
// 2 входа кнопок реверса руля и газа
#define	REV_THROTTLE	6	// PA6
#define	REV_STEERING	7	// PA7
// порт ламп
#define	LIGHT_PORT		PORTA
// порт кнопок
#define	BTN_PORT		PORTA
// порт шим
#define	PWM_PORT		PORTB
// зазор нуля
#define	TRESHHOLD		30

// глобальный таймер с периодичностью 0,1мс
volatile unsigned long dmsec;

// инициализация проца
void init(void) {
	// порты
	DDRB = 0<<THROTTLE_PWM|0<<STEERING_PWM|0<<GEAR_PWM;
	DDRA = 1<<LEFT_LIGHT|1<<RIGHT_LIGHT|1<<FWD_LIGHT|1<<REAR_LIGHT|1<<DAY_LIGHT|1<<STOP_LIGHT|0<<REV_THROTTLE|0<<REV_STEERING;
	LIGHT_PORT = 0<<STOP_LIGHT|0<<FWD_LIGHT|0<<REAR_LIGHT|0<<DAY_LIGHT|0<<LEFT_LIGHT|0<<RIGHT_LIGHT;

	// таймер (толком не настроен, должен тикать 10000 раз в секунду)
	TCCR0 = (1<<WGM01)|(1<<CS02);
	TIMSK = (1<<7);
	OCR0 = 173;

	dmsec = 0;
}

void StopLightOn(void) {
	LIGHT_PORT |= 1<<STOP_LIGHT;
}

void StopLightOff(void) {
	LIGHT_PORT &= ~(1<<STOP_LIGHT);
}

void FwdLightOn(void) {
	LIGHT_PORT |= 1<<FWD_LIGHT;
}

void FwdLightOff(void) {
	LIGHT_PORT &= ~(1<<FWD_LIGHT);
}

void RearLightOn(void) {
	LIGHT_PORT |= 1<<REAR_LIGHT;
}

void RearLightOff(void) {
	LIGHT_PORT &= ~(1<<REAR_LIGHT);
}

void DayLightOn(void) {
	LIGHT_PORT |= 1<<DAY_LIGHT;
}

void DayLightOff(void) {
	LIGHT_PORT &= ~(1<<DAY_LIGHT);
}

void LeftLightOn(void) {
	LIGHT_PORT |= 1<<LEFT_LIGHT;
}

void LeftLightOff(void) {
	LIGHT_PORT &= ~(1<<LEFT_LIGHT);
}

void RightLightOn(void) {
	LIGHT_PORT |= 1<<RIGHT_LIGHT;
}

void RightLightOff(void) {
	LIGHT_PORT &= ~(1<<RIGHT_LIGHT);
}


// обработка прерывания
ISR (TIMER0_COMP_vect) {
	++dmsec;
}

int main(void) {

	// инициализируем порты и прочее
	init();

	// два раза мигнем аварийкой
	LeftLightOn();
	RightLightOn();
	_delay_ms(200);
	LeftLightOff();
	RightLightOff();
	_delay_ms(300);
	LeftLightOn();
	RightLightOn();
	_delay_ms(200);
	LeftLightOff();
	RightLightOff();

	// подождем 2 секунды для того чтобы приемник стартовал
	_delay_ms(2000);

	StopLightOn();
	_delay_ms(200);
	FwdLightOn();
	_delay_ms(200);
	RearLightOn();
	_delay_ms(200);
	RearLightOff();
	_delay_ms(200);
	FwdLightOff();
	_delay_ms(200);
	StopLightOff();
	_delay_ms(1000);

	// включим ближний свет
	DayLightOn();

	sei();

	volatile unsigned int throttle_timer, steering_timer;
	volatile unsigned int throttle_default, steering_default;
	volatile unsigned int throttle_counter, steering_counter;
	volatile unsigned char prev_throttle, prev_steering;

	// определяем нулевое положение
	throttle_timer = 0;
	throttle_default = 0;
	throttle_counter = 0;
	prev_throttle = 0;
	steering_timer = 0;
	steering_default = 0;
	steering_counter = 0;
	prev_steering = 0;
	while(dmsec<20000) { // крутимся 2 секунды или 100 циклов ШИМ
		// газ
		if((PWM_PORT & THROTTLE_PWM) == 1) { // высокий уровнень
			prev_throttle = 1;
			throttle_timer++;
		} else { // низкий уровнень
			if(prev_throttle == 1) { // это задний фронт
				prev_throttle = 0;
				throttle_default += throttle_timer;
				throttle_counter++;
				throttle_timer = 0;
			}
		}
		// руль
		if((PWM_PORT & STEERING_PWM) == 1) { // высокий уровнень
			prev_steering = 1;
			steering_timer++;
		} else { // низкий уровнень
			if(prev_steering == 1) { // это задний фронт
				prev_steering = 0;
				steering_default += steering_timer;
				steering_counter++;
				steering_timer = 0;
			}
		}
	}
	throttle_default = throttle_default / throttle_counter;
	steering_default = steering_default / steering_counter;

	// главный цикл
	throttle_timer = 0;
	prev_throttle = 0;
	steering_timer = 0;
	prev_steering = 0;
	while(1) {
		// газ
		if((PWM_PORT & THROTTLE_PWM) == 1) { // высокий уровнень
			prev_throttle = 1;
			throttle_timer++;
		} else { // низкий уровнень
			if(prev_throttle == 1) { // это задний фронт
				prev_throttle = 0;
				if(throttle_timer > (throttle_default+TRESHHOLD)) {
					FwdLightOn();
				} else if(throttle_timer < (throttle_default-TRESHHOLD)) {
					RearLightOn();
				} else {
					FwdLightOff();
					RearLightOff();
				}
				throttle_timer = 0;
			}
		}
		// руль
		if((PWM_PORT & STEERING_PWM) == 1) { // высокий уровнень
			prev_steering = 1;
			steering_timer++;
		} else { // низкий уровнень
			if(prev_steering == 1) { // это задний фронт
				prev_steering = 0;
				if(steering_timer > (steering_default+TRESHHOLD)) {
					RightLightOn();
					LeftLightOff();
				} else if(steering_timer < (steering_default-TRESHHOLD)) {
					LeftLightOn();
					RightLightOff();
				} else {
					LeftLightOff();
					RightLightOff();
				}
				steering_timer = 0;
			}
		}
		
	}

	return 0;
}
0
timsa™
AVR mega32 на 12МГц
0
0хCB
брррр. непонятно нифига.
таймер0 юзится тока для отсчета 2 секунд в начале? нафиг тада он вобще нужен? :-)
впринципе работать будет. но реализовано ... переферия контроллера не задействована почти

[Сообщение изменено пользователем 22.04.2011 20:12]
0
timsa™
От пользователя FGV
таймер0

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

а что непонятного?
0
0хCB
непонятно:
// 3 входа шим
#define THROTTLE_PWM 1 // PB1
#define STEERING_PWM 2 // PB2
#define GEAR_PWM 3 // PB3
це номера разрядов портов или маски битов? при ините портов юзиится как номера разрядов, при опросе портов - как маски разрядов :-)
0
timsa™
От пользователя FGV
це номера разрядов


это номера разрядов, в коментах я себе записал какая нога это физически на моей демоплате.

а при опросе написано с ошибкой, потому что я не знаю как правильно опросить состояние пина :-(
0
timsa™
Исходник:
// входы шим
#define THROTTLE_PWM 1
#define STEERING_PWM 2
// порт шим
#define PWM_PORT  PORTB

if((PWM_PORT & (1<<THROTTLE_PWM)) == 1) {
...


этот вариант опроса помоему тоже неправильный. или правильный?
0
timsa™
блин!
как же правильно опросить ножку?
0
От пользователя timsa™
как же правильно опросить ножку?


вот так:

Исходник:
if((PWM_PORT & (1<<STEERING_PWM))) { ... } 


ты делаешь x&(1<<2), оно же x&4 и оно равно либо 4 либо ноль, единицей быть не может.

кстати. когда будешь делать

Исходник:
if((PWM_PORT & (1<<GEAR_PWM))) { ... } 


оно будет x&8 -- либо 8 либо 0, единицей тоже никогда не будет.
0
0хCB
От пользователя ITihonov
оно будет x&8 -- либо 8 либо 0, единицей тоже никогда не будет.

а в си побарабану так то 8 или 1. 0-false, все что не ноль-true :-)
так что вариант с опросом if (PINB&(1<<номер_пина)) более кореектный
0
Мoзгoпрaв и мoзгoвeд©
От пользователя ITihonov
PWM_PORT &


это внутренняя защелка регистра выходного, что бы считать с ноги значение нужно:


От пользователя FGV
так что вариант с опросом if (PINB&(1<<номер_пина)) более кореектный
0
timsa™
ага, спасибо. я тоже уже немного разобрался что надо через пин и без ==1.
ща потестю в железе что получается.
0
От пользователя Мозгоправ и мозговед
Я уже третий большой проект заканчиваю на стмках, пересели на них иза атмела - с его сроками...

чо за сроки? или я чето пропустил?

От пользователя Мозгоправ и мозговед
да. многабукф. но именно это я и имел в виду как обработку прерывания. как на твоем примере про таймеры.


про опрос ножки - там все просто через if можно сделать... или нуно не опрос а прерывание по изменению состояния?

все остальное - многабукфкода... ниасилил.. иболень. коддить - коддю редко и давно такое было. только по спецзаказу

[Сообщение изменено пользователем 24.04.2011 12:43]
0
timsa™
возвращаясь к первоначальной теме :-)

всем спасибо за подсказки, программу я дописал, и она работает (в железе с реальным источником сигнала).
но, только если выключена оптимизация флаг "-O0". если же её собрать с любой другой оптимизацией, работа прекращается (первая часть, проверочное мигание лампочками работает, а вот дальше фиг знает что там происходит, но явно не то что надо).

как быть? переписывать все на асме? забить на оптимизацию?
размер без оптимизации 7кб, с оптимизацией 600б

дело в том что это не окончательное решение, есть еще вещи которые надо доделать (мигание поворотников например).
опять же нулевое положение ищется не совсем корректно (буду разбираться почему).
0
Авторизуйтесь, чтобы принять участие в дискуссии.