Показаны сообщения с ярлыком программирование. Показать все сообщения
Показаны сообщения с ярлыком программирование. Показать все сообщения
пятница, 15 ноября 2013 г.
среда, 23 октября 2013 г.
Как писать передаточные функции на Си (Converting Transfer Functions to C Code)
http://www.slideshare.net/DelftOpenEr/ch1-9097263
EMBEDDED CONTROL
- if a feedback control function is to be implemented in software the transfer function can be converted to a C subroutine.
суббота, 12 октября 2013 г.
AVR - как избавиться от чисел с плавающей точкой
Одно из сильных ограничений AVR (на платформе MCS51 это сказывается не так) - быстрый расход памяти при написании программ на Си.
Что поделаешь, за удобства Си и скорость RISC надо платить. Еще больший соблазн - использование для вычислений (например, при измерении напряжений с помощью ADC) чисел float(числа с плавающей запятой). Несмотря на то, что эти вычисления не точны, их слишком просто и удобно применять - можно делить и умножать, не задумываясь о переполнении, и легко представлять результаты вычисления в формате, понятном человеку.
Но плата за float слишком высока - линкер добавляет код библиотек математики, и память программ кончается очень быстро. Другое ограничение - вычисления с float выполняются слишком медленно (если конечно не используется аппаратный перемножитель типа [1]). Если нет возможности реализовать алгоритм программы с применением чисел float (из-за вышеуказанных ограничений по объему кода и скорости), одним из вариантов решения проблемы является переход на числа сфиксированной запятой. Их математические операции (вычитание, сложение, деление, умножение) ничем не отличаются от математических операций с простыми целыми числами, код получается компактный и быстрый.
Число с фиксированной запятой (обычно байт или слово из двух байт) состоит из целой части(находится в старших битах 8 или 16-разрядного числа) и дробной части (находится в младших битах). Пример числа с фиксированной запятой указан на рисунке, с разрядностью в 8 бит (1 байт).

пятница, 4 октября 2013 г.
Программатор AVR USB на Atmega8
Источник http://www.getchip.net/posts/040-uartrs-232-to-usb-prostojj-preobrazovatel/
Наконец-то закончились праздники, и пришло время чего-нибудь сделать.
Начнем, пожалуй, с необходимого устройства, облегчающего жизнь рядового электронщика – устройства связи с компьютером. Это нужно для того, чтобы передать данные в компьютер (температура с датчиков, положение дверей, частота вращения двигателя, таблица значений с регистратора …) или принять данные из компьютера (таблицы значений для вычислений, настоечные данные для устройств, новая прошивка для загрузчика…). Для отладки нового устройства (посмотреть что там, в мозгах микроконтроллера, происходит) вообще незаменимая вещь.
Как Вы знаете, существует множество интерфейсов, посредством которых микроконтроллер может общаться с внешним миром. Но если речь идет о связи с компьютером – вне конкуренции интерфейс RS-232 (COM порт). Причина – простота работы с портом со стороны компьютера и наличие большого количества программ для этого предназначенных. Кроме того, почти в каждом микроконтроллере есть аппаратно поддерживаемый интерфейс USART (это тот-же RS-232, только с напряжениями 0 – 5v), что делает процесс связи легко реализуемым.
Для того, чтобы привести уровни сигнала микроконтроллерного USART к уровням COM порта компьютера нужно собрать несложный преобразователь (например, на МАХ232), но можно пойти по более интересному пути
Более интересный путь - собрать преобразователь UART to USB. При этом USB порт воспринимается компьютером как виртуальный COM порт. В этом случае мы убиваем сразу несколько зайцев:
– USB порт есть в любом компьютере (хотя COM порт встречается еще довольно часто, но на ноутбуках его уже нет);
– как оказалось преобразователь UART to COM(RS-232) сделать гораздо сложнее, чем UART to USB (два раза делал программатор для СОМ порта с преобразователем МАХ232 – оба раза неудачно);
– если подключать преобразователь через USB хаб, то мы получаем сразу несколько виртуальных COM портов на одном USB, плюс безопасность для компьютера, так как хаб выступает в роли буфера.
Как Вы знаете, существует множество интерфейсов, посредством которых микроконтроллер может общаться с внешним миром. Но если речь идет о связи с компьютером – вне конкуренции интерфейс RS-232 (COM порт). Причина – простота работы с портом со стороны компьютера и наличие большого количества программ для этого предназначенных. Кроме того, почти в каждом микроконтроллере есть аппаратно поддерживаемый интерфейс USART (это тот-же RS-232, только с напряжениями 0 – 5v), что делает процесс связи легко реализуемым.
Для того, чтобы привести уровни сигнала микроконтроллерного USART к уровням COM порта компьютера нужно собрать несложный преобразователь (например, на МАХ232), но можно пойти по более интересному пути
Более интересный путь - собрать преобразователь UART to USB. При этом USB порт воспринимается компьютером как виртуальный COM порт. В этом случае мы убиваем сразу несколько зайцев:
– USB порт есть в любом компьютере (хотя COM порт встречается еще довольно часто, но на ноутбуках его уже нет);
– как оказалось преобразователь UART to COM(RS-232) сделать гораздо сложнее, чем UART to USB (два раза делал программатор для СОМ порта с преобразователем МАХ232 – оба раза неудачно);
– если подключать преобразователь через USB хаб, то мы получаем сразу несколько виртуальных COM портов на одном USB, плюс безопасность для компьютера, так как хаб выступает в роли буфера.
Вот схема преобразователя UART to USB.
Сразу честно признаюсь – это не мое устройство. Взята данная схема с сайта www.recursion.jp/avrcdc/ . Причина, по которой я ее здесь привожу – это простота схемы и дешевизна изготовления. Собрать схему довольно просто (можно даже на макете).
Готовое устройство я выполнил в форме «флешки» для того, чтобы удобней было пользоваться в «полевых» условиях. Для большего комфорта можно взять USB удлинитель, одним разъемом прицепить к компьютеру, во второй вставить нашу «флешку-преобразователь» и получим мобильное устройство, которое можно без проблем подключить к любой схеме.
среда, 2 октября 2013 г.
понедельник, 30 сентября 2013 г.
пятница, 27 сентября 2013 г.
вторник, 24 сентября 2013 г.
четверг, 19 сентября 2013 г.
пятница, 13 сентября 2013 г.
Программирование множества кнопок
http://www.adafruit.com/blog/2009/10/20/example-code-for-multi-button-checker-with-debouncing/
#define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc byte buttons[] = {14, 15, 16, 17, 18, 19}; // the analog 0-5 pins are also known as 14-19 // This handy macro lets us determine how big the array up above is, by checking the size #define NUMBUTTONS sizeof(buttons) // we will track if a button is just pressed, just released, or 'currently pressed' byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS]; void setup() { byte i; // set up serial port Serial.begin(9600); Serial.print("Button checker with "); Serial.print(NUMBUTTONS, DEC); Serial.println(" buttons"); // pin13 LED pinMode(13, OUTPUT); // Make input & enable pull-up resistors on switch pins for (i=0; i< NUMBUTTONS; i++) { pinMode(buttons[i], INPUT); digitalWrite(buttons[i], HIGH); } } void check_switches() { static byte previousstate[NUMBUTTONS]; static byte currentstate[NUMBUTTONS]; static long lasttime; byte index; if (millis() < lasttime) { // we wrapped around, lets just try again lasttime = millis(); } if ((lasttime + DEBOUNCE) > millis()) { // not enough time has passed to debounce return; } // ok we have waited DEBOUNCE milliseconds, lets reset the timer lasttime = millis(); for (index = 0; index < NUMBUTTONS; index++) { justpressed[index] = 0; // when we start, we clear out the "just" indicators justreleased[index] = 0; currentstate[index] = digitalRead(buttons[index]); // read the button /* Serial.print(index, DEC); Serial.print(": cstate="); Serial.print(currentstate[index], DEC); Serial.print(", pstate="); Serial.print(previousstate[index], DEC); Serial.print(", press="); */ if (currentstate[index] == previousstate[index]) { if ((pressed[index] == LOW) && (currentstate[index] == LOW)) { // just pressed justpressed[index] = 1; } else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) { // just released justreleased[index] = 1; } pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed } //Serial.println(pressed[index], DEC); previousstate[index] = currentstate[index]; // keep a running tally of the buttons } } void loop() { check_switches(); // when we check the switches we'll get the current state for (byte i = 0; i < NUMBUTTONS; i++) { if (justpressed[i]) { Serial.print(i, DEC); Serial.println(" Just pressed"); // remember, check_switches() will CLEAR the 'just pressed' flag } if (justreleased[i]) { Serial.print(i, DEC); Serial.println(" Just released"); // remember, check_switches() will CLEAR the 'just pressed' flag } if (pressed[i]) { Serial.print(i, DEC); Serial.println(" pressed"); // is the button pressed down at this moment } } }
#define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc byte buttons[] = {14, 15, 16, 17, 18, 19}; // the analog 0-5 pins are also known as 14-19 // This handy macro lets us determine how big the array up above is, by checking the size #define NUMBUTTONS sizeof(buttons) // we will track if a button is just pressed, just released, or 'currently pressed' volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS]; void setup() { byte i; // set up serial port Serial.begin(9600); Serial.print("Button checker with "); Serial.print(NUMBUTTONS, DEC); Serial.println(" buttons"); // pin13 LED pinMode(13, OUTPUT); // Make input & enable pull-up resistors on switch pins for (i=0; i< NUMBUTTONS; i++) { pinMode(buttons[i], INPUT); digitalWrite(buttons[i], HIGH); } // Run timer2 interrupt every 15 ms TCCR2A = 0; TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20; //Timer2 Overflow Interrupt Enable TIMSK2 |= 1<<TOIE2; } SIGNAL(TIMER2_OVF_vect) { check_switches(); } void check_switches() { static byte previousstate[NUMBUTTONS]; static byte currentstate[NUMBUTTONS]; static long lasttime; byte index; if (millis() < lasttime) { // we wrapped around, lets just try again lasttime = millis(); } if ((lasttime + DEBOUNCE) > millis()) { // not enough time has passed to debounce return; } // ok we have waited DEBOUNCE milliseconds, lets reset the timer lasttime = millis(); for (index = 0; index < NUMBUTTONS; index++) { currentstate[index] = digitalRead(buttons[index]); // read the button /* Serial.print(index, DEC); Serial.print(": cstate="); Serial.print(currentstate[index], DEC); Serial.print(", pstate="); Serial.print(previousstate[index], DEC); Serial.print(", press="); */ if (currentstate[index] == previousstate[index]) { if ((pressed[index] == LOW) && (currentstate[index] == LOW)) { // just pressed justpressed[index] = 1; } else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) { // just released justreleased[index] = 1; } pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed } //Serial.println(pressed[index], DEC); previousstate[index] = currentstate[index]; // keep a running tally of the buttons } } void loop() { for (byte i = 0; i < NUMBUTTONS; i++) { if (justpressed[i]) { justpressed[i] = 0; Serial.print(i, DEC); Serial.println(" Just pressed"); // remember, check_switches() will CLEAR the 'just pressed' flag } if (justreleased[i]) { justreleased[i] = 0; Serial.print(i, DEC); Serial.println(" Just released"); // remember, check_switches() will CLEAR the 'just pressed' flag } if (pressed[i]) { Serial.print(i, DEC); Serial.println(" pressed"); // is the button pressed down at this moment } } }
четверг, 20 июня 2013 г.
Синхронизация таймеров STM32(Работают не синхронно)
http://forum.easyelectronics.ru/viewtopic.php?f=35&t=12983
Имеет место какой таймер запускать первым! Сначала необходимо запустить ведомый так как он не запустится пока не запустится ведущий.
Ведомый TIM3 запускаем первым
Ведущий TIM1 запускаем вторым.
void TIMERS_Start(void)
{
TIM_Cmd(TIM3, ENABLE);
TIM_Cmd(TIM1, ENABLE); // запуск таймера после инициализации АЦП и его синхронизации с TIMER3
TIM_CtrlPWMOutputs(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
#include "timer.h"
uint16_t TimerPeriod = 0;
uint8_t TIM1_HalfPeriodCNT = 1;
void TIMER1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
TimerPeriod = (SystemCoreClock / 40000) - 1;
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* Channel 1, 2, 3, 4 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
//PWM for Cell3_PWM_EN
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
//TIM_OC2FastConfig(TIM1, TIM_OCFast_Enable);
TIM_OCInitStructure.TIM_Pulse = 1;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
//PWM for Primary WIND and Cell3_PWM_OGR
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 2;
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
//TIM_OC3FastConfig(TIM1, TIM_OCFast_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_CCPreloadControl(TIM1, ENABLE);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* Automatic Output enable, Break, dead time and lock configuration*/
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRInitStructure.TIM_DeadTime = 0;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
// Allow interruput from TIM_1 update event
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE );
/* Master Mode selection */
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Enable);//TIM_TRGOSource_Enable);
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
}
//--------------------------------------
void TIMER3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TimerPeriod = (SystemCoreClock / 40000 ) - 1;
// Time Base configuration
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// PWM for
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1FastConfig(TIM3, TIM_OCFast_Enable);
// PWM for
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2FastConfig(TIM3, TIM_OCFast_Enable);
// PWM for
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3FastConfig(TIM3, TIM_OCFast_Enable);
// PWM for
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
TIM_OC4FastConfig(TIM3, TIM_OCFast_Enable);
TIM_CCPreloadControl(TIM3, ENABLE);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0);
}
//--------------------------------------
void TIMERS_Start(void)
{
TIM_Cmd(TIM3, ENABLE);
TIM_Cmd(TIM1, ENABLE); // запуск таймера после инициализации АЦП и его синхронизации с TIMER3
TIM_CtrlPWMOutputs(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
Имеет место какой таймер запускать первым! Сначала необходимо запустить ведомый так как он не запустится пока не запустится ведущий.
Ведомый TIM3 запускаем первым
Ведущий TIM1 запускаем вторым.
void TIMERS_Start(void)
{
TIM_Cmd(TIM3, ENABLE);
TIM_Cmd(TIM1, ENABLE); // запуск таймера после инициализации АЦП и его синхронизации с TIMER3
TIM_CtrlPWMOutputs(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
#include "timer.h"
uint16_t TimerPeriod = 0;
uint8_t TIM1_HalfPeriodCNT = 1;
void TIMER1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
TimerPeriod = (SystemCoreClock / 40000) - 1;
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* Channel 1, 2, 3, 4 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
//PWM for Cell3_PWM_EN
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
//TIM_OC2FastConfig(TIM1, TIM_OCFast_Enable);
TIM_OCInitStructure.TIM_Pulse = 1;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
//PWM for Primary WIND and Cell3_PWM_OGR
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 2;
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
//TIM_OC3FastConfig(TIM1, TIM_OCFast_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_CCPreloadControl(TIM1, ENABLE);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* Automatic Output enable, Break, dead time and lock configuration*/
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRInitStructure.TIM_DeadTime = 0;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
// Allow interruput from TIM_1 update event
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE );
/* Master Mode selection */
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Enable);//TIM_TRGOSource_Enable);
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
}
//--------------------------------------
void TIMER3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TimerPeriod = (SystemCoreClock / 40000 ) - 1;
// Time Base configuration
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// PWM for
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1FastConfig(TIM3, TIM_OCFast_Enable);
// PWM for
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2FastConfig(TIM3, TIM_OCFast_Enable);
// PWM for
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3FastConfig(TIM3, TIM_OCFast_Enable);
// PWM for
TIM_OCInitStructure.TIM_Pulse = TimerPeriod >> 3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
TIM_OC4FastConfig(TIM3, TIM_OCFast_Enable);
TIM_CCPreloadControl(TIM3, ENABLE);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0);
}
//--------------------------------------
void TIMERS_Start(void)
{
TIM_Cmd(TIM3, ENABLE);
TIM_Cmd(TIM1, ENABLE); // запуск таймера после инициализации АЦП и его синхронизации с TIMER3
TIM_CtrlPWMOutputs(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
среда, 19 июня 2013 г.
среда, 6 февраля 2013 г.
Операнды сдвига (умножение всегда влево, деление вправо)
http://rfe.by/media/kafedry/kaf4/publication/strikeleva/lekcija-04.pdf
1 2 3 4 5 6 7 8 9 10 11 12 соотв. 2 4 8 16 32 64 128 256 512 1024 2048 4096
1 2 3 4 5 6 7 8 9 10 11 12 соотв. 2 4 8 16 32 64 128 256 512 1024 2048 4096
четверг, 31 января 2013 г.
Keil ошибки с extern
http://electronix.ru/forum/lofiversion/index.php/t107394.html
Деннис Ритчи - стр 94 о том что объявление и определение переменной разные вещи. EXTERN когда и как правильно.
Деннис Ритчи - стр 94 о том что объявление и определение переменной разные вещи. EXTERN когда и как правильно.
Подписаться на:
Сообщения (Atom)