Ви не увійшли.
Сторінки 1
Когда Вы делаете realloc(config.poliv_Plans[_plan].poliv_ZoneTimes, ...); то последние значения config.poliv_Plans[_plan].poliv_ZoneTimes (до индекса config.poliv_PlanCount и начиная с его предыдущего значения) находятся в только что выделенной (расширенной) области памяти и не инициализированы. Чтобы инициализировать нулями только нужные (новые), Вам нужна информация о предыдущем значении config.poliv_PlanCount.
Это как раз понятно и будет отработано.
Осенила другая мысль
void ConfigLoad(){
Serial.print("np1");
uint16_t startingAddress = 0;
EEPROM.get(startingAddress, config); startingAddress += sizeof(config);
config.poliv_ZonePin=0;
config.poliv_Plans=0;
ChangeConfig();
Строки
config.poliv_ZonePin=0;
config.poliv_Plans=0;
Переменные являются указателями на динамические массивы. Предполагалось что строки сбросят указатели, т.е. они не должны указывать никуда.
Но помоему в этом написании я не сбрасываю указатель, а изменяю значение, на которое указывает указатель?
Как правильно сбросить указатель, чтобы сам указатель был NULL?
Добрый день. Помогите начинающему.
Хочу сделать управление поливом. Плата UNO.
Создал структуру CONFIG для хранения конфирационных данных.
- poliv_ZoneCount - количество зон
- poliv_ZonePin - динамический массив номеров зон (по количеству зон)
- poliv_Plans - динамический массив структур плана полива PolivPlan_t, структура собержит время старта и динамический массив таймингов полива зон (по количеству зон)
В void setup() сначала задаю количество зон и количество планов, переконфигурируется переменная CONFIG и потом заполняется.
Для теста сразу выводится конфигурация.
Проблема:
1.Помогите пожалуйста оценить правильно ли я работаю с массивами
2.Иногда код выводит неожиданные числа в тайминге плана, при чем именно в тайминге, стартовое время показывается правильно
Пример правильного вывода
poliv_Plan:0 active:1 time:12:33 timers:5 6 7 8 9 10 11
Но иногдла показывает
poliv_Plan:0 active:1 time:12:33 timers:21 32 8 56 0 1 0
#include <EEPROM.h>
#define SerialSpeed 9600
#define InvBit(reg, bit) reg ^= (1<<(bit))
bool needRestart = false;
// Структура объекта ЗонаПолива
typedef struct PolivPlan_t{
bool Active ;
uint8_t TimeStartH;
uint8_t TimeStartM;
uint8_t *poliv_ZoneTimes=0; // массив Таймингов для каждой зоны
} ;
struct configObj {
bool serialShow; // показывать диагностический вывод
bool poliv_Active; // полив может запускаться
uint8_t poliv_ZoneCount; // количество зон полива
uint8_t poliv_PlanCount; // количество планов полива
uint8_t *poliv_ZonePin=0; // Массив номеров зон полива
PolivPlan_t *poliv_Plans=0;// Массив зон полива
byte controlByte = 0x55;
} config;
//-----------------------------------------------------------------------
void printConfig();
void ConfigSave(){
uint16_t startingAddress = 0;
EEPROM.put(startingAddress, config); startingAddress += sizeof(config);
//poliv zone pins
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++){
EEPROM.put(startingAddress, config.poliv_ZonePin[_zone]); startingAddress += sizeof(config.poliv_ZonePin[_zone]);
}
//poliv plans
for (uint8_t _plan=0; _plan<config.poliv_PlanCount; _plan++) {
EEPROM.put(startingAddress, config.poliv_Plans[_plan].Active); startingAddress += sizeof(config.poliv_Plans[_plan].Active);
EEPROM.put(startingAddress, config.poliv_Plans[_plan].TimeStartH); startingAddress += sizeof(config.poliv_Plans[_plan].TimeStartH);
EEPROM.put(startingAddress, config.poliv_Plans[_plan].TimeStartM); startingAddress += sizeof(config.poliv_Plans[_plan].TimeStartM);
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++) {
EEPROM.put(startingAddress, config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]); startingAddress += sizeof(config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]);
}
}
}
void ConfigLoad(){
Serial.print("np1");
uint16_t startingAddress = 0;
EEPROM.get(startingAddress, config); startingAddress += sizeof(config);
config.poliv_ZonePin=0;
config.poliv_Plans=0;
ChangeConfig();
//poliv zone pins
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++){
EEPROM.get(startingAddress, config.poliv_ZonePin[_zone]); startingAddress += sizeof(config.poliv_ZonePin[_zone]);
}
//poliv plans
for (uint8_t _plan=0; _plan<config.poliv_PlanCount; _plan++) {
EEPROM.get(startingAddress, config.poliv_Plans[_plan].Active); startingAddress += sizeof(config.poliv_Plans[_plan].Active);
EEPROM.get(startingAddress, config.poliv_Plans[_plan].TimeStartH); startingAddress += sizeof(config.poliv_Plans[_plan].TimeStartH);
EEPROM.get(startingAddress, config.poliv_Plans[_plan].TimeStartM); startingAddress += sizeof(config.poliv_Plans[_plan].TimeStartM);
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++) {
EEPROM.get(startingAddress, config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]); startingAddress += sizeof(config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]);
}
}
}
void ChangeConfig(){
//--- poliv_ZonePin
config.poliv_ZonePin = (uint8_t*) realloc(config.poliv_ZonePin, config.poliv_ZoneCount * sizeof(uint8_t));
//--- poliv_Plans
config.poliv_Plans = (PolivPlan_t*) realloc(config.poliv_Plans, config.poliv_PlanCount * sizeof(PolivPlan_t));
for (uint8_t _plan=0; _plan<config.poliv_PlanCount; _plan++) {
config.poliv_Plans[_plan].poliv_ZoneTimes = (uint8_t*)realloc(config.poliv_Plans[_plan].poliv_ZoneTimes, config.poliv_ZoneCount * sizeof(uint8_t));
}
}
void setup() {//=== SETUP ======= SETUP ======= SETUP
Serial.begin(SerialSpeed);
// --- Предварительная запись в EEPROM ----
Serial.println(F("test varialbe set"));
config.poliv_Active = true;
config.poliv_ZoneCount = 7;
config.poliv_PlanCount = 1;
config.poliv_ZonePin = 0; // первоначальная инициализация перед заполнением из EEPROM
config.poliv_Plans = 0; // первоначальная инициализация перед заполнением из EEPROM
Serial.println(F("nChangeConfig();"));
ChangeConfig(); // переконфигурирование CONFIG
Serial.println(F("test varialbe set next"));
config.poliv_ZonePin[0] = 20;
config.poliv_ZonePin[1] = 21;
config.poliv_ZonePin[2] = 22;
config.poliv_ZonePin[3] = 23;
config.poliv_ZonePin[4] = 24;
config.poliv_ZonePin[5] = 25;
config.poliv_ZonePin[6] = 26;
config.poliv_Plans[0].Active = true;
config.poliv_Plans[0].TimeStartH = 12;
config.poliv_Plans[0].TimeStartM = 33;
config.poliv_Plans[0].poliv_ZoneTimes[0] = 5;
config.poliv_Plans[0].poliv_ZoneTimes[1] = 6;
config.poliv_Plans[0].poliv_ZoneTimes[2] = 7;
config.poliv_Plans[0].poliv_ZoneTimes[3] = 8;
config.poliv_Plans[0].poliv_ZoneTimes[4] = 9;
config.poliv_Plans[0].poliv_ZoneTimes[5] = 10;
config.poliv_Plans[0].poliv_ZoneTimes[6] = 11;
printConfig();
Serial.println(F("nChangeSave()"));
ConfigSave();
/* Serial.println(F("nConfigLoad()"));
ConfigLoad();
Serial.println("nAFTER LOAD");
printConfig();
*/
}
void loop(){
/* Serial.println("nvoid loop()");
printConfig();
delay(1000);
*/
}
void printConfig() {//--- Вывод текущей конфигурации ----------
Serial.print(F("Current config"));
if (needRestart) Serial.print(F(" !!! Need restart !!!"));
Serial.println();
Serial.print(F("serial show:")); Serial.println(config.serialShow);
Serial.print(F("poliv_Active:")); Serial.println(config.poliv_Active);
Serial.print(F("poliv_ZoneCount:")); Serial.print(config.poliv_ZoneCount);
Serial.print(F(" contact numbers:")); for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++){Serial.print(config.poliv_ZonePin[_zone], DEC); Serial.print(" ");} Serial.println();
Serial.print(F("poliv_PlanCount:")); Serial.println(config.poliv_PlanCount);
// poliv plan
for (uint8_t _plan=0; _plan<config.poliv_PlanCount; _plan++) {
Serial.print(F("poliv_Plan:")); Serial.print(_plan);
Serial.print(F(" active:")); Serial.print(config.poliv_Plans[_plan].Active);
Serial.print(F(" time:")); Serial.print(config.poliv_Plans[_plan].TimeStartH);Serial.print(F(":")); Serial.print(config.poliv_Plans[_plan].TimeStartM);
Serial.print(F(" timers:"));
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++) {
Serial.print(config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]);Serial.print(F(" "));
}
Serial.println();
}
}
Не помогло. Тогда остается причина - чтото с самим контролером?
Дабы разобраться не в среде ли дело, не согласится ли кто-то скомпилить код и переслать мне бинарный файл для заливки.
Atmega125a 8мг
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile unsigned char z1;
ISR(TIMER0_OVF_vect)
{
z1++;
if (z1<=250) {return;}
z1=0;
PORTA ^= (1<<PA4);
}
int main(void)
{
//TIMER0 -------------------------------------------------
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 9,984 ms
ASSR=0<<AS0;
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0xB2;
OCR0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);
DDRA = 0xFF;
DDRD = 0xFF;
PORTA = 0;
PORTD = 0;
z1=0;
sei();
PORTA |= (1<<PA4); _delay_ms(1000);
PORTD |= (1<<PD5); _delay_ms(1000);
PORTA |= (1<<PA3); _delay_ms(1000);
PORTA |= (1<<PA5); _delay_ms(1000);
PORTA |= (1<<PA6); _delay_ms(1000);
PORTA = 0;
PORTD = 0;
while (1)
{
PORTD ^= (1<<PD5); _delay_ms(500);
}
}
VLDnepr пише:что я делаю не так
Не читаешь, что тебе пишут. Я ж тебе уже написал, что у меня твой код работает, значит, дело не в коде.
VLDnepr пише:Не суть какой делитель устанавлиывется
С точки зрения работоспособности кода, не влияет, а вот с точки зрения "общей аккуратности" ... если ты говоришь, что делитель такой, а он совсем другой, какие у меня основания доверять, что у тебя там в вправду 128-ая на 8МГц, а не 32U на 20?
VLDnepr пише:Фьюзы как по мне тут непричем
Ну, тебе виднее. Раз ты всё и сам знаешь - что причём, а что - нет, зачем было сюда обращаться?
Мне не видно, потому и обратился.
Но и надпись типа "... Поэтому, смотри на фьюзы, всё ли там в порядке. ..." - тоже очень информативна, конкретна и после нее сразу понятно куда смотреть и что делать.
Что не ясновидец - понятно.
AtmelStudio menu Project\Device\CurrentDevice: ATmega128
Код в посте выше приводил копипастом, без правки.
Результат тотже, если раскоментировать строки установки TIMSK - сразу после сброса зажигается первый светодиод (в данном коде это PD5) и все. Такое ощущение что программа вешается на
_delay_ms(1000);
потому как если раскоментировать строку
//PORTA |= (1<<PA4); _delay_ms(1000);
записало все после зажигания PA4, это все при том что сейчас обработчик ISR(TIMER0_OVF_vect) пустой
может ли зависать _delay_ms?
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile unsigned char z1;
ISR(TIMER0_OVF_vect)
{
}
ISR(INT1_vect){PORTD |= (1<<PA3);}
ISR(INT2_vect){PORTD |= (1<<PA3);}
ISR(INT3_vect){PORTD |= (1<<PA3);}
ISR(INT4_vect){PORTD |= (1<<PA3);}
ISR(INT5_vect){PORTD |= (1<<PA3);}
ISR(INT6_vect){PORTD |= (1<<PA3);}
ISR(INT7_vect){PORTD |= (1<<PA3);}
ISR(TIMER0_COMP_vect){PORTD |= (1<<PA5);}
ISR(TIMER1_CAPT_vect){PORTD |= (1<<PA5);}
ISR(TIMER1_COMPA_vect){PORTD |= (1<<PA5);}
ISR(TIMER1_COMPB_vect){PORTD |= (1<<PA5);}
ISR(TIMER1_OVF_vect){PORTD |= (1<<PA5);}
ISR(TIMER3_CAPT_vect){PORTD |= (1<<PA6);}
ISR(TIMER3_COMPA_vect){PORTD |= (1<<PA6);}
ISR(TIMER3_COMPB_vect){PORTD |= (1<<PA6);}
ISR(TIMER3_COMPC_vect){PORTD |= (1<<PA6);}
ISR(TIMER3_OVF_vect){PORTD |= (1<<PA6);}
ISR(USART1_RX_vect){PORTD |= (1<<PA6);}
ISR(USART1_UDRE_vect){PORTD |= (1<<PA6);}
ISR(USART1_TX_vect){PORTD |= (1<<PA6);}
ISR(TWI_vect){PORTD |= (1<<PA6);}
ISR(SPM_READY_vect){PORTD |= (1<<PA6);}
int main(void)
{
//TIMER0 -------------------------------------------------
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 9,984 ms
ASSR=0<<AS0;
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0xB2;
OCR0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);
DDRA = 0xFF;
DDRD = 0xFF;
PORTA = 0;
PORTD = 0;
z1=0;
sei();
//PORTA |= (1<<PA4); _delay_ms(1000);
PORTD |= (1<<PD5); _delay_ms(1000);
PORTA |= (1<<PA3); _delay_ms(1000);
PORTA |= (1<<PA5); _delay_ms(1000);
PORTA |= (1<<PA6); _delay_ms(1000);
PORTA = 0;
PORTD = 0;
while (1)
{
PORTD ^= (1<<PD5); _delay_ms(500);
}
}
Ребята, Вы конечно может быть и великие Знайки, но я ничего не темню и не скрываю, мне хочется просто понять что я делаю не так, или где ковырять чтобы разобраться.
Еще раз
1.Полный код приведен ниже, контроллер atmega128a, 8 мг
2.Не суть какой делитель устанавлиывется, суть вопроса в прекращении работы основного цикла
3.Сгенерировал настройки таймера в CodeVisionAVR
4.Фьюзы как по мне тут непричем, ну или подскажите как они влияют.
5.Из подключенный внешних устройств только USBASP на USART0.
6.Только что рассмотрел, что при подаче питания сразу зажигается PA4 и больше ничего не происходит.
7.Если закоментировать TIMSK=... и ETIMSK=.... - все работает как написано, т.е. код в преравыние не заходит, т.к. перавание таймара не разрешено, основной цикл моргает.
Что то-то не так, не понимаю что именно.
Буду благодарен, если подскажете.
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile unsigned char z1;
ISR(TIMER0_OVF_vect)
{
TCNT0=0xB2;
z1++;
if (z1<=250) {return;}
z1=0;
PORTA ^= (1<<PA4);
}
int main(void)
{
//TIMER0 -------------------------------------------------
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 9,984 ms
ASSR=0<<AS0;
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0xB2;
OCR0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);
DDRA = 0xFF;
DDRD = 0xFF;
PORTA = 0;
PORTD = 0;
z1=0;
sei();
PORTA |= (1<<PA4); _delay_ms(1000);
PORTD |= (1<<PD5); _delay_ms(1000);
PORTA = 0;
PORTD = 0;
while (1)
{
PORTD ^= (1<<PD5); _delay_ms(500);
}
}
это понятно, в прерывании просто тестовый код.
Почему перестает работать основной цикл, вот в чем вопрос? PD5 не моргает, просто не горит.
Помогите, пожалуйста, разобраться.
Наинаю осваивать программирование контроллеров.
До этого немного покаталсяна меге16, все относительно понятно и получалось
Решил перейти на мега 128 - не могу запустить простое мигание светодиодом через прерывание
Если закоментировать sei(); работает основной цикл.
Но при раскоментировании зажигается PA4 и горит постоянно, а PD5 (основной цикл) не моргает.
Не понимаю почему не работает основной цикл?
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect)
{
PORTA |= (1<<PA4);
}
int main(void)
{
//TIMER0 -------------------------------------------------
TCCR0 |= (1<<CS02)|(1<<CS00); // устанавливаем прескалер - 1024
TIFR = 1<<TOV0; // очищаем флаг прерывания таймера Т0
TIMSK |= 1<<TOIE0; // разрешаем прерывание по переполнению
TCNT0 = 0; // загружаем начальное зн. в счетный регистр
sei();
DDRA = 0xFF;
DDRD = 0xFF;
PORTA |= (1<<PA4); _delay_ms(500);
PORTD |= (1<<PD5); _delay_ms(500);
PORTA = 0;
PORTD = 0;
while (1)
{
PORTD ^= (1<<PD5); _delay_ms(500);
}
}
Так вон же Кино всё выложил на блюдечке. Или мало?
А можно ссылку?
Блин, какой однако контроллер я выбрал.
Неужто с ним все так сложно и нет мастеров.
Попробовал несколько bootloader
http://robot-develop.org/archives/1092
http://easyelectronics.ru/avr-uchebnyj-kurs-ispolzovanie-bootloadera.html
Сам не разберусь, только начинаю осваивать.
Спасибо за подсказки. Контроллер подключил, USBArt читает, пишет.
Есть желание перейти на заливку кода через бутлоадер.
Подскажите, пожалуйста, нормальный и не сложный (для начинающего) бутлоадер для atmega128
Пробовал http://easyelectronics.ru/avr-uchebnyj-kurs-ispolzovanie-bootloadera.html,
чтото не смог осилить, после заливки светодиод загорается и не гаснет, т.е. насколько я понял вополнение попадает в загнрузчик и там виснет.
Т.е. или USBasp или USART для com порта.
Параллельно их нельзя включать?
Подскажите, пожалуйста, еще один вопрос.
У меня програматор USBasp.
Получается, что я лишился USART0, подключив USBasp по вышеуказанной схеме?
Можно ли это как-то обойти?
Предполагалось что програматор я подключу к MISO, MOSI, а USART0 использую для подключения к компьютеру через COM-USB переходник (USB to TTL YP-01).
Второй USART (USART1) предполагалось в последующем использовать для соединения с GSM модулем.
У меня контора закупила лазерный резак и режет фанеру. Думаю что можно договориться. Для начала нужен макет резки, например в CorelDraw, и количество. Цену можно будет узнать. Это в Днепре.
Разобрался.
На самом деле ноги програмирования не соответствуют проведенному в даташите.
Для 128 меги ноги программирования - другие
MOSI PE0
MISO PE1
SCK PB1
Подключил - заработало. Теперь хочу найти эту информацию в описании, ведь где-то это написано.
Здравствуйте.
Есть давнее желание поработать с контроллерами.
Купил контроллер, програматор USBasp и прочее.
По началу купил ATMega128. Припаял ее к переходнику с TQFP64.
Присоединил в программатору - не видит он контроллер.
Вознкла мыли что либо спалил контроллер лбо чтото с програматором.
Купил ATMega8 в DIP корпусе - поставил на макетную плату - програматор увидел его, все работает.
Купил второй контроллер ATMega128, перепаял на переходник - опять не работает.
Может у кого-то есть возможность подсоединить контроллер к своему програматору и проверить работоспособность, может у меня програматор кривой, может руки кривые или присоединил не так.
На контроллер подал питание, присоединил програматор. Пытался с и без кварца.
Должен ли контроллер ATMega128 работать без обвеса (ATMega8 работал)?
Сторінки 1