Страница 381 из 422
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 08:41:17
serg_svd
Продолжаю разбираться с UART. Вроде получилось выводить текст на гипертерминал, используя созданную мастером функцию getchar();.
Осталось разобраться с приемом.
Но всплыли вопросы поважнее.
1. в начале кода у меня прописана строковая константа в EEPROM, я ранее уже интересовался по ее поводу. ПримерЖ
Код: Выделить всё
unsigned eeprom char Text[16]="Test EEPROM";
Эта константа сохраняется в EEPROM, начиная с адреса 0х00. Как сделать, чтобы нулевой адрес пропускался и писалось в адрес 0х01? Для защиты от сбоя. Я в интернете в описаниях кодевижена встречал фразу, что компилятор сам сдвигает данные и не дает заполнять ячейку 0х00. Но в настройках программы я этого не увидел.
2. Вопрос чисто сишный. Область хранения переменных может быть задана RAM, FLASH, EEPROM. Соответственно при вызове функции, которой требуется передать данные на обработку, тоже прописывается тип данных.
У меня сейчас получилось так, что есть данные во всех трех областях памяти, а функции их обрабатывающие по внутреннему коду идентичны. Отличие как раз в определении переменной в функции. Можно ли написать одну функцию, а вызывать ее с данными, хранящимися в RAM, FLASH, EEPROM вместо трех?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 08:59:52
pyzhman
1.
Код: Выделить всё
unsigned eeprom char Empty;
unsigned eeprom char Text[16]="Test EEPROM";
Добавлено after 5 minutes 38 seconds:
serg_svd писал(а):...Для защиты от сбоя...
Вы сталкивались с такими сбоями?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 09:35:44
serg_svd
pyzhman писал(а):
Код: Выделить всё
unsigned eeprom char Empty;
unsigned eeprom char Text[16]="Test EEPROM";
В первую очередь так пробовал. Компилятор ругается
Код: Выделить всё
Warning: global variable 'Empty' was declared, but not referenced
И тупо ее пропускает. Запись следующей константы начинается все равно с адреса 0х00
Вы сталкивались с такими сбоями?
Да слава Богу нет еще. Да и BODLEVEL включаю, если EEPROM использую. Но вот начитался "страстей" в интернете и решил сработать на предупреждение проблем

Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 10:00:36
uk8amk
2.
Данные хранятся в разных типах памяти и способы обращения к этим областям различаются. Если работа на уровне языка Си с этими данными идентична(или как минимум похожа), то компилятор AVR генерирует разный код.
LPM - для чтения флеш
LDS - для чтения ОЗУ
Такая задумка возможна на контроллерах с единым адресным пространством. В вашем случае придётся довольствоваться загрузкой данных в буфер ОЗУ и передачи его указателя в функцию обработки.
serg_svd писал(а):И тупо ее пропускает.
Есть волшебное слово volatile
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 10:09:39
pyzhman
Warning: global variable 'Empty' was declared, but not referenced
Надеюсь, поняли, что это обозначает?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 11:19:48
serg_svd
pyzhman писал(а):Надеюсь, поняли, что это обозначает?
Переменная объявлена, но не используется
uk8amk писал(а):Есть волшебное слово volatile
Попробовал, тоже не помогло.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 11:31:53
pyzhman
Так используйте ее вхолостую хотя бы раз.
Добавлено after 1 minute 34 seconds:
serg_svd писал(а):...начитался "страстей" в интернете...
Читать нужно еррата в даташите и следовать рекомендациям производителя.
Опять же
константа в EEPROM
Смысл? Что мешает хранить ее во флеше?
Возвращаясь к ЕЕПРОМ - используйте, если уж на то пошло, 24С...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 12:43:03
serg_svd
pyzhman писал(а):Читать нужно еррата в даташите и следовать рекомендациям производителя.
Читал. Поэтому BODLEVEL и включаю.
pyzhman писал(а):если уж на то пошло, 24С...
А смысла нет. Данные будут меняться очень редко. И проще их менять не перепрошивая каждый раз контроллер и не применяя внешнюю память. Объема EEPROM хватает с головой. Общение с устройством будет через UART. Через него же и ввод новых значений с последующей записью в EEPROM.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 15:32:39
oleg110592
serg_svd писал(а):Как сделать, чтобы нулевой адрес пропускался и писалось в адрес 0х01? Для защиты от сбоя.
лет незнаюсколько назад Атмел вроде победил порчу 0 ячейки еепром, если надо перебдеть, можно структурным способом:
Код: Выделить всё
eeprom struct eeprom_structure
{
unsigned char bad0E;
unsigned char var1E;
unsigned int var2E;
} par;
unsigned char temp;
void main(void)
{
temp = par.var1E;
while (1)
{
}
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт янв 26, 2017 21:06:00
AndTer
И всё же крокодил не ловится...
Протеус при симуляции показывает что каждый период запускается по три раза... Хотя должен по одному...
Понимаю что протеусу доверять сильно не стоит, но нет ничего чем мог бы записать и посмотреть что вылазит с мк...

И собственно код:
Спойлер
/*****************************************************
AVR Core Clock frequency: 16,000000 MHz
*****************************************************/
#include <mega8.h>
// Declare your global variables here
unsigned char SND[]={0x05,0x0D};
int i=1;
// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
OCR1AL=SND;
i=i-1;
if(i<0)i=1;
}
void main(void)
{
PORTB=0x00;
DDRB=0x02;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
// Mode: Fast PWM top=ICR1
// OC1A output: Non-Inv.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x82;
TCCR1B=0x18;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x13;
OCR1AH=0x00;
OCR1AL=0x13;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x20;
// Global enable interrupts
#asm("sei")
TCCR1B=0x19;
while (1)
{
// Place your code here
};
}
На проверку переменной i в прерывании не обращайте внимания, массив последовательностей, как и она сама, будет больше чем 1 поэтому такое условие.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пт янв 27, 2017 16:44:41
kadenca
Здравствуйте. Буду очень благодарен за любую помощь. Пытаюсь по UART получить заведомо известную строку и по этой строке выполнить определенное действие. Написал такой Код в CodeVision
volatile char led_ON[7]="Led_ON"; //верная строка для включения светодиода
volatile char led_OFF[7]="Led_OF";// верная строка для выключения светодиода
volatile char buff[6]; // буфер для размещения пришедших символов
while (1)
{
if(gets(buff,6)) // если пришедшие символы размещены в буфере, сравним их с заведомо известными строками
{
if ( strcmp(led_ON, buff) == 0) // если строки в массивах led_ON и buff совпадают
{ // включим светодиод
PORTB.0=1;
}
if ( strcmp(led_OFF, buff) == 0) // если строки в массивах led_OFF и buff совпадают
{ // выключим светодиод
PORTB.0=0;
}
printf("%s",buff,"\r\n");// выведем то что есть в буфере
}
}
вообщем как только я отсылаю по UART строку "Led_ON" светодиод загорается, отправляю "Led_OF" светодиод потухает. И так можно делать много раз и все работает.
Но стоит отправить что-то другой, например "123" и после этого команды "Led_ON" и "Led_OF" не работают (.
И по UART ф-цией printf() я получаю уже, что-то вроде _ONLed, d_ONLe... те же символы, но в разном порядке. Как с этим бороться?) Заранее большое спасибо.
P/S и еще вопрос в функции gets(buff,6) цифра 6 задает количество символов, которые необходимо записать из потока?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 11:08:11
AndTer
Подскажите "красивое" решение:
Имеем число, нужно разбить его на массив:
На выходе нужно получить:
Код: Выделить всё
M[0]=2
M[1]=5
M[2]=6
M[3]=8
M[4]=7
M[5]=9
...
Сам себе отвечаю:
Код: Выделить всё
unsigned long int X=256879;
int M[9];
unsigned long int e=0;
int i=0;
e=X;
for(i=5;i>=0;i--)
{
M[i]=e%10;
e/=10;
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 11:08:47
misterkuk
Суть программы- автомобильный термометр на 4 канала. Датчики температуры ds18b20. проц atmega8. при первм запуске с нажатой кнопкой программа входит в режим записи в еепром индивидуальных данных датчиков. после сохранения данных схема запускается с отжатой кнопкой, данные считываются из еепром в массив и далее программа работает с массивом. Всё рааботает. Но на дисплее прыгают значения показаний датчиков. Это уже не первый проэкт с такой проблемой. Допустим на экране высвечивается 25.0 градусов через время, а оно разное всегда, появляется -9999.0 потом при следующем круге программы появляется 25.09.0 тоесть нормально высвителось, но последние 9.0 остались.
было 2 5 . 0
стало - 9 9 9 9 . 0
стало 2 5 . 0
9 . 0
Я сначала думал что лишние цифры остаются в буфере массива. Попробывал чистить его перед записью- не помогло. Выходит эти цифры остаются в дисплее. Потом думал что не правильно считывается температура с датчика. Сделал проверку. Считываю температуру в переменную. Проверяю лежат ли считанные данные в пределах и потом отправляю переменную в sprintf. ошибка не пропала. Это значит что температура считывается без ошибок проходит проверку, уходит в sprintf и тут этот глюк и зараждается. А именно в строчке sprintf( LcdBuff,"motor %.1f", ds18b20_temperature( &RomCode[1][0] ) );
Подскажите, в чемм пожет быть причина? Фото прелагаются. Код программы в спойлере. Да программа корявенькая, но работает. только показания всё портят.
Спойлер
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
#include <io.h>
#include <stdio.h>
#include <eeprom.h>
#include <1wire.h>
#include <ds18b20.h>
#include <alcd.h>
#define MAX_DS1820 4
#asm
.equ __w1_port=0x12
.equ __w1_bit=1
#endasm
unsigned char nastroyka=0;
unsigned char RomCode[4][9];
int i;
int j;
int flag=7000;
unsigned char EEPROM_ADRESS_MASS=0x10;
unsigned char dspor=0x00;
unsigned char LcdBuff[20];
unsigned char devices;
unsigned int adc_data;
float t;
// Declare your global variables here
// Voltage Reference: Int., cap. on AREF
#define ADC_VREF_TYPE ((1<<REFS1) | (1<<REFS0) | (0<<ADLAR))
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
// Read the AD conversion result
adc_data=ADCW;
// Place your code here
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
flag+=1;
}
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
TCCR0=(1<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<TOIE0);
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: Int., cap. on AREF
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
SFIOR=(0<<ACME);
// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
// 1 Wire Bus initialization
// 1 Wire Data port: PORTD
// 1 Wire Data bit: 1
// Note: 1 Wire port settings are specified in the
// Project|Configure|C Compiler|Libraries|1 Wire menu.
w1_init();
// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 4
// RD - PORTB Bit 3
// EN - PORTB Bit 2
// D4 - PORTB Bit 1
// D5 - PORTB Bit 0
// D6 - PORTD Bit 7
// D7 - PORTD Bit 6
// Characters/line: 8
// Global enable interrupts
if (PIND.5==0)
nastroyka=1;
w1_init();
lcd_init(20);
lcd_clear(); //очистить дисплей
if(nastroyka==0)
{
EEPROM_ADRESS_MASS=0x10;
for ( i = 0; i<4; i++)
{
for (j = 0; j < 9; j++)
{
RomCode[i][j] = eeprom_read_word(EEPROM_ADRESS_MASS);
EEPROM_ADRESS_MASS+=1;
}
}
}
ds18b20_init( &RomCode[0][0], -20, 125, DS18B20_9BIT_RES );
ds18b20_init( &RomCode[1][0], -20, 125, DS18B20_9BIT_RES );
ds18b20_init( &RomCode[2][0], -20, 125, DS18B20_9BIT_RES );
ds18b20_init( &RomCode[3][0], -20, 125, DS18B20_9BIT_RES );
#asm("sei")
while (1)
{
if(nastroyka==0 )
{
lcd_gotoxy(0,0);
sprintf( LcdBuff,"salon %.1f", ds18b20_temperature( &RomCode[0][0] ) );
delay_us(50);
lcd_puts(LcdBuff);
lcd_gotoxy(0,1);
sprintf( LcdBuff,"motor %.1f", ds18b20_temperature( &RomCode[1][0] ) );
delay_us(50);
lcd_puts(LcdBuff);
lcd_gotoxy(0,2);
sprintf( LcdBuff,"pechka %.1f", ds18b20_temperature( &RomCode[2][0] ) );
delay_us(50);
lcd_puts(LcdBuff);
lcd_gotoxy(0,3);
sprintf( LcdBuff,"ulitsa %.1f", t );
delay_us(50);
lcd_puts(LcdBuff);
}
if(nastroyka==1)
{
devices=w1_search( DS18B20_SEARCH_ROM_CMD, RomCode ); //поиск датчиков на линии 1-wire
lcd_gotoxy(0,0);
sprintf(LcdBuff,"DS18B20=%u",devices); //выводим информацию о кол-ве датчиков
lcd_puts(LcdBuff);
delay_ms(500);
delay_ms(500);
lcd_clear(); //очистить дисплей
}
dspor=eeprom_read_word(0x00);
if(dspor==255)
dspor=0;
if(dspor<=3)
{
for (j = 0; j < 9; j++)
{
eeprom_write_word(EEPROM_ADRESS_MASS,RomCode[0][j]);
EEPROM_ADRESS_MASS+=1;
}
#asm("cli")
dspor+=1;
eeprom_write_word(0x00,dspor);
#asm("sei")
lcd_gotoxy(0,0);
lcd_putsf("okey");
}
while (PIND.5==0)
{
}
}
}




Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 11:15:02
WiseLord
CRC при съёме показаний проверяется? Если данные приходят от датчика некорректные, нужно их просто игнорировать.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 11:21:35
ARV
во-первых, не понятно, у вас графический или символьный ЖКИ? ощущение, что символьный, и тогда причина такого нехорошего поведения очевидна: вы не очищаете строку символов дисплея до конца.
во-вторых, показания термометра 9999 и т.п. - это сигнализация об ошибке обмена с датчиком, и в этом случае выводить результат не нужно. у вас в коде анализа ошибочной ситуации нет, а должна быть.
чтобы решить первую проблему, достаточно при выводе строки всегда выводить одинаковое количество символов, равное количеству позиций в строке ЖКИ. например, если у вас в строке 16 знаков, то ввод должен быть таким:
Код: Выделить всё
#define LINE_LEN 16
void fix_str_output(char *s){
unsigned char len;
lcd_puts(s);
len = LINE_LEN - strlen(s);
for(;len; len--) lcd_putc(' ');
}
ну а борьбу со второй проблемой сделайте самостоятельно.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 11:25:54
AndTer
Как можно осуществить сброс МК программно?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 11:32:29
rusl32
misterkuk писал(а):Суть программы- автомобильный термометр на 4 канала.
А очистить в начале цикла LCD?
Добавлено after 2 minutes 19 seconds:
AndTer писал(а):Как можно осуществить сброс МК программно?
Асмовой командой безусловного перехода в нужное место.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 11:44:16
ARV
rusl32 писал(а):А очистить в начале цикла LCD?
категорически не советую - будет заметное мерцание дисплея.
AndTer писал(а):Как можно осуществить сброс МК программно?
многократно уже говорил и повторю: самый корректный способ программного сброса - это запретить прерывания, разрешить WDT и уйти в вечный цикл. примерно так:
Код: Выделить всё
cli(); // запрет прерываний
wdt_enable(); // разрешаем WDT
while(1); // ждем сброса
переход "на начало кода" не является полным эквивалентом аппаратного сброса, и может быть рекомендован лишь в некоторых случаях, в то время как предлагаемый мною вариант может быть рекомендован всегда.
для педантов поясняю: сброс по WDT отличается от сброса по внешнему сигналу на входе RESET только установкой определенных флагов в определенном регистре (если таковой предусмотрен архитектурой МК). такое поведение документировано и может быть учтено в программе. иных отличий по "источнику" сброса нет.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 12:28:24
misterkuk
ARV писал(а):во-первых, не понятно, у вас графический или символьный ЖКИ?
HD44780 2004
у вас в коде анализа ошибочной ситуации нет, а должна быть.
Я же написал что делал анализ на ошибку. Даже с анализом выводятся 9ки. Значит температура с датчика считывается нормально, проходит проверку,, но после строки
sprintf( LcdBuff,"motor %.1f", ds18b20_temperature( &RomCode[1][0] ) ); получаются девятки.
Код: Выделить всё
t=ds18b20_temperature( &RomCode[1][0] ); //Считываем и записываем в переменную
if((t>=(-20)) && (t<=125)) // Проверяем на адекватность считанные данные. Проверку проходит нормально.
{
sprintf( LcdBuff,"motor %.1f", t); // и вот тут в буфер уже помещаются деватки, переодически
lcd_gotoxy(0,3);
lcd_puts(LcdBuff);
}
Чтобы решить первую проблему, достаточно при выводе строки всегда выводить одинаковое количество символов
Первая проблема не проблема вообще. Если девятки не будут выскакивать, то ничего лишнего не будет вылазить. Я слева хочу выводить температуру, а с права напряжение и еще чтонибуть.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс янв 29, 2017 12:38:47
ARV
misterkuk писал(а):Первая проблема не проблема вообще. Если девятки не будут выскакивать, то ничего лишнего не будет вылазить.
ошибаетесь.
у вас такой код для вывода (кстати, почему не в цикле?)
Код: Выделить всё
lcd_gotoxy(0,2);
sprintf( LcdBuff,"pechka %.1f", ds18b20_temperature( &RomCode[2][0] ) );
delay_us(50);
lcd_puts(LcdBuff);
в этом коде если температура была 10.5 градусов, а потом стала 9.5, вы увидите 9.55 ровно по той же причине, что и "хвост" от девяток. то, что вы еще этого не увидели - это временно. а правильные подходы дают всегда правильный результат. ваш код можно улучшить и иначе, чем советовал я, используя возможности форматированного вывода
Код: Выделить всё
sprintf( LcdBuff,"pechka %6.1f", ds18b20_temperature( &RomCode[2][0] ) );
хотя внешне это может выглядеть не всегда красиво - это уж от вашего эстетства зависит
misterkuk писал(а):Я же написал что делал анализ на ошибку. Даже с анализом выводятся 9ки.
ну что я могу сказать... если сказанное вами правда, то я делаю только один вывод: не правильно делали. потому что просто не может быть девяток, если бы вы сделали так:
Код: Выделить всё
float temp;
temp = ds18b20_temperature( &RomCode[2][0]);
if((temp > -60) && (temp < 150)) sprintf( LcdBuff,"pechka %.1f", temp);