Передатчик и приемник - два разных микроконтроллера, никак не синхронизированные. Включаем питание, по программе включется UART и там и там. Но момент то включения разный. Понятно, что определенный, но не для контроллеров относительно друг друга.
_________________ We do what we must because we can (c) GLaDOS
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Пн июн 08, 2015 10:42:36
Модератор
Карма: 90
Рейтинг сообщений: 1443
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4609 Откуда: Планета Земля
Рейтинг сообщения:1 Медали: 1
Если передатчик постоянно, без всяких пауз, долбит байт за байтом - руки оторвать такому разработчику. Между пакетами в передатчике всегда делается пауза, для синхронизации с ним приёмной стороны. Если пауз никаких нет, то вы никак не ссинхронизируетесь ни со старт-битом, ни, тем более, с началом пакета.
начнется передача на передатчике и прием на приемнике (жуть какая)
Ну это алгоритм работы Одесского базара. В реальных сетях есть, как правило, мастер и слейв. Работают они по логическому протоколу. Мастер дает запрос, слейв (-ы ) отвечает. Если надо врубиться в чужую сеть ( шпионские страсти ), то надо дождаться тайм-аута ( состояние стоп-біта в течение времени > времені передачі одного байта [ блін, на украінскую раскладку перескочіло - хакеры ? - у меня на компе ее нет!] ) . І с этого момента ждать стартового біта. Прі этом нужно знать параметры передачі ( см. выше ) . Теоретіческі можно, думаю, программно іх определіть і к нім подстроіться, практіческі мне не пріходілось, да і нах. Но это уже далеко за рамкамі спрошенного вопроса.
Если передатчик постоянно, без всяких пауз, долбит байт за байтом - руки оторвать такому разработчику. Между пакетами в передатчике всегда делается пауза, для синхронизации с ним приёмной стороны. Если пауз никаких нет, то вы никак не ссинхронизируетесь ни со старт-битом, ни, тем более, с началом пакета.
Спасибо, в том и был вопрос. Синхронизация идет через паузу передатчика. В обучалках этот момент мне не попадался в явном виде, а сам долго доходил до самой необходимости такой синхронизации при асинхронной передаче. Теперь стало ясно, чего оно у меня не шевелится.
_________________ We do what we must because we can (c) GLaDOS
Пис'ал с обчественного компа и вдруг ни с того ни с сего EN=B RU=i . Раскладка, конечно, нашенская, белорусская. Но откуда ей взяться ? Впрочем, комп ничейный, лапают кому не лень. Могло быть и хуже.
Во первых не подключена ни одна библиотека, а во вторых не подключена библиотека sub1.c надо прописать #include "sub1.c"
господи, ну сколько можно?! никогда не подключайте сишные файлы директивой #include !!!! ну хотя бы самый простенький букварик по Си прочтите, наконец!
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Вт июн 30, 2015 06:14:03
Первый раз сказал Мяу!
Карма: 4
Рейтинг сообщений: 4
Зарегистрирован: Пт мар 07, 2014 18:37:20 Сообщений: 38 Откуда: Пермь
Рейтинг сообщения:0
ARV писал(а):
rxstart1 писал(а):
Во первых не подключена ни одна библиотека, а во вторых не подключена библиотека sub1.c надо прописать #include "sub1.c"
господи, ну сколько можно?! никогда не подключайте сишные файлы директивой #include !!!! ну хотя бы самый простенький букварик по Си прочтите, наконец!
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Вт июн 30, 2015 16:45:20
Родился
Зарегистрирован: Пн май 05, 2014 11:59:11 Сообщений: 15
Рейтинг сообщения:0
Да хочу функцию написать по закрашиванию пикселя по координатам что то вроде: x = 50; y = 60; draw_pixel(x, y); собственно мне нужны команды для выхода на эти координаты, пока есть только идея использовать 21h и 22h, но там сообщение длинное получается Еще я по команде 81h не могу изменить контраст(((
Добрый день, подскажите как более правильно организовать следующую библиотеку.
service_timer.с Спойлер
Код:
#include <service_timer.h>
volatile unsigned int Timir[MAX_TIMERS];
unsigned int GetTimers(unsigned char timers){ return Timir[timers]; } void ResetTimers(unsigned char timers){ Timir[timers]=0; } void StartTimers(unsigned char timers){ Timir[timers]=0xFFFD; //65533 2ms что бы дошло до нужного места программы }
void servic_timer(void){ unsigned char i=0; for (i=0; i<MAX_TIMERS; i++) { Timir[i]++; //-----Доработка что бы таймеры не обнулился после переполнения----- if(Timir[i]>0xFFFA){ //65530 (5 едениц запас) Timir[i]=0xFFFA; } } }
#define MAX_TIMERS 3 //****************************************************************************** // Секция определения глобальных переменных //****************************************************************************** extern volatile unsigned int Timir[MAX_TIMERS]; //****************************************************************************** //*******************Секция прототипов функций //****************************************************************************** unsigned int GetTimers(unsigned char timers); void ResetTimers(unsigned char timers); void StartTimers(unsigned char timers); void servic_timer(void); #endif /* service_timer_h_*/ //****************************************************************************** // ENF OF FILE //******************************************************************************
Используется она достаточно просто servic_timer запускаем в таймер и всё дальше только работаем с Enum и не забываем изменять MAX_TIMERS
Так вот проблема в том что в одном проекте может быть 5 счётчиков в другом 10 в третьем 25 по этому файл service_timer.h от проекта к проекту меняется и приходится копировать его, что я думаю не совсем правильно. А создавать ещё один файл который содержит только enum тоже как-то не то. Как в таком случае создать библиотеку? (единую для всех проектов) и где и как лучше разместить различия?
вообще-то в Си "библиотекой" принято называть специальным образом скомпилированный объектный файл. а когда вы работаете с исходниками, это и называется "исходник", библиотекой это называем мы некорректно.
так вот, настоящая библиотека, например, math, собирается единожды и затем уже никак не позволяет вам менять макросы, которые были при ее сборке определены, хотя в math.h у вас эти макросы перечислены и вроде бы даже доступны для изменения. эти изменения никак не повлияют на библиотеку, только на ваши исходники.
поэтому если вы все-таки будете работать с исходниками, в вашем подходе нет никакого криминала, более того, копирование исходников - это чуть ли не единственно корректный подход в этом случае!
но если уж вы совсем щепитильно хотите следить за неизменностью "основного" кода вашей "библиотеки", можете сделать что-то вроде этого:
то есть если "где-то раньше" не определен макрос MAX_TIMERS, будет использовано дефолтное значение, а если определено - то оно и будет использовано. таким образом в своем проекте вы получаете право делать любое количество таймеров, не влезая в "основной код либы".
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
// Функция чтения данных по шине uint8_t I2CReadByte(uint8_t *data,uint8_t ack) { if(ack) // Устанавливаем подтверждение { // Возвращаем подтверждение после приема TWCR |= (1 << TWEA); } else { // Возвращаем неподтверждение после приема // Ведомое устройство не получает больше данных // обычно используется для распознования последнего байта TWCR &= ~(1 << TWEA); } // Разрешение приема данных после сброса TWINT TWCR |= (1 << TWINT); while(!(TWCR & (1 << TWINT))); // Ожидание установки флага TWINT // Проверка статуса if((TWSR & 0xF8) == 0x58 || (TWSR & 0xF8) == 0x50) { // Прием данных и возвращение подтверждения // или // Прием данных и возвращение неподтверждения *data = TWDR; // Читаем данные return 1; } else return 0; // Ошибка }
void I2CStart(void) { // Передача условия СТАРТ TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWSTA); // Ожидание установки флага TWINT while(!(TWCR & (1 << TWINT))); }
void I2CStop(void) { TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWSTO); // Передача условия СТОП while(TWCR & (1 << TWSTO)); // Ожидание завершения передачи условия СТОП }
// Функция записи данных по шине uint8_t I2CWriteByte(uint8_t data) { TWDR = data; // Загрузка данных в TWDR TWCR = (1 << TWEN)|(1 << TWINT); // Сброс флага TWINT для начала передачи данных while(!(TWCR & (1 << TWINT))); // Ожидание завершения передачи // Проверка статуса if((TWSR & 0xF8) == 0x18 || (TWSR & 0xF8) == 0x28 || (TWSR & 0xF8) == 0x40) { // Если адрес DS1307, биты R/W и данные переданы // и получено подтверждение return 1; } else return 0; // ОШИБКА }
// Функция чтения данных по шине uint8_t I2CReadByte(uint8_t *data,uint8_t ack) { if(ack) // Устанавливаем подтверждение { // Возвращаем подтверждение после приема TWCR |= (1 << TWEA); } else { // Возвращаем неподтверждение после приема // Ведомое устройство не получает больше данных // обычно используется для распознования последнего байта TWCR &= ~(1 << TWEA); } // Разрешение приема данных после сброса TWINT TWCR |= (1 << TWINT); while(!(TWCR & (1 << TWINT))); // Ожидание установки флага TWINT // Проверка статуса if((TWSR & 0xF8) == 0x58 || (TWSR & 0xF8) == 0x50) { // Прием данных и возвращение подтверждения // или // Прием данных и возвращение неподтверждения *data = TWDR; // Читаем данные return 1; } else return 0; // Ошибка } // Функция чтения данных из DS1307 uint8_t DS1307Read(uint8_t address,uint8_t *data) { uint8_t res; // Результат I2CStart(); // СТАРТ res = I2CWriteByte(0b11010000); // адрес DS1307 + бит W if(!res) return 0; // ОШИБКА // Передача адреса необходимого регистра res = I2CWriteByte(address); if(!res) return 0; // ОШИБКА I2CStart(); // Повторный СТАРТ res = I2CWriteByte(0b11010001); // адрес DS1307 + бит R if(!res) return 0; // ОШИБКА // Чтение данных с неподтверждением res = I2CReadByte(data,0); if(!res) return 0; // ОШИБКА I2CStop(); // СТОП return 1; } // Функция записи данных в DS1307 uint8_t DS1307Write(uint8_t address,uint8_t data) { uint8_t res; // Результат I2CStart(); // СТАРТ res = I2CWriteByte(0b11010000); // адрес DS1307 + бит W if(!res) return 0; // ОШИБКА // Передача адреса необходимого регистра res = I2CWriteByte(address); if(!res) return 0; // ОШИБКА res = I2CWriteByte(data); // Запись данных if(!res) return 0; // ОШИБКА I2CStop(); // СТОП return 1; } // Функции работы с LCD #define RS PD0 #define EN PD2 // Функция передачи команды void lcd_com(unsigned char p) { PORTD &= ~(1 << RS); // RS = 0 (запись команд) PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл _delay_us(100); PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл _delay_us(100); PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); } // Функция передачи данных void lcd_data(unsigned char p) { PORTD |= (1 << RS)|(1 << EN); // RS = 1 (запись данных), EN - 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл _delay_us(100); PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл _delay_us(100); PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); } // Функция вывода строки на LCD void lcd_string(unsigned char command, char *string) { lcd_com(0x0C); lcd_com(command); while(*string != '\0') { lcd_data(*string); string++; } } // Функция вывода переменной void lcd_num_to_str(unsigned int value, unsigned char nDigit) { switch(nDigit) { case 4: lcd_data((value/1000)+'0'); case 3: lcd_data(((value/100)%10)+'0'); case 2: lcd_data(((value/10)%10)+'0'); case 1: lcd_data((value%10)+'0'); } } // Функция инициализации LCD void lcd_init(void) { PORTD = 0x00; DDRD = 0xFF;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 168
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения