Второе, а почему при использовании таймеров такой огромный джиттер, когда программно реализую через микрос() - понятно, точность попадания как минимум 4 микросекунды, ну а через таймеры??? в чем засада?
Так там встроенный генератор хреновенький. А от него и все остальное дрожит. На твоей платке кварц есть? Если от кварца тактоваться разве джиттер не уменьшается?
Второе, а почему при использовании таймеров такой огромный джиттер, когда программно реализую через микрос() - понятно, точность попадания как минимум 4 микросекунды, ну а через таймеры??? в чем засада?
Так там встроенный генератор хреновенький. А от него и все остальное дрожит. На твоей платке кварц есть? Если от кварца тактоваться разве джиттер не уменьшается?
кварц есть, что надо, чтобы от кварца тактироваться?
pittyalex, таймер можно затактировать от pll 64МГц, соответссно максимальная частота с выхода таймера 32МГц. Про отладку не знаю, за неимением программатора я не угублялся в эту тему. По идее под их программатор есть USB драйвер, который виден из под студии.
Продолжаю исследовать таймеры!
Ниже привожу пример использования таймера 3 и немного добавленный код в Калькулятор версии 2 от ЕвгенияП
Таймер:
// Пример использования Таймера 3 (с) UA6EM на основет заимствований на arduino.ru у DIMAX и ЕвгенийП
#include "lgtx8p.h"
enum Prescalers {
PRESCALER_STOP = 0,
PRESCALER_1 = 1,
PRESCALER_8 = 2,
// PRESCALER_32 = 3,
PRESCALER_64 = 3,
// PRESCALER_128 = 5,
PRESCALER_256 = 4,
PRESCALER_1024 = 5
};
int dig = 256;
uint8_t r3ah;
uint8_t r3al;
void setup() {
uint8_t prescaler = PRESCALER_1024;
uint16_t topValue = 0;
if(topValue > dig){
r3ah = topValue / dig;
r3al = topValue % dig;
}
else{
r3ah = 0x00;
r3al = topValue;
}
//*(uint8_t*)0x33 =0x2; // DDRF=1<<DDF1 // ПИН TXI
//*(uint8_t*)0x33 =0x4; // DDRF=1<<DDF2 // ПИН D2
*(uint8_t*)0x33 = 0x6; // DDRF=1<<DDF2,DDF1 // ПИН D2 + TXI
OCR3AH=r3ah; // Важно, вначале необходимо загрузить верхний регистр!!!
OCR3AL=r3al; // затем нижний
// Нельзя как для Atmega328 - OCR3A = topValue;
//TCCR3A=1<<COM3A0; // ПИН TXI
// TCCR3A=1<<COM3B0; // ПИН D2
TCCR3A=1<<COM3A0 | 1<<COM3B0; // ПИН D2 + TXI
TCCR3B=1<<WGM32 | prescaler; // Режим СТС WGM3[3:0]=4 или 12
}
void loop(){}
Калькулятор для таймеров от 0 до 3 (Very TKS ЕвгенийП)
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Калькулятор тактов и делителя частоты СТС режима таймера/счётчика микроконтроллера ATMega328
// Добавлена поддержка Таймера 3 микроконтроллера WAVGAT LGT8F328P ;-))) (C) UA6EM
//
// По заданной желаемой частоте вычисляет количество тактов для всех делителей частоты.
// Перед словом Prescaler в скобках указывается для каких таймеров/счётчиков такой результат может быть получен.
//
// Результат выдаётся для всех делителей частоты в порядке возрастания погрешности. Делители для
// которых такая частота невозможна, печатаются последними.
//
// Результат считается для текущей тактовой частоты микроконтроллера, на котором на котором
// производится расчёт. Частоту, для которой считается результат, можно изменить - см. комментарий
// в тексте скетча.
//
// Условия использования:
//
// - допускается свободное и безвозмездное использование скетча в коммерческих и некоммерческих целях;
// - модификация допускается только с указанием факта (и автора) модификации в заголовке файла;
// - не допускается использование в проектах, связанных с разработкой устройств, предназначенных для
// совершения или подготовки терактов, незаконного сбора информации и любых иных устройств,
// предназначенных для противозаконной деятельности.
//
// Ответственность и обязательства автора:
//
// - каждый разработчик может использовать или не использовать данный код на свой страх и риск;
// - автор не несёт решительно никакой ответственности за прямые или косвенные негативные или
// позитивные последствия использования или неиспользования данного кода;
// - автор с благодарностью примет сообщения о проблемах, ошибках и т.п., а также предложения
// по совершенствованию скетча и постарается исправить код в кратчайшие сроки, однако
// никаких обязательств по оперативному исправлению на себя не берёт;
// - автор по мере возможности, сил и времени готов ответить на вопросы пользователей, но
// обязательств на этот счёт на себя не берёт.
//
// Расширение обязательств и ответственности автора:
//
// - если код предполагается использовать в серьёзном проекте, где обязательства автора по
// исправлению ошибок и предоставлению консультаций необходимы, следует связаться с автором
// на предмет заключения гражданско-правового договора. Тогда обязанности и ответственность
// автора будут определяться не настоящей декларацией, а условиями договора
//
// Если данный код Вам пригодился как готовый скетч, или как учебное пособие, и у Вас возникло желание
// материально поддержать автора (что ни в коей мере НЕ является обязательным условием использования
// кода), Вы можете воспользоваться службой WebMoney, кошелёк № R626206676373
//
//
#include <limits.h>
///////////////////////////////////////////////////////////////////////
//
// !!! ВАЖНО !!!
// Результат считется для текущей тактовой частоты микроконтроллера, на котором на котором
// производится расчёт. Она доступна в константе F_CPU.
// Если необходимо посчитать для другой тактовой частоты, следует в строке ниже вместо F_CPU
// указать желаемую тактовую частоту в герцах. Например,
// static const double fCPU = 16000000.0; // 8МГц
//
static const double fCPU = F_CPU;
// Всего у таймера/счётчика может быть семь делителей частоты
#define TOTAL_PRESCALERS 7
// Потоковая печать в Serial
template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }
////////////////////////////////////////////
//
// Класс, для расчёта количества тактов и делителя
//
// Расчёт производится в функции Calculate по формуле
// со стр.123 ATmega48A/PA/88A/PA/168A/PA/328/P [DATASHEET]
// Сначала производится прямой расчёт для данного делителя,
// Затем, после округления, обратный и определяется разница
// желаемой и полученной частоты.
//
class CalcResult : public Printable {
public:
CalcResult(uint16_t p) {
prescaler = p;
valid = false;
}
void Calculate(const double freq) {
frequency = floor(fCPU / (2.0 * prescaler * freq) - 0.5);
if (frequency < 0.0 || frequency > (double)UINT_MAX) return;
counter = (uint16_t) frequency;
if ((prescaler==32 || prescaler==128) && (counter > 255)) return;
valid = true;
frequency = fCPU / (2.0 * prescaler * (1.0 + counter));
difference = fabs(frequency - freq);
}
protected:
size_t printTo(Print& p) const {
size_t res = 0;
if (valid) {
res += p.print((prescaler==32 || prescaler==128) ? "(2) " : ((counter > 255) ? "(1,3) " : "(0,1,2,3) "));
}
res += p.print("Prescaler: ");
res += p.print(prescaler);
if (! valid) return res + p.println(" - Not possible");
res += p.print("; MaxValue: ");
res += p.print(counter);
res += p.print("; Frequency: ");
res += p.print(frequency);
res += p.print("Hz; Diff: ");
res += p.print(difference);
return res += p.println("Hz");
}
private:
uint16_t counter;
int16_t prescaler;
double frequency;
double difference;
bool valid;
friend int cmp(const void *, const void *);
};
/////////////////////////////////////////////////////////
//
// Функция сравнения двух результатов для qsort
// Правила:
// 1. если для одного делителя результат получен, а для другого нет, то первый меньше второго
// 2. Из двух результатов меньше тот, у которого меньше difference (погрешность частоты)
//
static int cmp(const void * va, const void * vb) {
const CalcResult * a = (const CalcResult *) va;
const CalcResult * b = (const CalcResult *) vb;
if (a->valid && ! b->valid) return -1;
if (! a->valid && b->valid) return 1;
if (! a->valid && ! b->valid) return 0;
if (a->difference - b->difference < 0) return -1;
if (a->difference - b->difference > 0) return 1;
return 0;
}
////////////////////////////////////////////////////////////////||||||
//
// расчёт для пяти делителей, сотрировка и вывод результатов в Serial
//
void CalculateParameters(const double frequency) {
CalcResult results [TOTAL_PRESCALERS] = {
CalcResult(1), CalcResult(8), CalcResult(32), CalcResult(64), CalcResult(128), CalcResult(256), CalcResult(1024)
};
for (int8_t i = 0; i < TOTAL_PRESCALERS; i++) results[i].Calculate(frequency);
qsort(results, TOTAL_PRESCALERS, sizeof(results[0]), cmp);
for (int8_t i = 0; i < TOTAL_PRESCALERS; Serial << results[i++]);
}
////////////////////////////////////////////////////////////////||||||
//
// инициализация
//
void setup() {
Serial.begin(115200);
Serial.setTimeout(LONG_MAX);
}
////////////////////////////////////////////////////////////////||||||
//
// На каждом шаге производим расчёт для одного значения частоты
//
void loop() {
Serial << "\nEnter desired frequency in Hz\n(use decimal point for fractions. I.e. 0.12 means 0,12Hz):\n";
const double frequency = Serial.parseFloat();
Serial << "\nResults for frequency: " << frequency << "Hz\n";
if (frequency < 0) {
Serial << "ERROR: frequency cannot be negative.\n";
} else if (frequency > fCPU / 2.0) {
Serial << "ERROR: frequency should not be greater then " << fCPU / 2.0 << "Hz\n";
} else {
CalculateParameters(frequency);
}
}
// собственно. всё.
Да, использование Pin TXI для вывода меандра - плохая идея, подпорка порядка 1.5 вольта, а это в логике уже за гранью добра и зла )))
Тактирование таймера1 от 64 МГц
#include "lgtx8p.h"
TCKSR|=1<<F2XEN;
TCKSR|=1<<TC2XS1;
Нашёл и в даташите!
Вот видно, что ты в изучении зачитал его до дыр...
Еще один вопрос?
Инициализация порта на вывод для таймера 3 через pinMode(2,OUTPUT) эффекта не имеет!
Как делать правильно? Средствами IDE.
Вот, а говорят библиотеки не стоит обновлять, а брал аддон из твоего первого поста и совсем недавно (мне так показалось)
Качаю, устанавливаю, проверяю, по результатам отпишусь здесь и скину скетчи для проверок всех таймеров
PS
Ни один из режимов настройки пинов из нового аддона для CTC режима не подошёл )))
Так получается, что аддоны разные оказывается:
Проверочные скетчи.
Таймер 0:
// Пример использования Таймера 0 (восьмибитный) (с) UA6EM
// на основе заимствований на arduino.ru у DIMAX и ЕвгенийП
#include "lgtx8p.h"
enum Prescalers {
PRESCALER_STOP = 0,
PRESCALER_1 = 1,
PRESCALER_8 = 2,
PRESCALER_64 = 3,
PRESCALER_256 = 4,
PRESCALER_1024 = 5
};
unsigned int counter = 0;
void setup() {
pinMode(13, OUTPUT);
uint8_t prescaler = PRESCALER_1024;
uint8_t topValue = 255;
pinMode(6, OUTPUT);
TCCR0A = 0x42; // Инвертирование пина 6 по сравнению и режим CTC то OCR0A
TCCR0B = 0x00 | prescaler; // Установить СТС режим и делитель частоты
OCR0A = topValue; // установить TOP равным topValue
}
void loop() {
while(digitalRead(6)==LOW);
counter++;
if(counter==60000){
digitalWrite(13,!digitalRead(13));
counter = 0;}
}
Таймер 1:
// Пример использования Таймера 1 (шестнадцатибитный) (с) UA6EM
// на основе заимствований на arduino.ru у DIMAX и ЕвгенийП
#include "lgtx8p.h"
enum Prescalers {
PRESCALER_1 = 1,
PRESCALER_8 = 2,
PRESCALER_64 = 3,
PRESCALER_256 = 4,
PRESCALER_1024 = 5
};
void setup() {
pinMode(13,OUTPUT);
uint8_t prescaler = PRESCALER_1024;
uint16_t topValue = 30000;
pinMode(9, OUTPUT);
TCCR1A = 0x40; // Инвертирование пина 9 по сравнению
TCCR1B = 0x08 | prescaler; // Установить СТС режим и делитель частоты
OCR1A = topValue; // установить TOP равным topValue
}
void loop() {
digitalWrite(13,digitalRead(9));
}
Таймер 2:
// Пример использования Таймера 2 (восьмибитный)(с) UA6EM
// на основе заимствований на arduino.ru у DIMAX и ЕвгенийП
#include "lgtx8p.h"
enum Prescalers {
PRESCALER_STOP = 0,
PRESCALER_1 = 1,
PRESCALER_8 = 2,
PRESCALER_32 = 3,
PRESCALER_64 = 4,
PRESCALER_128 = 5,
PRESCALER_256 = 6,
PRESCALER_1024 = 7
};
unsigned int counter = 0;
void setup() {
pinMode(13, OUTPUT);
uint8_t prescaler = PRESCALER_128;
uint8_t topValue = 255;
pinMode(11, OUTPUT);
TCCR2A = 0x42; // Инвертирование пина 11 по сравнению и режим CTC то OCR2A
TCCR2B = 0x00 | prescaler; // Установить СТС режим и делитель частоты
OCR2A = topValue; // установить TOP равным topValue
}
void loop() {
while(digitalRead(11)==LOW);
counter++;
if(counter==60000){
digitalWrite(13,!digitalRead(13));
counter = 0;}
}
Таймер 3: (он несколько особенный, кстати шестнадцатибитный как и таймер1)
// Пример использования Таймера 3 (шестнадцатибитный)(с) UA6EM
// на основе заимствований на arduino.ru у DIMAX и ЕвгенийП
#include "lgtx8p.h"
enum Prescalers {
PRESCALER_STOP = 0,
PRESCALER_1 = 1,
PRESCALER_8 = 2,
PRESCALER_64 = 3,
PRESCALER_256 = 4,
PRESCALER_1024 = 5
};
int dig = 256;
uint8_t r3ah;
uint8_t r3al;
void setup() {
pinMode(13,OUTPUT);
uint8_t prescaler = PRESCALER_1024;
uint16_t topValue = 30000;
if(topValue > dig){
r3ah = topValue / dig;
r3al = topValue % dig;
}
else{
r3ah = 0x00;
r3al = topValue;
}
//*(uint8_t*)0x33 = 0x2; // DDRF=1<<DDF1 // ПИН TXI
//*(uint8_t*)0x33 = 0x4; // DDRF=1<<DDF2 // ПИН D2
//*(uint8_t*)0x33 = 0x6; // DDRF=1<<DDF2,DDF1 // ПИН D2 + TXI DDRF = 1<<2 | 1<<1;
DDRF = 1<<2 | 1<<1; // Разрешаем вывод в порты D1 и D2
OCR3AH=r3ah; // Важно, вначале необходимо загрузить верхний регистр!!!
OCR3AL=r3al; // затем нижний
// Нельзя как для Atmega328 - OCR3A = topValue;
// TCCR3A=1<<COM3A0; // ПИН TXI
// TCCR3A=1<<COM3B0; // ПИН D2
TCCR3A=1<<COM3A0 | 1<<COM3B0; // ПИН D2 + TXI
TCCR3B=1<<WGM32 | prescaler; // Режим СТС WGM3[3:0]=4 или 12
}
void loop(){
digitalWrite(13,!digitalRead(2)); // L-)))
}
Вот это замутили китайцы )))
Беру код Таймер 3 из поста, что выше. Если выбираю плату LGT8F328P-LQFB32-MiniEVB то светодиоды на пинах D1 и D13 blinkают синхронно, а если выбираю плату WAVGAT NANO 3.0 то блинкают, как в скетче задумано, попеременно ...
И как тут не быть? )))
Снял осциллограмму с пинов D1 и D2, а сигналы то противофазны, если выбрать LGT8F328P-LQFB32-MiniEVB
Предлагаю другой вариант чтения GUID, без всяких байтовых сдвигов.
uint32_t guid= *(uint32_t*)&GUID0 ;
не многовато буков? ))
у меня такой микрухи пока нет, и очень лень проверять на чем либо другом, но должно работать и будет понятнее так:
uint32_t *guid = &GUID0;
а вот это вот все вот это вот *(uint32_t*) это лишнее)) мы указателю на тип uint32 присвоили адрес первого байта числа, все. а в твоем случае ты сразу извлекаешь значение, и это в значительной мере затрудняет понимание кода и побуждает новичка поскорее закрыть код и просто посмотреть - работает или нет. ногу сломишь. и еще в твоем варианте создается переменная и выделяется память 32бита под ее значение. в моем - экономия, храним только указатель. и по скорости - не нужно копировать значение в другую область памяти..
блин, точно! а вдруг мне из считанного из ADCH 8-ми битного значения, положим, захочется сделать int32_t, и реверснуть его биты. не знаю зачем, но "теперь нам надо". значит под adc буфер _надо_ выделить не 256 байт, например, а 1024. без вариантов. а я сразу не подумал. пойду скетч поправлю...)))
Предлагаю другой вариант чтения GUID, без всяких байтовых сдвигов.
uint32_t guid= *(uint32_t*)&GUID0 ;
не многовато буков? ))
у меня такой микрухи пока нет, и очень лень проверять на чем либо другом, но должно работать и будет понятнее так:
uint32_t *guid = &GUID0;
а вот это вот все вот это вот *(uint32_t*) это лишнее)) мы указателю на тип uint32 присвоили адрес первого байта числа, все. а в твоем случае ты сразу извлекаешь значение, и это в значительной мере затрудняет понимание кода и побуждает новичка поскорее закрыть код и просто посмотреть - работает или нет. ногу сломишь. и еще в твоем варианте создается переменная и выделяется память 32бита под ее значение. в моем - экономия, храним только указатель. и по скорости - не нужно копировать значение в другую область памяти..
если ошибаюсь - раскодируюсь и напьюсь))
У меня есть, полный скетч приведите, я проверю )))
блин, точно! а вдруг мне из считанного из ADCH 8-ми битного значения, положим, захочется сделать int32_t, и реверснуть его биты. не знаю зачем, но "теперь нам надо". значит под adc буфер _надо_ выделить не 256 байт, например, а 1024. без вариантов. а я сразу не подумал. пойду скетч поправлю...)))
И што вы хотите этим проиллюстрировать - что всем в обязательном порядке следует оперировать исключительно солёным огурцом, как вы, а не сложными закусками, как dimax? Это же завсегда проще - наколол на вилку и жуй-наслаждайся.
ааа, я вообще по диагонали смотрю) вопрос снят) таки приводить тип нужно явно.
посыпаю голову пеплом)
зы: в далекие времена на Си можно было указателю присвоить адрес функции, и потом вызвать эту функцию, написав имя переменной со скобками, как будто она и есть функция... а тут такие нежности, уже нельзя пошалить с указателями, фи, как грубо))
спасибо за потраченное время. обратно хочу себе 286-й на 20 МГц 1 МБ оперативы и 41 МБ винт, MS-DOS 6.22 и какой-нибудь нортон коммандер и турбо-Си ))
ЗЫ: наверное, можно прям в библиотеке от микрухы рядышком с дефайнами GUID0,GUID1.. прописать
#define GUID (*((volatile uint32_t *)0xF3))
и при надобности юзать GUID без всяких заморочек. только есть мнение, что это кагбэ никому не нужно))
Приветствую. Тоже приобрел данное устройтво, хотел сделать с ребенком мини плоттер из старых DVD, как теперь разобраться чтоб переделать программы, даже либа серв не работает на нем. А я уже и драйверы и шиелд купил под это дело. Без сишки никак? Как в документации разобраться что значат обозначения в таблице выводов?
Приветствую. Тоже приобрел данное устройтво, хотел сделать с ребенком мини плоттер из старых DVD, как теперь разобраться чтоб переделать программы, даже либа серв не работает на нем. А я уже и драйверы и шиелд купил под это дело. Без сишки никак? Как в документации разобраться что значат обозначения в таблице выводов?
обязана работать если всё сделано по инструкции (тип платы правильно выбран)
зы: в далекие времена на Си можно было указателю присвоить адрес функции, и потом вызвать эту функцию, написав имя переменной со скобками, как будто она и есть функция... а тут такие нежности
Дак и щас можно
using pvfError = void(*)(int); // pointer to void function(int)
pvfError onError; // переменная, где храница адрес такой функции
void error(int errorcode){ // функция, обрабатывающая ошибки
.
.
}
int main(){
.
onError = error; // в переменную пхаем адрес функции
.
.
.
if (onError != NULL) onError(err_OutOfMemory); // вызываем
.
.
}
ну ты объявил указатель на функцию, а сделай тоже самое, например, с char * :) может я сильно путаю, но еще ковыряясь на 286 проце с 1МБ мозга и 41МБ винт я сам обнаружил это, пока игрался с указателями. могу сильно ошибаться ибо память, уже лет 28+ как прошло...
я вообще не понимаю компилятор. мне нужен был просто адрес не важно чего, и если уж я юзаю указатели и прошу адрес, мог бы компиллер подумать, что я знаю, что делаю, но нет...
в случае с копированием значения пускай себе проверяет типы, а для адреса зачем? хотя тут ему пофиг что куда присваивать, байт, сигн/ансигн инт, долби, бул - присваивай в любом порядке. то есть, подразумевается, что ты знаешь, что делаешь... это же двойные мать его стандарты! когда ты байту присваиваешь инт32 - теряешь 3/4 верхних байтов или инт32 присваиваешь булевое - не, не о чем предупреждать, твои проблемы. а адрес попросил - ругается. хочет явного указания типа - ладно, бум указывать. но имхо по задорнову - ну вы... компилятор перепишите))
ну ты объявил указатель на функцию, а сделай тоже самое, например, с char * :) может я сильно путаю, но еще ковыряясь на 286 проце с 1МБ мозга и 41МБ винт я сам обнаружил это, пока игрался с указателями. могу сильно ошибаться ибо память, уже лет 28+ как прошло...
Не было такого. по указателю на char* функцию не вызовешь. всё равно предварительно кастовать надо.
Хотя, я не профессионал, надо у взрослых спросить.
я тоже не профессионал. мне профик только подарил книгу Си на порезанной ленте. долго она в туалете лежала, пока от корки до корки не выучил. два раза) и с тех пор я пропал) такой себе доморощенный кодер-вебмастер-электроннщик-механька-абортмахер))) (последнее вычеркнуть)) все на уровне "с чем столкнулся - то и решил". мне не нужны горы академических знаний. вон, обезьяна знает, что такое палка, и как ее можно использовать))
Хотя, я не профессионал, надо у взрослых спросить.
Небыло. Они в разных сегментах памяти потому и не работает. Код по адресу 0х1234 и данные на таком же адресе - две большие разницы, хотя указатели численно и равны будут. Компилятор их в разные сегменты сует. Для МК это какбыдаже очевидно - одно во флеше другое ОЗУ. У ПК оба в ОЗУ, а сегменты разные.
Хотя, я не профессионал, надо у взрослых спросить.
Небыло. Они в разных сегментах памяти потому и не работает. Код по адресу 0х1234 и данные на таком же адресе - две большие разницы, хотя указатели численно и равны будут. Компилятор их в разные сегменты сует. Для МК это какбыдаже очевидно - одно во флеше другое ОЗУ. У ПК оба в ОЗУ, а сегменты разные.
У пк ФЛЭШ в одном сегменте с озу, как бы чернобыль жил )))
Небыло. Они в разных сегментах памяти потому и не работает. Код по адресу 0х1234 и данные на таком же адресе - две большие разницы, хотя указатели численно и равны будут. Компилятор их в разные сегменты сует. Для МК это какбыдаже очевидно - одно во флеше другое ОЗУ. У ПК оба в ОЗУ, а сегменты разные.
а как же char far *? до любого адреса дотягивается ведь (в пределах базовых 640КБ точно) и содержит полный 32бит адрес памяти, включая сегмент, а не только кусок в каком-то там сегменте. ...от темы я всех увел)
короче, микруха классная, надо брать!))) жаль, что SPI почти на любой скорости (ну, до вменяемых 32МГц, больше не тянут дисплейчики) не даст и половину скорости параллельного интерфейса, ибо spi это тупо узкий расширитель портов. но это уже такое...
Я не разберусь. Собрал по схеме и ничего не происходит
Предлагаю создать отдельную тему. Там опишите- какая ардуина, как конкретно подключали (желательно с фото), какой конкретно скетч заливали, что после этого делали и в чем выражается "ничего не происходит".
Думаю что не стоит. А те кто разбираются сразу видят что различно и могут помочь. Какая ардуно я написал что такая как описано на старте темы.
Во первых: "На старте темы" написано - "Обзор клона меги328 -LGT8F328P". И на этом клоне только у меня дома есть 2 довольно отличные друг от друга ардуины. А сколько может их еще существовать?
Во вторых "На старте темы" написано - "Обзор клона меги328 -LGT8F328P", а не "Как мне программировать флеш используя плату на базе LGT8F328P". Так что не стоит засорять этот топик посторонними вопросами.
В третьих гадание на кофейной гуще это в другие форумы. Хотите помощи - давайте подробную информацию о вашей проблеме.
а как же char far *? до любого адреса дотягивается ведь (в пределах базовых 640КБ точно) и содержит полный 32бит адрес памяти, включая сегмент, а не только кусок в каком-то там сегменте. ...от темы я всех увел)
Не дотягивается, а может дотянутся, если не помешают. Но помешают. При попытке выйти за границу своего сегмента даст ошибку сегментации. Но это не совсем о том. Речь о компиляции. Сразу сущности присутствующие в коде разделяются по секциям. Встретился исполняемый код - помещается машинный код в свою секцию, обявлены новые данные - в свою и т.д. Адресация в каждой секции идет своя, независимая от других, после добавления очередно "порции" адрес соответственно подростает на размер "порции". Вот собственно отчего возникает то различие между указателями на функции и на данные. Таких секций обычно довольно много, даже коменты в свою могут собиратся перед тем как игнорится :) Затем по настройкам линкера эти секции в некотором порядке собираются вместе в сегменты. Для ПК это код и переменные, оба в ОЗУ, понятное дело, но с разными атрибутами, чтоб не исполнять даенные как код и не обращатся к коду как к данным, защита вобщем, но методы находятся;) Ну а для МК - код в флеш и константы PROGMEM тудаже. А переменные в ОЗУ. Полезно иногда в файле map посмотреть для общего развития.
hi Dimax! I saw you introduce LGT8F328P, I found it to be the same as the nano mode, I asked about the code, if the code is on this device, can I use it with the Arduino? thank you
hi Dimax! I saw you introduce LGT8F328P, I found it to be the same as the nano mode, I asked about the code, if the code is on this device, can I use it with the Arduino? thank you
Второе, а почему при использовании таймеров такой огромный джиттер, когда программно реализую через микрос() - понятно, точность попадания как минимум 4 микросекунды, ну а через таймеры??? в чем засада?
Так там встроенный генератор хреновенький. А от него и все остальное дрожит. На твоей платке кварц есть? Если от кварца тактоваться разве джиттер не уменьшается?
Второе, а почему при использовании таймеров такой огромный джиттер, когда программно реализую через микрос() - понятно, точность попадания как минимум 4 микросекунды, ну а через таймеры??? в чем засада?
Так там встроенный генератор хреновенький. А от него и все остальное дрожит. На твоей платке кварц есть? Если от кварца тактоваться разве джиттер не уменьшается?
кварц есть, что надо, чтобы от кварца тактироваться?
кварц есть, что надо, чтобы от кварца тактироваться?
Cмотри пост №1 - http://arduino.ru/forum/apparatnye-voprosy/obzor-klona-megi328-lgt8f328p#comment-390436
pittyalex, таймер можно затактировать от pll 64МГц, соответссно максимальная частота с выхода таймера 32МГц. Про отладку не знаю, за неимением программатора я не угублялся в эту тему. По идее под их программатор есть USB драйвер, который виден из под студии.
Дмитрий!
А как затактироваться 64Мгц?
Продолжаю исследовать таймеры!
Ниже привожу пример использования таймера 3 и немного добавленный код в Калькулятор версии 2 от ЕвгенияП
Таймер:
Калькулятор для таймеров от 0 до 3 (Very TKS ЕвгенийП)
Да, использование Pin TXI для вывода меандра - плохая идея, подпорка порядка 1.5 вольта, а это в логике уже за гранью добра и зла )))
[А как затактироваться 64Мгц?
Тактирование таймера1 от 64 МГц
#include "lgtx8p.h"
TCKSR|=1<<F2XEN;
TCKSR|=1<<TC2XS1;
[А как затактироваться 64Мгц?
Тактирование таймера1 от 64 МГц
#include "lgtx8p.h"
TCKSR|=1<<F2XEN;
TCKSR|=1<<TC2XS1;
Нашёл и в даташите!
Вот видно, что ты в изучении зачитал его до дыр...
Еще один вопрос?
Инициализация порта на вывод для таймера 3 через pinMode(2,OUTPUT) эффекта не имеет!
Как делать правильно? Средствами IDE.
ua6em, ну ведь прямо в аддоне есть пример.
https://github.com/LGTMCU/Larduino_HSP/tree/master/hardware/LGT/avr/libr...
ua6em, ну ведь прямо в аддоне есть пример.
https://github.com/LGTMCU/Larduino_HSP/tree/master/hardware/LGT/avr/libraries/Larduino_HSPExamples/examples/lgt8fx8p_pwm_d1d2_solo_fast
Вот, а говорят библиотеки не стоит обновлять, а брал аддон из твоего первого поста и совсем недавно (мне так показалось)
Качаю, устанавливаю, проверяю, по результатам отпишусь здесь и скину скетчи для проверок всех таймеров
PS
Ни один из режимов настройки пинов из нового аддона для CTC режима не подошёл )))
Так получается, что аддоны разные оказывается:
Проверочные скетчи.
Таймер 0:
Таймер 1:
Таймер 2:
Таймер 3: (он несколько особенный, кстати шестнадцатибитный как и таймер1)
Вот это замутили китайцы )))
Беру код Таймер 3 из поста, что выше. Если выбираю плату LGT8F328P-LQFB32-MiniEVB то светодиоды на пинах D1 и D13 blinkают синхронно, а если выбираю плату WAVGAT NANO 3.0 то блинкают, как в скетче задумано, попеременно ...
И как тут не быть? )))
Снял осциллограмму с пинов D1 и D2, а сигналы то противофазны, если выбрать LGT8F328P-LQFB32-MiniEVB
Выходит что аддоны корявые.
Сигналы на выходных пинах от Таймера 3 противофазные.
не многовато буков? ))
у меня такой микрухи пока нет, и очень лень проверять на чем либо другом, но должно работать и будет понятнее так:
а вот это вот все вот это вот *(uint32_t*) это лишнее)) мы указателю на тип uint32 присвоили адрес первого байта числа, все. а в твоем случае ты сразу извлекаешь значение, и это в значительной мере затрудняет понимание кода и побуждает новичка поскорее закрыть код и просто посмотреть - работает или нет. ногу сломишь. и еще в твоем варианте создается переменная и выделяется память 32бита под ее значение. в моем - экономия, храним только указатель. и по скорости - не нужно копировать значение в другую область памяти..
если ошибаюсь - раскодируюсь и напьюсь))
А теперь нам надо, положим, сделать guid|=0xFF ...
блин, точно! а вдруг мне из считанного из ADCH 8-ми битного значения, положим, захочется сделать int32_t, и реверснуть его биты. не знаю зачем, но "теперь нам надо". значит под adc буфер _надо_ выделить не 256 байт, например, а 1024. без вариантов. а я сразу не подумал. пойду скетч поправлю...)))
не многовато буков? ))
у меня такой микрухи пока нет, и очень лень проверять на чем либо другом, но должно работать и будет понятнее так:
а вот это вот все вот это вот *(uint32_t*) это лишнее)) мы указателю на тип uint32 присвоили адрес первого байта числа, все. а в твоем случае ты сразу извлекаешь значение, и это в значительной мере затрудняет понимание кода и побуждает новичка поскорее закрыть код и просто посмотреть - работает или нет. ногу сломишь. и еще в твоем варианте создается переменная и выделяется память 32бита под ее значение. в моем - экономия, храним только указатель. и по скорости - не нужно копировать значение в другую область памяти..
если ошибаюсь - раскодируюсь и напьюсь))
У меня есть, полный скетч приведите, я проверю )))
блин, точно! а вдруг мне из считанного из ADCH 8-ми битного значения, положим, захочется сделать int32_t, и реверснуть его биты. не знаю зачем, но "теперь нам надо". значит под adc буфер _надо_ выделить не 256 байт, например, а 1024. без вариантов. а я сразу не подумал. пойду скетч поправлю...)))
И што вы хотите этим проиллюстрировать - что всем в обязательном порядке следует оперировать исключительно солёным огурцом, как вы, а не сложными закусками, как dimax? Это же завсегда проще - наколол на вилку и жуй-наслаждайся.
кто в своем уме захочет менять фактически константу?
вообще надо все проверять, я не знаю, как работает этот мк...
и это
по моему должно выводить одно и тоже
просто uint32_t guid= *(uint32_t*)&GUID0; меняется на uint32_t *guid = &GUID0; имхо так понятнее = указатель обрел адрес)))
и это
по моему должно выводить одно и тоже
просто uint32_t guid= *(uint32_t*)&GUID0; меняется на uint32_t *guid = &GUID0; имхо так понятнее = указатель обрел адрес)))
GUID0-Read:14:25: error: invalid conversion from 'uint32_t* {aka long unsigned int*}' to 'long unsigned int' [-fpermissive]
exit status 1
no matching function for call to 'println(uint32_t*&, int)'
ну да, я звезду перед guid забыл
ну да, я звезду перед guid забыл
cannot convert 'volatile unsigned char*' to 'uint32_t* {aka long unsigned int*}' in initialization
#define GUID0 (*((volatile unsigned char *)0xF3))
ааа, я вообще по диагонали смотрю) вопрос снят) таки приводить тип нужно явно.
посыпаю голову пеплом)
зы: в далекие времена на Си можно было указателю присвоить адрес функции, и потом вызвать эту функцию, написав имя переменной со скобками, как будто она и есть функция... а тут такие нежности, уже нельзя пошалить с указателями, фи, как грубо))
спасибо за потраченное время. обратно хочу себе 286-й на 20 МГц 1 МБ оперативы и 41 МБ винт, MS-DOS 6.22 и какой-нибудь нортон коммандер и турбо-Си ))
ЗЫ: наверное, можно прям в библиотеке от микрухы рядышком с дефайнами GUID0,GUID1.. прописать
и при надобности юзать GUID без всяких заморочек. только есть мнение, что это кагбэ никому не нужно))
Приветствую. Тоже приобрел данное устройтво, хотел сделать с ребенком мини плоттер из старых DVD, как теперь разобраться чтоб переделать программы, даже либа серв не работает на нем. А я уже и драйверы и шиелд купил под это дело. Без сишки никак? Как в документации разобраться что значат обозначения в таблице выводов?
Приветствую. Тоже приобрел данное устройтво, хотел сделать с ребенком мини плоттер из старых DVD, как теперь разобраться чтоб переделать программы, даже либа серв не работает на нем. А я уже и драйверы и шиелд купил под это дело. Без сишки никак? Как в документации разобраться что значат обозначения в таблице выводов?
обязана работать если всё сделано по инструкции (тип платы правильно выбран)
зы: в далекие времена на Си можно было указателю присвоить адрес функции, и потом вызвать эту функцию, написав имя переменной со скобками, как будто она и есть функция... а тут такие нежности
Дак и щас можно
Поиск переднего или заднего фронта импульса(немного исправил):
я вообще не понимаю компилятор. мне нужен был просто адрес не важно чего, и если уж я юзаю указатели и прошу адрес, мог бы компиллер подумать, что я знаю, что делаю, но нет...
в случае с копированием значения пускай себе проверяет типы, а для адреса зачем? хотя тут ему пофиг что куда присваивать, байт, сигн/ансигн инт, долби, бул - присваивай в любом порядке. то есть, подразумевается, что ты знаешь, что делаешь... это же двойные мать его стандарты! когда ты байту присваиваешь инт32 - теряешь 3/4 верхних байтов или инт32 присваиваешь булевое - не, не о чем предупреждать, твои проблемы. а адрес попросил - ругается. хочет явного указания типа - ладно, бум указывать. но имхо по задорнову - ну вы... компилятор перепишите))
ну ты объявил указатель на функцию, а сделай тоже самое, например, с char * :) может я сильно путаю, но еще ковыряясь на 286 проце с 1МБ мозга и 41МБ винт я сам обнаружил это, пока игрался с указателями. могу сильно ошибаться ибо память, уже лет 28+ как прошло...
Не было такого. по указателю на char* функцию не вызовешь. всё равно предварительно кастовать надо.
Хотя, я не профессионал, надо у взрослых спросить.
Хотя, я не профессионал, надо у взрослых спросить.
Небыло. Они в разных сегментах памяти потому и не работает. Код по адресу 0х1234 и данные на таком же адресе - две большие разницы, хотя указатели численно и равны будут. Компилятор их в разные сегменты сует. Для МК это какбыдаже очевидно - одно во флеше другое ОЗУ. У ПК оба в ОЗУ, а сегменты разные.
Хотя, я не профессионал, надо у взрослых спросить.
Небыло. Они в разных сегментах памяти потому и не работает. Код по адресу 0х1234 и данные на таком же адресе - две большие разницы, хотя указатели численно и равны будут. Компилятор их в разные сегменты сует. Для МК это какбыдаже очевидно - одно во флеше другое ОЗУ. У ПК оба в ОЗУ, а сегменты разные.
У пк ФЛЭШ в одном сегменте с озу, как бы чернобыль жил )))
У пк ФЛЭШ в одном сегменте с озу, как бы чернобыль жил )))
нда... Кто на ком стоял говорите?
короче, микруха классная, надо брать!))) жаль, что SPI почти на любой скорости (ну, до вменяемых 32МГц, больше не тянут дисплейчики) не даст и половину скорости параллельного интерфейса, ибо spi это тупо узкий расширитель портов. но это уже такое...
А это будет работать? Если нет то как изменить?
http://skproj.ru/programmator-spi-flash-svoimi-rukami/?from=flasher
А это будет работать? Если нет то как изменить?
http://skproj.ru/programmator-spi-flash-svoimi-rukami/?from=flasher
А вы попробуйте и тут расскажите.
Я не разберусь. Собрал по схеме и ничего не происходит
Я не разберусь. Собрал по схеме и ничего не происходит
Предлагаю создать отдельную тему. Там опишите- какая ардуина, как конкретно подключали (желательно с фото), какой конкретно скетч заливали, что после этого делали и в чем выражается "ничего не происходит".
Думаю что не стоит. А те кто разбираются сразу видят что различно и могут помочь. Какая ардуно я написал что такая как описано на старте темы.
Думаю что не стоит. А те кто разбираются сразу видят что различно и могут помочь. Какая ардуно я написал что такая как описано на старте темы.
Во первых: "На старте темы" написано - "Обзор клона меги328 -LGT8F328P". И на этом клоне только у меня дома есть 2 довольно отличные друг от друга ардуины. А сколько может их еще существовать?
Во вторых "На старте темы" написано - "Обзор клона меги328 -LGT8F328P", а не "Как мне программировать флеш используя плату на базе LGT8F328P". Так что не стоит засорять этот топик посторонними вопросами.
В третьих гадание на кофейной гуще это в другие форумы. Хотите помощи - давайте подробную информацию о вашей проблеме.
...те кто разбираются сразу видят что различно и могут помочь.
А оно им надо?
Типичное заблуждение новичка - думать, что другим интересно решать ваши проблемы.
а как же char far *? до любого адреса дотягивается ведь (в пределах базовых 640КБ точно) и содержит полный 32бит адрес памяти, включая сегмент, а не только кусок в каком-то там сегменте. ...от темы я всех увел)
Не дотягивается, а может дотянутся, если не помешают. Но помешают. При попытке выйти за границу своего сегмента даст ошибку сегментации. Но это не совсем о том. Речь о компиляции. Сразу сущности присутствующие в коде разделяются по секциям. Встретился исполняемый код - помещается машинный код в свою секцию, обявлены новые данные - в свою и т.д. Адресация в каждой секции идет своя, независимая от других, после добавления очередно "порции" адрес соответственно подростает на размер "порции". Вот собственно отчего возникает то различие между указателями на функции и на данные. Таких секций обычно довольно много, даже коменты в свою могут собиратся перед тем как игнорится :) Затем по настройкам линкера эти секции в некотором порядке собираются вместе в сегменты. Для ПК это код и переменные, оба в ОЗУ, понятное дело, но с разными атрибутами, чтоб не исполнять даенные как код и не обращатся к коду как к данным, защита вобщем, но методы находятся;) Ну а для МК - код в флеш и константы PROGMEM тудаже. А переменные в ОЗУ. Полезно иногда в файле map посмотреть для общего развития.
hi Dimax! I saw you introduce LGT8F328P, I found it to be the same as the nano mode, I asked about the code, if the code is on this device, can I use it with the Arduino? thank you
можно ))) #41 как образец использования
AS31979, так обзор не для новичков был, я думал по примерам это понятно :) Я даже не советывал бы начинающим покупать эту плату.
Золотые слова, только покупалось то как "WAVGAT Pro Mini ATMEGA328P" (чтоб они были здоровы...)
Благодаря этой теме хоть как-то задышало, а поначалу был шок :) Кстати, при аддоне "от wavgat" времянка по millis совпадает (т.е. заветные 16МГц ©), а WDTO_2S срабатывает ровно через 8 секунд (т.е. в 4 раза дольше)
рискну показать результаты своего небольшого теста ADC.
правда я использовал WEMOS XI LGT8F328D это немного отличается от сабжа ...
Подопытными будут выступать WEMOS XI LGT8F328D и arduino Pro Mini
Для каждой из плат было проведены замеры четырьмя способами и для каждого способа вычислялось время. Способы и результаты видны на скринах
WEMOS XI
https://a.d-cd.net/X2AAAgDPYuA-1920.jpg
Pro Mini
https://a.d-cd.net/TuAAAgDPYuA-1920.jpg
затем из скетчей убрал все, что касается замера времени и вывел результат в плотер.
номер графика соответствует номеру способа замера.
WEMOS XI
https://a.d-cd.net/f2AAAgDPYuA-1920.jpg
Pro Mini
https://a.d-cd.net/weAAAgDPYuA-1920.jpg
рискну показать результаты своего небольшого теста ADC.
хм. а что за сигнал вообще ты измерял? ножку в воздухе?
рискну показать результаты своего небольшого теста ADC.
хм. а что за сигнал вообще ты измерял? ножку в воздухе?
Переменный резистор 10кОм, ползунок примерно в среднем положении.
Здравствуйте .на этом клоне возможно ли вывести полноценный vga(640х480 c частотой точки 25.175Мгц).?
(если пишут заявлено 32 МГц для питания от 1.8 вольт??!!. то моя чуйка говорит что при 5 вольтах будет работать на 60МГц )
А АЦП интересно проверять закольцовыванием PWM(DAC)--фильтр--ADC
так проверял на пропуск (монотонность ?)кодов.. при тактовой ацп меги8 800кГц еще все коды были ,но с разной вреоятностью
то моя чуйка говорит что при 5 вольтах будет работать на 60МГц
Чуйка херовая, надо менять, а то попалишся.