Официальный сайт компании Arduino по адресу arduino.cc
Таймер 32F103
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Пт, 19/01/2018 - 16:46
Ребята помогите разобраться как этот код переделать чтобы работал на STM32F103.
// Set up timer 1. // Prescaler = 1, phase correct PWM mode, TOP = ICR1A TCCR1A = (1 << COM1A1) | (1 << WGM11); TCCR1B = (1 << WGM12) | (1 << WGM13) | (1 << CS10); // CTC mode, prescaler = 1 TCCR1C = 0; OCR1AH = (TIMER1_TOP/2 >> 8); OCR1AL = (TIMER1_TOP/2 & 0xFF); ICR1H = (TIMER1_TOP >> 8); ICR1L = (TIMER1_TOP & 0xFF); TCNT1H = 0; TCNT1L = 0; TIFR1 = 0x07; // clear any pending interrupt TIMSK1 = (1 << TOIE1);
Ща сс-овец придёт и всё будет :)
А остальные тут как предпочитают вот такое решение :)
Ребята помогите разобраться как этот код переделать чтобы работал на STM32F103.
чтобы это сделать, надо знать, для какого конкретного МК этот код. так как значения одних и тех же констант на разных контроллерах - разные.
Вообще, переписать этот таймер с AVR на STM сложнее, чем написать его с нуля сразу на STM. Так что если вы сформулируете, что должен делать таймер - задача упростится.
ну не все, Женя! Но и помочь тут не возможно.
ну не все, Женя!
Ну, не знаю, как Все, но Вы в той теме сказали примерно тоже, толь другими словами :))))
Прошу обратить внимание: изделие на STM32F103! Девица доверяет STM самое сокровенное! ;););)
Ребята помогите разобраться как этот код переделать чтобы работал на STM32F103.
Конкретно этот - никак... Надо писать другой код под STM.
Вообще, переписать этот таймер с AVR на STM сложнее, чем написать его с нуля сразу на STM. Так что если вы сформулируете, что должен делать таймер - задача упростится.
Спасибо за ответы!
программа от Atmega2560.
Важны буквы после 103. Важно в какой среде будет компилироваться программа. Важно какой таймер задействовать(1,2,3,4?). Важно аппаратно или программно выводить "волну" на ногу процессора. Нога любая или конкретная? Частота процессора(72 или 8 ?).
В STM не обязательно делить "системные часы". Давай точно что тебе надо. Тогда помогу. Иначе не получится.
Эти три строчки определяют частоту таймера 3. Первая делит частоту системы (72МГц) для тактирования таймера. Может быть от 1 до 2^16. Вторая строка количество тактов таймера. -1 что бы учесть ноль. Т.е. для 100 тактов надо написать число 99. Третья строка определяет на каком такте менять менять полярность. Для меандра и 100 тактов должно быть 100/2=50.
Чтобы поделить частоту на 10 можно в первой строчке написать 100, или во второй-третей 1000-1 и 500.
Спасибо за объяснения.
каждый таймер может работать только на одной частоте
Таймеры не могут быть не синхронными. Они тактируются от одного генератора. Сделай одинаковый делитель для таймеров (setPrescaleFactor(10);) Сделай запуск почти одновременно (pwmtimer3.resume(); pwmtimer2.resume();)
Убрал - void loop() - и работает ?
Конечно работает. Пустой loop() объявлен в недрах среды. Здесь перекрывается. Если не видно суслика, то он есть!
Можно подать на PA0 c выхода третьего таймера. Запрограмировать тактирование от внешнего источника и коэффициент деления 10. Или запрограмировать в режиме slave. Тогда можно обойтись без внешних соединений. Проблема в том, что я не нашёл в библиотеке таймера команды выбора источника тактирования. Придется писать через регистры типа
TIMER2->regs.gen->CCER = 0b0001;
Я такие вещи через stdlib писал в виде для таймера 2 - ведущего и таймера 3 ведомого
Большое спасибо за объяснения, я останусь с № 12.
Прерывание по переполнению таймера 1.
Инкремент переменной ticks.
Считывание значение счётчика таймера 0.
Считывание значения регистров данных АЦП.
Если значения счётчика таймера 0 не равны трём нижним битам предыдущего значения счетчика +1 то инкремент переменной misses.
Запомнить значение счетчика для следующего прерывания.
Получить адрес элемента массива bins под номером последних двух битов счётчика таймера 0.
Если значение счётчика таймера 0 меньше 4 .......
Зачем это всё надо я смутно догадываюсь, но до конца не понимаю :-)
Вот здесь я наткнулся на такой металлоискатель, я хочу переделать его на stm32 и увеличить частоту два раза, потому что stm 32 намного быстрее, сейчас он работает на 7.8 кГц, что является пределом возможностей Atmega2560.
Спасибо, что объяснили, не могли бы вы написать то же самое для ARM stm32 - этот кусок AVR
Для какого таймера и что там делает АЦП?
Из соображения таймер1 - системное время 4мкс, таймер 2 - рабочий, написано для stdlib embitz 1.11.
У меня есть предложение - изменить эту программу на заказ, что вы скажете?
К сожалению у меня нет времени вникать в проблемы металлоискателей. Возьмите готовую разработку http://fandy.ucoz.org/publ/metalloiskatel_quot_kvazar_quot_quot_quasar_quot/metalloiskatel_quot_quasar_arm_quot/2-1-0-5
лучше сделать очень трудно. Её делали люди разбирающиеся в вопросе.
.
Я в вопросе разбираюсь хорошо, "Quasar ARM" мне знакомый но там никаких изменений нельзя делать - hex файл, мне надо перевести этy АРМ программy на ARM, разбираться не надо там есть объяснения на английском, могу перевести если надо и добавить свои если что-то неясно. Я знаю, что должна делать программа.
Я в вопросе разбираюсь хорошо, "Quasar ARM" мне знакомый но там никаких изменений нельзя делать - hex файл, мне надо перевести этy АРМ программy на ARM, разбираться не надо там есть объяснения на английском, могу перевести если надо и добавить свои если что-то неясно. Я знаю, что должна делать программа.
Для начала - протрезвей, Паша. Научись говорить внятно и с запятыми.
Кот не вмешивайся пишу как хочу. Не нравится не читай.
Я в вопросе разбираюсь хорошо
Найдёшь медаль - повесь её себе на грудь!
Я знаю, что должна делать программа.
И что толку? Объяснить это другим ты все равно не можешь.
Для nik182
И одного хватит.
Используй прелоад.
Посмотрел на схему и исходник. Сделать прямо не получится. Надо подбирать время работы АЦП. Оно как то завязано на измерение фазы отклика сигнала.
То, что строки не компилируются - они железо зависимы. Почитайте в интернете статьи по програмированию stm32. Вам нужно про АЦП и таймеры. Меня тема металлоискателей не интересует.
Да, там нужно вникать в тонкости работы девайса, без этого - никак. На СТМ32, вполне может быть, АЦП и нахрен может быть не нужен. Может туда АЦП прилепили из-за ограниченности АВР по таймерам, хотя АЦП в АВР тоже тормознутый. А даже если и нужен, то АЦП в СТМ32 пошустрее АВРовского будет, но переложить код построчно всё равно не получится, увы.
#include <stdio.h>
#include <stdint.h>
/*to be added
int inputVal = analogRead(PA6);
int outputVal = firFilter(inputVal);
analogWrite(PA7, outputVal);
*/
// #1
int inputPin = PA6; // set input pin for the signal
int inputValue = PA6; // potentiometer input variable
int ledPin = PA7; // set output pin for PA7
//#2
int inputVal = analogRead(PA6);
int outputVal = firFilter(inputVal);
//////////////////////////////////////////////////////////////
// Filter Code Definitions
//////////////////////////////////////////////////////////////
// maximum number of inputs that can be handled
// in one function call
#define MAX_INPUT_LEN 80
// maximum length of filter than can be handled
#define MAX_FLT_LEN 63
// buffer to hold all of the input samples
#define BUFFER_LEN (MAX_FLT_LEN - 1 + MAX_INPUT_LEN)
// array to hold input samples
double insamp[ BUFFER_LEN ];
// FIR init
void firFloatInit( void )
{
memset( insamp, 0, sizeof( insamp ) );
}
// the FIR filter function
void firFloat( double *coeffs, double *input, double *output,
int length, int filterLength )
{
double acc; // accumulator for MACs
double *coeffp; // pointer to coefficients
double *inputp; // pointer to input samples
int n;
int k;
// put the new samples at the high end of the buffer
memcpy( &insamp[filterLength - 1], input,
length * sizeof(double) );
// apply the filter to each input sample
for ( n = 0; n < length; n++ ) {
// calculate output n
coeffp = coeffs;
inputp = &insamp[filterLength - 1 + n];
acc = 0;
for ( k = 0; k < filterLength; k++ ) {
acc += (*coeffp++) * (*inputp--);
}
output[n] = acc;
}
// shift input samples back in time for next time
memmove( &insamp[0], &insamp[length],
(filterLength - 1) * sizeof(double) );
}
//////////////////////////////////////////////////////////////
// Test program
//////////////////////////////////////////////////////////////
// bandpass filter centred around 1000 Hz
// sampling rate = 8000 Hz
#define FILTER_LEN 63
double coeffs[ FILTER_LEN ] =
{
-0.0448093, 0.0322875, 0.0181163, 0.0087615, 0.0056797,
0.0086685, 0.0148049, 0.0187190, 0.0151019, 0.0027594,
-0.0132676, -0.0232561, -0.0187804, 0.0006382, 0.0250536,
0.0387214, 0.0299817, 0.0002609, -0.0345546, -0.0525282,
-0.0395620, 0.0000246, 0.0440998, 0.0651867, 0.0479110,
0.0000135, -0.0508558, -0.0736313, -0.0529380, -0.0000709,
0.0540186, 0.0766746, 0.0540186, -0.0000709, -0.0529380,
-0.0736313, -0.0508558, 0.0000135, 0.0479110, 0.0651867,
0.0440998, 0.0000246, -0.0395620, -0.0525282, -0.0345546,
0.0002609, 0.0299817, 0.0387214, 0.0250536, 0.0006382,
-0.0187804, -0.0232561, -0.0132676, 0.0027594, 0.0151019,
0.0187190, 0.0148049, 0.0086685, 0.0056797, 0.0087615,
0.0181163, 0.0322875, -0.0448093
};
void intToFloat( int16_t *input, double *output, int length )
{
int i;
for ( i = 0; i < length; i++ ) {
output[i] = (double)input[i];
}
}
void floatToInt( double *input, int16_t *output, int length )
{
int i;
for ( i = 0; i < length; i++ ) {
if ( input[i] > 32767.0 ) {
input[i] = 32767.0;
} else if ( input[i] < -32768.0 ) {
input[i] = -32768.0;
}
// convert
output[i] = (int16_t)input[i];
}
}
// number of samples to read per loop
#define SAMPLES 80
int main( void )
{
int size;
int16_t input[SAMPLES];
int16_t output[SAMPLES];
double floatInput[SAMPLES];
double floatOutput[SAMPLES];
FILE *in_fid;
FILE *out_fid;
// open the input waveform file
in_fid = fopen( "input.pcm", "rb" );
if ( in_fid == 0 ) {
printf("couldn't open input.pcm");
return -1;
}
// open the output waveform file
out_fid = fopen( "outputFloat.pcm", "wb" );
if ( out_fid == 0 ) {
printf("couldn't open outputFloat.pcm");
return -1;
}
// initialize the filter
firFloatInit();
// process all of the samples
do {
// read samples from file
size = fread( input, sizeof(int16_t), SAMPLES, in_fid );
// convert to doubles
intToFloat( input, floatInput, size );
// perform the filtering
firFloat( coeffs, floatInput, floatOutput, size,
FILTER_LEN );
// convert to ints
floatToInt( floatOutput, output, size );
// write samples to file
fwrite( output, sizeof(int16_t), size, out_fid );
} while ( size != 0 );
fclose( in_fid );
fclose( out_fid );
return 0;
}
//#3
void loop() {
// read the value from input pin
inputValue = analogRead(inputPin);
// send the square wave signal to PA7
analogWrite(ledPin, inputValue / 4);
//#4
analogWrite(PA7, outputVal);
}
ты ж в вопросе "разбираешься хорошо". Но код вставить правильно, тебе видимо не под силу...
Кот открой свою новую тему - Вредный Кот, пригласи SSS
Забей на это тухлое дело. Займись чем-то более приземленным. Тебе эту тему не поднять.
В среде ардуины фунция main определена в недрах. Если ты её перекрываешь, то теряешь init, setup и loop.
Паша, не пей и не кури больше этого никогда ! Следующая остановка будет последней !
Ну и напугал.