CodeVision AVR в вопросах и ответах
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: CodeVision AVR в вопросах и ответах
Там вроде проблема даже с прямым обращением к массиву.
Как ведет себя программа, если задать массив фиксированной длины uint8_t first[9];
Или если обращаться как к указателю
uint8_t *first = ...
*(first+5) = 1;
Как ведет себя программа, если задать массив фиксированной длины uint8_t first[9];
Или если обращаться как к указателю
uint8_t *first = ...
*(first+5) = 1;
- Реклама
-
Pnjom-Penb
- Мучитель микросхем
- Сообщения: 469
- Зарегистрирован: Вс авг 30, 2015 03:52:59
Re: CodeVision AVR в вопросах и ответах
Вечером воскресного дня как-то не въехал - в чем проблема-то?COKPOWEHEU писал(а):Там вроде проблема даже с прямым обращением к массиву.
Как ведет себя программа, если задать массив фиксированной длины uint8_t first[9];
Или если обращаться как к указателю
uint8_t *first = ...
*(first+5) = 1;
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: CodeVision AVR в вопросах и ответах
Я вот про эту цитату, стоит разобраться где здесь баг.Даже такая простая операция выдаёт: first = 0 1 2 3 0 0 0 0 0Код: Выделить всё
D2printf("first = "); for(i=0;i<9;i++) { first[i] = i; D2printf("%u ", first[i]); } D2printf("\n");
Re: CodeVision AVR в вопросах и ответах
Доброго времени суток.
Где-то закрался косяк с скромный код программы-вольтметра (вернее измерителя АЦП) с выводом значения на LCD 16x2 экранчик.
Отдельно измеритель код АЦП работает, что показывает не одно моё устройство.
Отдельно вывод динамических данных на дисплей тоже работает. Проверил...
Всё это вместе работает более чем странно:
Значения АЦП должны быть 0...1024, но независимо от того, на GND или на Vcc я подкину ногу ADC0, на экране данные от 100 до 9800 (примерно)
И скачут как им хочется.
МК ATmega8A.
Может кто ткнёт носом в ошибку?
AVR Core Clock frequency: 1,000000 MHz
*****************/
#include <mega8.h>
#include <lcd.h>
#include <delay.h>
#include <stdio.h> // библиотека для преобразования переменных в строки
#asm
.equ __lcd_port=0x12; PORTD /* ЖКИ дисплей подключили к порту I/O D */
#endasm
// Обьявзяем переменные
char lcd_buffer[20]; // создается буфер (масив) для символов, выводимых на дисплей
unsigned int res; // переменная для хранения хначения АЦП
//Функция измерения АЦП
unsigned int ADC_result(void)
{
ADCSRA = 0b10000100; // - предделитель на 16, прерывания запрещены, ADC включён
ADMUX = 0b11000000; // - 2.56VCC , ACD0, ADLAR off
delay_us(30); //задержка для стабилизации
ADCSRA |= 0x40; //начинаем измерение
while((ADCSRA & 0x10)==0); //Ждём флаг окончания измерения
ADCSRA |=0x10;
return ADCW; //Возвращаем функции значение регистра ADCW
}
void main(void) /* Основная функция "main", с которой начинается выполнение всей программой процедуры */
{
lcd_init(16);
lcd_gotoxy(2,0);
lcd_putsf("Digital ADC");
lcd_gotoxy(1,1);
lcd_putsf("CodeVision AVR");
delay_ms(1000);
lcd_clear();
while(1){
res = ADC_result(); //значение измерения АЦП присваеваем переменной RES
lcd_gotoxy(0,0);
sprintf(lcd_buffer, "ADC = %i", res); // преобразуем переменные в строки
lcd_puts(lcd_buffer); // выводим строку на дисплей
delay_ms(500);
lcd_clear(); // первая ошибка
}
}
UPD1: если добавить очистку дисплея после каждого преобразования, то данные на дисплее станут более правдопадобными. При подключении на "землю" показывает 105...90, а при подключении на +5 показывает ~900.
Но тем не менее врёт...
Где-то закрался косяк с скромный код программы-вольтметра (вернее измерителя АЦП) с выводом значения на LCD 16x2 экранчик.
Отдельно измеритель код АЦП работает, что показывает не одно моё устройство.
Отдельно вывод динамических данных на дисплей тоже работает. Проверил...
Всё это вместе работает более чем странно:
Значения АЦП должны быть 0...1024, но независимо от того, на GND или на Vcc я подкину ногу ADC0, на экране данные от 100 до 9800 (примерно)
МК ATmega8A.
Может кто ткнёт носом в ошибку?
Спойлер
/****************AVR Core Clock frequency: 1,000000 MHz
*****************/
#include <mega8.h>
#include <lcd.h>
#include <delay.h>
#include <stdio.h> // библиотека для преобразования переменных в строки
#asm
.equ __lcd_port=0x12; PORTD /* ЖКИ дисплей подключили к порту I/O D */
#endasm
// Обьявзяем переменные
char lcd_buffer[20]; // создается буфер (масив) для символов, выводимых на дисплей
unsigned int res; // переменная для хранения хначения АЦП
//Функция измерения АЦП
unsigned int ADC_result(void)
{
ADCSRA = 0b10000100; // - предделитель на 16, прерывания запрещены, ADC включён
ADMUX = 0b11000000; // - 2.56VCC , ACD0, ADLAR off
delay_us(30); //задержка для стабилизации
ADCSRA |= 0x40; //начинаем измерение
while((ADCSRA & 0x10)==0); //Ждём флаг окончания измерения
ADCSRA |=0x10;
return ADCW; //Возвращаем функции значение регистра ADCW
}
void main(void) /* Основная функция "main", с которой начинается выполнение всей программой процедуры */
{
lcd_init(16);
lcd_gotoxy(2,0);
lcd_putsf("Digital ADC");
lcd_gotoxy(1,1);
lcd_putsf("CodeVision AVR");
delay_ms(1000);
lcd_clear();
while(1){
res = ADC_result(); //значение измерения АЦП присваеваем переменной RES
lcd_gotoxy(0,0);
sprintf(lcd_buffer, "ADC = %i", res); // преобразуем переменные в строки
lcd_puts(lcd_buffer); // выводим строку на дисплей
delay_ms(500);
lcd_clear(); // первая ошибка
}
}
Но тем не менее врёт...
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Re: CodeVision AVR в вопросах и ответах
новые данные накладываются на старыеDataLife писал(а): если добавить очистку дисплея после каждого преобразования, то данные на дисплее станут более правдопадобными.
- Реклама
Re: CodeVision AVR в вопросах и ответах
Вопрос решил.
Ещё всё досконально проверю, но вышло так: скорее всего нужно было подтянуть AREF на землю через конденсатор. На моей версии плате это я не предусмотрел, зато предусмотрел LC фильтр для AVCC. Перенастроил АЦП на эту ногу, а не на внутренние 2.56В, и всё стало показывать верно.
Учиться... учиться ... и ещё раз учиться
Как бы то ни было, всем спасибо
Ещё всё досконально проверю, но вышло так: скорее всего нужно было подтянуть AREF на землю через конденсатор. На моей версии плате это я не предусмотрел, зато предусмотрел LC фильтр для AVCC. Перенастроил АЦП на эту ногу, а не на внутренние 2.56В, и всё стало показывать верно.
Учиться... учиться ... и ещё раз учиться
Как бы то ни было, всем спасибо
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Re: CodeVision AVR в вопросах и ответах
Здравствуйте, у меня следующая проблема. С ATmega8 мне необходимо управлять драйвером шаговика по step/dir. Кусок кода ниже работает, но если заявить переменную Apos в eeprom, то ничего не работает (драйвер включает обмотки хаотично, LCD- экранчик не инициализируется). Кажется, что контроллер не стартует. Не могу понять как это может быть связано с тем, для какой памяти я заявляю переменную.
Код: Выделить всё
eeprom int Zpos= 10000; //заданное положение
int Apos=0; //актуальное положение
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0x83;
if (Apos==Zpos)
{MOTOR_ENABLE=0;}
else
{
if (Apos<Zpos)
{
MOTOR_DIRECTION=1;
MOTOR_ENABLE=1;
MOTOR_STEP=1;
delay_us(5) ;
MOTOR_STEP=0;
Apos++;
}
else
{
MOTOR_DIRECTION=0;
MOTOR_ENABLE=1;
MOTOR_STEP=1;
delay_us(5) ;
MOTOR_STEP=0;
Apos--;
}
};
}
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
А не жалко EEPROM так насиловать?
Он, во-первых, медленный (запись вполне может не успевать в прерывании выполниться), во-вторых, ограничен в количестве циклов перезаписи. Несколько минут работы с eeprom Apos++ в прерывании - и МК можно выбрасывать на мусорку. Ну или забыть про дальнейшее использование EEPROM в нём.
Он, во-первых, медленный (запись вполне может не успевать в прерывании выполниться), во-вторых, ограничен в количестве циклов перезаписи. Несколько минут работы с eeprom Apos++ в прерывании - и МК можно выбрасывать на мусорку. Ну или забыть про дальнейшее использование EEPROM в нём.
Re: CodeVision AVR в вопросах и ответах
Спасибо за разъяснение. Просто я хотел чтобы он позицию помнил после выключения.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Ну так и запоминать надо при выключении, восстанавливая при включении значение.
А сотню раз в секунду флеш писать - это издевательство над МК.
А сотню раз в секунду флеш писать - это издевательство над МК.
Re: CodeVision AVR в вопросах и ответах
А можно сделать так чтобы контроллер понял, что его выключают. Или придется делать кнопку, по которой он будет копировал переменную в еепром ?
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Проще кнопкой. Но можно и с помощью АЦП или входа INT0/1. Главное, чтобы питание МК снижалось медленнее (за счёт тех же конденсаторов по питанию) чем напряжение на входе АЦП или уровень на INT0/1 (резистивный делитель, отделённый диодом от основного питания). Тогда можно отловить факт отключения и сохранить в EEPROM значение ещё до того, как питание МК окончательно пропадёт.
В широко известном на форуме проекте часов подобное реализовано.
В широко известном на форуме проекте часов подобное реализовано.
Re: CodeVision AVR в вопросах и ответах
Доброго времени суток, коты!
Не могу разобраться в, казалось бы, простых вещах.
МК: ATmega8
Суть: нужно сидеть в цикле while до тех пор, пока некая переменная не поменяет своё значение с 0 на 1.
Сама переменная изменяет своё значение в результате внешнего прерывания по INT1.
У меня же этот цикл пролетает, не дожидаясь изменения переменной, а далее, когда нужно зайти в цикл при условии "переменная == 1" он не заходит.
Может криво объяснил, но вот часть программы:
interrupt [EXT_INT1] void ext_int1_isr(void) // обработчик прерывания от кнопки СТАРТ
{
start++;
if (start == 2)
{start = 0;}
}
void main(void)
{
#asm("sei") // глобально разрешаем прерывания
GICR|=0x80; // разрешаем прерывание по INT1
MCUCR=0x08; // прерывание по спадающему фронту сигнала на INT1
GIFR=0x80;
while (start == 0) // пока не нажали кнопку пуска...
{
// делаем что-то, ПОКА переменная старт = 0
}
/*** ещё часть программы ***/
while (start == 1)
{
// делаем что-то, ПОКА переменная старт = 1
}
}
То есть цикл while (start == 0) у меня выполняется один раз, а в цикл while (start == 1) вообще не заходит...
Есть подозрения, что виной тому LCD 16x2, что подключён к порту D. Но нога с INT1 (PD3) как-раз не занята и её-то я и использую для прерываний...
Помогите, будьте добры...
Не могу разобраться в, казалось бы, простых вещах.
МК: ATmega8
Суть: нужно сидеть в цикле while до тех пор, пока некая переменная не поменяет своё значение с 0 на 1.
Сама переменная изменяет своё значение в результате внешнего прерывания по INT1.
У меня же этот цикл пролетает, не дожидаясь изменения переменной, а далее, когда нужно зайти в цикл при условии "переменная == 1" он не заходит.
Может криво объяснил, но вот часть программы:
Спойлер
unsigned char start = 0;interrupt [EXT_INT1] void ext_int1_isr(void) // обработчик прерывания от кнопки СТАРТ
{
start++;
if (start == 2)
{start = 0;}
}
void main(void)
{
#asm("sei") // глобально разрешаем прерывания
GICR|=0x80; // разрешаем прерывание по INT1
MCUCR=0x08; // прерывание по спадающему фронту сигнала на INT1
GIFR=0x80;
while (start == 0) // пока не нажали кнопку пуска...
{
// делаем что-то, ПОКА переменная старт = 0
}
/*** ещё часть программы ***/
while (start == 1)
{
// делаем что-то, ПОКА переменная старт = 1
}
}
Есть подозрения, что виной тому LCD 16x2, что подключён к порту D. Но нога с INT1 (PD3) как-раз не занята и её-то я и использую для прерываний...
Помогите, будьте добры...
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Для начала я бы сделал эту переменную volatile, коль скоро она в прерывании меняется.
Re: CodeVision AVR в вопросах и ответах
Большое спасибо за подсказку, исправил 
В принципе, проблему решил, всё работает.
Сделал подтяжку резистором на землю к ИНТ1, про неё я тоже забыл
В принципе, проблему решил, всё работает.
Сделал подтяжку резистором на землю к ИНТ1, про неё я тоже забыл
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
- alex-wolf
- Открыл глаза
- Сообщения: 63
- Зарегистрирован: Сб мар 09, 2013 21:46:01
- Откуда: Уфа
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Здравствуйте
кто сможет помочь есть таблица для графо-генератора, и есть функция которая вызывается в момент запроса символа на индикатор
http://yandex.ru/clck/jsredir?from=yand ... 1926211216
есть немого лишнего, к каждому разряду -цвета нужно указывать таблицу, а это съедает память (еще нужно запихнуть для atmega8 еще и протокол mod_bus с фиксированным адресом , и читать указанные регистры, и исходя из значений выводить число, норма =зеленый, повышенный =оранжевый , критично = красный)


в конкретном примере значение числа производилось из чтение регистра секунд ds1307



кусочек кода для оценки что получилось
pwm_=2;
//delay_ms(1000);
red_x10=red_x1='_'; green_x10='S';green_x1='T';green_x1='.';
delay_ms(1000);
pwm_=3;
BlkScrAll(); pwm_=1;
while (1) {
read_date_time(&sec,&minut,&hour,&day,&date,&month,&year);
ds1307_rddata=bcd2bin(ds1307_read(0x0));
//*
//используются для сравнения переменных, чисел (констант) и выражений.
//x < y // X меньше Y
//x > y // больше
//x <= y // меньше или равно
//x >= y // больше или равно
//x == y // равно
//x != y /* не равно
//| | // "ИЛИ" - только "ложь" и "ложь"
// дают "ложь"
//&& // "И" - только "истина" и "истина"
// дают "истина"
//! "НЕ" - логическое отрицание
//////////////////////////////////////////
// green_x1=((rc5_command));
// green_x10=((rc5_device));
//// green_x1=((rc5_command)10);
//// green_x10=((rc5_device)10);
////number_r(rc5_adr_out);
//green_x10_dp=(rc5_trg_out); red_x1_dp=(RC5_buffer [0]); green_x1_dp=(RC5_buffer [1]);
// BlkScrAll();
//
if((ds1307_rddata)<50) {
// green_x1=((ds1307_rddata)%10);
// green_x10=((ds1307_rddata)/10);
number_g(ds1307_rddata);
if ((ds1307_rddata) & (0x01) ) {green_x1_dp=(1);}
else {green_x1_dp=(0);};
}
else {
// red_x1=((ds1307_rddata)%10);
// red_x10=((ds1307_rddata)/10);
if ((ds1307_rddata) & (0x01) ) {green_x1_dp=(1);}
else {green_x1_dp=(0);};
number_r(ds1307_rddata);
}
if((ds1307_rddata)>44) {
// red_x1=((ds1307_rddata)%10);
// red_x10=((ds1307_rddata)/10);
// green_x1=((ds1307_rddata)%10);
// green_x10=((ds1307_rddata)/10);
number_y(ds1307_rddata);
if ((ds1307_rddata) & (0x01) ) {green_x1_dp=(1);}
else {green_x1_dp=(0);};
};
if((ds1307_rddata)>54) {
// BlkScrAll();
// red_x1=((ds1307_rddata)%10);
// red_x10=((ds1307_rddata)/10);
number_r(ds1307_rddata);
if ((ds1307_rddata) & (0x01) ) {green_x1_dp=(1);}
else {green_x1_dp=(0);}; };
if ((ds1307_rddata)==03 || PIND.2 == 0){;BlkScrAll();delay_ms(500);green_x10=(21);delay_ms(500);BlkScrAll();delay_ms(500);
green_x1=(((bcd2bin(ds1307_read(0x2))))%10);red_x1_dp=(1); green_x10=(((bcd2bin(ds1307_read(0x2))))/10);
delay_ms(1000);BlkScrAll();
BlkScrAll();delay_ms(500);number_g(bcd2bin(ds1307_read(0x1)));delay_ms(1000);BlkScrAll(); }
//// green_x1=red_x1=((bcd2bin(ds1307_read(0x0)))%10);
//red_x10=green_x10=((bcd2bin(ds1307_read(0x0)))/10);
delay_ms(1);
};
};
кто сможет помочь есть таблица для графо-генератора, и есть функция которая вызывается в момент запроса символа на индикатор
http://yandex.ru/clck/jsredir?from=yand ... 1926211216
есть немого лишнего, к каждому разряду -цвета нужно указывать таблицу, а это съедает память (еще нужно запихнуть для atmega8 еще и протокол mod_bus с фиксированным адресом , и читать указанные регистры, и исходя из значений выводить число, норма =зеленый, повышенный =оранжевый , критично = красный)


в конкретном примере значение числа производилось из чтение регистра секунд ds1307



кусочек кода для оценки что получилось
pwm_=2;
//delay_ms(1000);
red_x10=red_x1='_'; green_x10='S';green_x1='T';green_x1='.';
delay_ms(1000);
pwm_=3;
BlkScrAll(); pwm_=1;
while (1) {
read_date_time(&sec,&minut,&hour,&day,&date,&month,&year);
ds1307_rddata=bcd2bin(ds1307_read(0x0));
//*
//используются для сравнения переменных, чисел (констант) и выражений.
//x < y // X меньше Y
//x > y // больше
//x <= y // меньше или равно
//x >= y // больше или равно
//x == y // равно
//x != y /* не равно
//| | // "ИЛИ" - только "ложь" и "ложь"
// дают "ложь"
//&& // "И" - только "истина" и "истина"
// дают "истина"
//! "НЕ" - логическое отрицание
//////////////////////////////////////////
// green_x1=((rc5_command));
// green_x10=((rc5_device));
//// green_x1=((rc5_command)10);
//// green_x10=((rc5_device)10);
////number_r(rc5_adr_out);
//green_x10_dp=(rc5_trg_out); red_x1_dp=(RC5_buffer [0]); green_x1_dp=(RC5_buffer [1]);
// BlkScrAll();
//
if((ds1307_rddata)<50) {
// green_x1=((ds1307_rddata)%10);
// green_x10=((ds1307_rddata)/10);
number_g(ds1307_rddata);
if ((ds1307_rddata) & (0x01) ) {green_x1_dp=(1);}
else {green_x1_dp=(0);};
}
else {
// red_x1=((ds1307_rddata)%10);
// red_x10=((ds1307_rddata)/10);
if ((ds1307_rddata) & (0x01) ) {green_x1_dp=(1);}
else {green_x1_dp=(0);};
number_r(ds1307_rddata);
}
if((ds1307_rddata)>44) {
// red_x1=((ds1307_rddata)%10);
// red_x10=((ds1307_rddata)/10);
// green_x1=((ds1307_rddata)%10);
// green_x10=((ds1307_rddata)/10);
number_y(ds1307_rddata);
if ((ds1307_rddata) & (0x01) ) {green_x1_dp=(1);}
else {green_x1_dp=(0);};
};
if((ds1307_rddata)>54) {
// BlkScrAll();
// red_x1=((ds1307_rddata)%10);
// red_x10=((ds1307_rddata)/10);
number_r(ds1307_rddata);
if ((ds1307_rddata) & (0x01) ) {green_x1_dp=(1);}
else {green_x1_dp=(0);}; };
if ((ds1307_rddata)==03 || PIND.2 == 0){;BlkScrAll();delay_ms(500);green_x10=(21);delay_ms(500);BlkScrAll();delay_ms(500);
green_x1=(((bcd2bin(ds1307_read(0x2))))%10);red_x1_dp=(1); green_x10=(((bcd2bin(ds1307_read(0x2))))/10);
delay_ms(1000);BlkScrAll();
BlkScrAll();delay_ms(500);number_g(bcd2bin(ds1307_read(0x1)));delay_ms(1000);BlkScrAll(); }
//// green_x1=red_x1=((bcd2bin(ds1307_read(0x0)))%10);
//red_x10=green_x10=((bcd2bin(ds1307_read(0x0)))/10);
delay_ms(1);
};
};
Re: CodeVision AVR в вопросах и ответах
Товарищи, выручайте!
Не могу корректно выполнить поставленную задачу.
Делаю некое зарядное с мозгами на мега8.
Нужно мне увеличивать ШИМ, если напряжение на шунте (ток) ниже заданного.
Делал так:
while (1) {
while (ADC_shunt() <= ("условие"))
{
OCR2=OCR2+0x01;
if (OCR2==0xFF) break;
}
/** вывод разного на экран ***/
}
Дальше идёт вывод всего на дисплей, то не важно.
Казалось бы всё просто и верно: пока условие "напряжение меньше чем должно быть" - увеличиваем OCR2. Соответственно вырос реальный ток - выросло напряжение на шунте и тд. Если OCR2 достигло своего максимального значения, а условие не выполнено - выходим из цикла. Ну проще некуда!
Но!
Имитирую шунт подстроечником. Выставляю значения АЦП ниже заданного. Условие цикла "верно". ШИМ растёт, вижу (светодиод подцепил). Как только достигло максимального значения таки выходит из цикла и дальше выводит всё на экран. Но вот потом... Потом МК снова заходит в цикл, сбрасывает OCR2
в ноль и набирает снова до максимума и выходит из цикла.
Собственно вопрос:
1. Почему OCR2 сбрасывается?
2. Как это исправить?
Не могу корректно выполнить поставленную задачу.
Делаю некое зарядное с мозгами на мега8.
Нужно мне увеличивать ШИМ, если напряжение на шунте (ток) ниже заданного.
Делал так:
while (1) {
while (ADC_shunt() <= ("условие"))
{
OCR2=OCR2+0x01;
if (OCR2==0xFF) break;
}
/** вывод разного на экран ***/
}
Дальше идёт вывод всего на дисплей, то не важно.
Казалось бы всё просто и верно: пока условие "напряжение меньше чем должно быть" - увеличиваем OCR2. Соответственно вырос реальный ток - выросло напряжение на шунте и тд. Если OCR2 достигло своего максимального значения, а условие не выполнено - выходим из цикла. Ну проще некуда!
Но!
Имитирую шунт подстроечником. Выставляю значения АЦП ниже заданного. Условие цикла "верно". ШИМ растёт, вижу (светодиод подцепил). Как только достигло максимального значения таки выходит из цикла и дальше выводит всё на экран. Но вот потом... Потом МК снова заходит в цикл, сбрасывает OCR2
Собственно вопрос:
1. Почему OCR2 сбрасывается?
2. Как это исправить?
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
ну так вы закончили цикл в момент, когда OCR2==0xFF, а потом входите в цикл снова и увеличиваете OCR2 на 1. что будет если к байту 0xFF прибавить 1? байт станет равным 0.DataLife писал(а):1. Почему OCR2 сбрасывается?
элементарно:DataLife писал(а):2. Как это исправить?
Код: Выделить всё
while (ADC_shunt() <= ("условие"))
{
if (OCR2==0xFF) break;
OCR2=OCR2+0x01;
}если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: CodeVision AVR в вопросах и ответах
ARV, ну просто от души спасибо! Пол дня решаю эту "загадку"!
Я-то думал, что если максимальное значение 256 есть, то добавив 1 мы его и не увеличим и не сбросим. А тут во как...
Ещё раз спасибо!
Я-то думал, что если максимальное значение 256 есть, то добавив 1 мы его и не увеличим и не сбросим. А тут во как...
Ещё раз спасибо!
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Максимальное значение восьмибитного (unsigned) числа не 256, а 255. Если добавить 1, будет 256, а это единица (она "выпадает" из восьми бит) и 8 нулей, что равносильно 0.


