Декодер ШИМ на Atmel AVR
х
0хCB
газ, руль, коробка скоростей
но идут каждый по своему отдельному проводку.
теперь понятно. вот получил контроллер длительности каналов и посчитал их значения, дальше чего с ними делать? чего дергать/крутить/выдавать и куда?
t
timsa™
чего дергать/крутить/выдавать и куда?
в первом проекте тупо включать светодиодные фары, мигать поворотниками и т.д.
дальше видно будет :-)
М
Мoзгoпрaв и мoзгoвeд©
а если надо что-то мелкое, то мне нравится pic10f200. опять же - ценой.
от avr стало подташнивать после сношания с usb в atmega32u4. даташит - полный шит. ну и с перефереией там херня какая-то, например долбанутое ограничение на конфигурацию мультиплексора в дифференциальном режиме с усилителем.
Я уже третий большой проект заканчиваю на стмках, пересели на них иза атмела - с его сроками...
да и хмеги тоже еще то удовольствие конфигурировать...
рекомендую так же посмотреть на стмки 8, там перефирия такая же как 32 серии, но ядро 8 бит, цена в два раза дешевше, эт минимум
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хCB
тада тини13 хватит (ессли три оставшихся ноги хватит)
тут на ченить более большое переползать придется
щас как раз изучаю этот момент. может действительно будет проще.
вполне даже просто. подключаешь библиотеку и все. обработка прерывания - просто отдельной функцией с именем прерывания. по прерыванию вызывается эта функция.. и все
[Сообщение изменено пользователем 21.04.2011 10:55]
тока у тини 10 icp помоему всетаки нету
я ж не из головы говорю. зашел на сайт микрочипа, там табличко, в ней графа Input Capture. :-)
http://www.atmel.com/dyn/products/param_table.asp?...
вот получил контроллер длительности каналов и посчитал их значения, дальше чего с ними делать? чего дергать/крутить/выдавать и куда?
Куда-куда..............в шим и на выход
х
0хCB
ага, разобрался. старые у мну пдфки были :-)
написано почему то тини 10/11/12/13... хз откуда
М
Мoзгoпрaв и мoзгoвeд©
вполне даже просто. подключаешь библиотеку и все. обработка прерывания - просто отдельной функцией с именем прерывания. по прерыванию вызывается эта функция.. и все
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--;
}
М
М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--;
}
}
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--;
}
}
t
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; } |
t
timsa™
AVR mega32 на 12МГц
х
0хCB
брррр. непонятно нифига.
таймер0 юзится тока для отсчета 2 секунд в начале? нафиг тада он вобще нужен? :-)
впринципе работать будет. но реализовано ... переферия контроллера не задействована почти
[Сообщение изменено пользователем 22.04.2011 20:12]
таймер0 юзится тока для отсчета 2 секунд в начале? нафиг тада он вобще нужен? :-)
впринципе работать будет. но реализовано ... переферия контроллера не задействована почти
[Сообщение изменено пользователем 22.04.2011 20:12]
t
timsa™
таймер0
действительно мало задействован. потому я и говорю что это решение "в лоб".
к тому же есть ошибки.
а что непонятного?
х
0хCB
непонятно:
// 3 входа шим
#define THROTTLE_PWM 1 // PB1
#define STEERING_PWM 2 // PB2
#define GEAR_PWM 3 // PB3
це номера разрядов портов или маски битов? при ините портов юзиится как номера разрядов, при опросе портов - как маски разрядов :-)
// 3 входа шим
#define THROTTLE_PWM 1 // PB1
#define STEERING_PWM 2 // PB2
#define GEAR_PWM 3 // PB3
це номера разрядов портов или маски битов? при ините портов юзиится как номера разрядов, при опросе портов - как маски разрядов :-)
t
timsa™
це номера разрядов
это номера разрядов, в коментах я себе записал какая нога это физически на моей демоплате.
а при опросе написано с ошибкой, потому что я не знаю как правильно опросить состояние пина :-(
t
timsa™
Исходник:// входы шим #define THROTTLE_PWM 1 #define STEERING_PWM 2 // порт шим #define PWM_PORT PORTB if((PWM_PORT & (1<<THROTTLE_PWM)) == 1) { ... |
этот вариант опроса помоему тоже неправильный. или правильный?
t
timsa™
блин!
как же правильно опросить ножку?
как же правильно опросить ножку?
как же правильно опросить ножку?
вот так:
Исходник:if((PWM_PORT & (1<<STEERING_PWM))) { ... } |
ты делаешь x&(1<<2), оно же x&4 и оно равно либо 4 либо ноль, единицей быть не может.
кстати. когда будешь делать
Исходник:if((PWM_PORT & (1<<GEAR_PWM))) { ... } |
оно будет x&8 -- либо 8 либо 0, единицей тоже никогда не будет.
х
0хCB
а в си побарабану так то 8 или 1. 0-false, все что не ноль-true :-)
так что вариант с опросом if (PINB&(1<<номер_пина)) более кореектный
М
Мoзгoпрaв и мoзгoвeд©
PWM_PORT &
это внутренняя защелка регистра выходного, что бы считать с ноги значение нужно:
так что вариант с опросом if (PINB&(1<<номер_пина)) более
кореектный
t
timsa™
ага, спасибо. я тоже уже немного разобрался что надо через пин и без ==1.
ща потестю в железе что получается.
ща потестю в железе что получается.
Я уже третий большой проект заканчиваю на стмках, пересели на них иза атмела - с его сроками...
чо за сроки? или я чето пропустил?
про опрос ножки - там все просто через if можно сделать... или нуно не опрос а прерывание по изменению состояния?
все остальное - многабукфкода... ниасилил.. иболень. коддить - коддю редко и давно такое было. только по спецзаказу
[Сообщение изменено пользователем 24.04.2011 12:43]
t
timsa™
возвращаясь к первоначальной теме :-)
всем спасибо за подсказки, программу я дописал, и она работает (в железе с реальным источником сигнала).
но, только если выключена оптимизация флаг "-O0". если же её собрать с любой другой оптимизацией, работа прекращается (первая часть, проверочное мигание лампочками работает, а вот дальше фиг знает что там происходит, но явно не то что надо).
как быть? переписывать все на асме? забить на оптимизацию?
размер без оптимизации 7кб, с оптимизацией 600б
дело в том что это не окончательное решение, есть еще вещи которые надо доделать (мигание поворотников например).
опять же нулевое положение ищется не совсем корректно (буду разбираться почему).
всем спасибо за подсказки, программу я дописал, и она работает (в железе с реальным источником сигнала).
но, только если выключена оптимизация флаг "-O0". если же её собрать с любой другой оптимизацией, работа прекращается (первая часть, проверочное мигание лампочками работает, а вот дальше фиг знает что там происходит, но явно не то что надо).
как быть? переписывать все на асме? забить на оптимизацию?
размер без оптимизации 7кб, с оптимизацией 600б
дело в том что это не окончательное решение, есть еще вещи которые надо доделать (мигание поворотников например).
опять же нулевое положение ищется не совсем корректно (буду разбираться почему).
Авторизуйтесь, чтобы принять участие в дискуссии.