CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Re: CodeVision AVR в вопросах и ответах

Сообщение DataLife »

Аlex, да, это регистр SPI.
Дело в том, что цифровой потенциометр (как оказывается) нуждается в отправке байта команды (что мол сейчас будем мы что-то делать, будь мол готов), а потом уже следом и сами данные.
Я сначала и сделал, как вы написали. А потом полистал даташит (стр. 18)... Оказывается шаманить нужно ...
Разве что такое шаманство произвести не с регистром, а с переменной. А потом её отправлять в SPI...

Но мой вопрос всё-равно актуален: как красиво написать?
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

Сделайте, для начала, отрпавку одного байта. Выведите код в отдельную функцию. Потом посылайте в эту функцию свои байты по-очереди.
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

C AVR'ами не знаком, но вот что нарыл из источников :

Код: Выделить всё

void SPI_MasterInit()
{
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);//настраиваем на выход
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);//вкл SPI, ведущий, частота fck/16
}

void SPI_MasterTransmit(char cData)
{
SPDR = cData;//начинаем передачу
while(!(SPSR & (1<<SPIF)));//ждем пока передача завершится
}
Вот теперь останется только вызывать функцию SPI_MasterTransmit и передавать ей байты. Что то типа :

Код: Выделить всё

SPI_MasterTransmit(0x11);
SPI_MasterTransmit(r_spi);
Что касается CV, пишут, что в нём можно сгенерировать код для работы с SPI. Попробуйте.
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Re: CodeVision AVR в вопросах и ответах

Сообщение DataLife »

Аlex, может я ошибаюсь, но на графике в даташите нарисовано, но байты должны идти один за одним... Разве можно отправить сначала один байт (команду), следом второй (данные) но спустя "некое" время?

Изображение

Если посылать их (байты) один за одним, то будут ли они "поняты" правильно получаталем?

ПС. ведь часики тикают пока Мк перескочит от строчки к строчке... А отправить одним пакетом более правильно, наверное.
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

16 бит послать не получится, передатчик всего 8-ми битный. В любом случае, байты придётся посылать по-очереди.
А микрухе, по-барабану. Хоть час пройдёт между байтами. Ибо SPI - синхронный интерфейс и тактируется от SCK.
Я Вам больше скажу, Вы даже можете биты посылать хоть раз в час. SPI интерфейс ограничивается максимальной частотой слейва. По минимальной частоте нет ограничений. А уж тем более не ограничен временем между байтами.
Реклама
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Re: CodeVision AVR в вопросах и ответах

Сообщение DataLife »

А, вот оно что.
Что же, большое спасибо за разъяснения! Буду пробовать!
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Реклама
Аватара пользователя
alex-wolf
Открыл глаза
Сообщения: 63
Зарегистрирован: Сб мар 09, 2013 21:46:01
Откуда: Уфа
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение alex-wolf »

проигнорировали
http://radiokot.ru/forum/viewtopic.php? ... 1#p2680941
, жаль

вопрос по легче
каую фукцию применить, для подмены обозначения десятичной точки на запятую
например
http://www.mikrocontroller.net/attachme ... Sensor.jpg
Последний раз редактировалось alex-wolf Вс мар 20, 2016 08:38:27, всего редактировалось 1 раз.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: CodeVision AVR в вопросах и ответах

Сообщение oleg110592 »

так можно попробовать:

Код: Выделить всё

    char str[100];
    float adc_read = 678.0123;
    int d1, d2;
    float f2;
    
    d1 = (int)adc_read; // Get the integer part (678).
    f2 = adc_read - d1; // Get fractional part (678.0123 - 678 = 0.0123).
    d2 = (int)(f2 * 10000); // Turn into integer (123).
    // Print as parts, note that you need 0-padding for fractional bit.
    // Since d1 is 678 and d2 is 123, you get "678.0123".
    sprintf (str, "adc_read = %d,%04d\n", d1, d2);
проверил на GCC для PC - работает:
Изображение
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: CodeVision AVR в вопросах и ответах

Сообщение COKPOWEHEU »

Код: Выделить всё

char *ch = strchr(input_string, ',');
if(ch) *ch = '.';
Или даже так

Код: Выделить всё

lcd_goto(18, y); lcd_putchar('.');
Если я правильно посчитал, десятичный разделитель расположен в 18 столбце. Само собой, вместо lcd_goto() и lcd_putchar() вставите свои функции для работы с дисплеем.
Аватара пользователя
alex-wolf
Открыл глаза
Сообщения: 63
Зарегистрирован: Сб мар 09, 2013 21:46:01
Откуда: Уфа
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение alex-wolf »

а еще варианты,
и вариант для передачи по асинхронному приемо-передатчику
Аватара пользователя
alex-wolf
Открыл глаза
Сообщения: 63
Зарегистрирован: Сб мар 09, 2013 21:46:01
Откуда: Уфа
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение alex-wolf »

COKPOWEHEU писал(а):

Код: Выделить всё

char *ch = strchr(input_string, ',');
if(ch) *ch = '.';
Или даже так

Код: Выделить всё

lcd_goto(18, y); lcd_putchar('.');
Если я правильно посчитал, десятичный разделитель расположен в 18 столбце. Само собой, вместо lcd_goto() и lcd_putchar() вставите свои функции для работы с дисплеем.
вот конкретный пример
lcd_gotoxy(0,0); w1_search(0xf0,ds18b20_rom_codes);
sprintf(lcd_buffer,"%2d:%02d:%02d %+5.1fC\n%2d/%02d/20%02d %s",hour,minut,sec,ds18b20_temperature(&ds18b20_rom_codes[ii][0]),date,month,year,(str_day[myday]),);
lcd_puts(lcd_buffer);


если оформить строку так

rtc_get_date_time(&sec,&minut,&hour,&day,&date,&month,&year);
myday=ds1307_read(3); // день недели

delay_ms(200);
lcd_gotoxy(0,0); w1_search(0xf0,ds18b20_rom_codes);
sprintf(lcd_buffer,"%2d:%02d:%02d %+5.1fC\n%2d/%02d/20%02d %s",hour,minut,sec,ds18b20_temperature(&ds18b20_rom_codes[ii][0]),date,month,year,(str_day[myday]),);

lcd_puts(lcd_buffer);

то кроме даты больше нечего не выводится(буфер затирается после lcd_gotoxy(0,14);; lcd_putchar(',');)
нужно по другому оформить синтаксис
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: CodeVision AVR в вопросах и ответах

Сообщение COKPOWEHEU »

Либо функции работы с дисплеем написаны криво, либо после описанного вами фрагмента идет еще какая-то работ с дисплеем.
Но зачем это извращение, если у вас в наличии буфер, в котором можно поменять символ. lcd_buffer[14]=','; Ну, точное положение в строке подберете.
Аватара пользователя
alex-wolf
Открыл глаза
Сообщения: 63
Зарегистрирован: Сб мар 09, 2013 21:46:01
Откуда: Уфа
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение alex-wolf »

COKPOWEHEU писал(а):Либо функции работы с дисплеем написаны криво, либо после описанного вами фрагмента идет еще какая-то работ с дисплеем.
Но зачем это извращение, если у вас в наличии буфер, в котором можно поменять символ. lcd_buffer[14]=','; Ну, точное положение в строке подберете.
благодарю, работает

sprintf(lcd_buffer,"%2d:%02d:%02d %+5.1fC\n%2d/%02d/20%02d %s",hour,minut,sec,ds18b20_temperature(&ds18b20_rom_codes[ii][0]),date,month,year,(str_day[myday]),);
lcd_buffer[13]=',';
lcd_puts(lcd_buffer);

:)

жаль, что в самом компеляторе нельзя указать, что использовать
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: CodeVision AVR в вопросах и ответах

Сообщение COKPOWEHEU »

Вроде можно, если использовать локали, но я с этим толком не разбирался.
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: CodeVision AVR в вопросах и ответах

Сообщение L.O.D »

alex-wolf писал(а):жаль, что в самом компеляторе нельзя указать, что использовать
Самописная функция в десяток строк длиной будет еще и в несколько раз компактнее printf'а. Что мешает?
COKPOWEHEU писал(а):Вроде можно, если использовать локали, ...
А у CV есть локали?!
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: CodeVision AVR в вопросах и ответах

Сообщение COKPOWEHEU »

Понятия не имею, но они упоминаются в книжке по Си, не отдающей предпочтение какому-то конкретному компилятору. Другой вопрос, будет ли это выгоднее, чем ручная замена точки.
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: CodeVision AVR в вопросах и ответах

Сообщение L.O.D »

COKPOWEHEU писал(а):они упоминаются в книжке по Си, не отдающей предпочтение какому-то конкретному компилятору
Книжку назовите, плиз. Насколько мне известно, локали не только не являются частью стандарта Си, но и не могут в него входить. Локали пока никак не стандартизированы и потому отличаются даже не только в разных ОС, но и в разных версиях одной ОС. Потому ожидать, что они есть в таком анекдоте, как CV, не приходится. Было бы полезно разобраться в этом вопросе, безотносительно вопроса ТС.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: CodeVision AVR в вопросах и ответах

Сообщение COKPOWEHEU »

Вряд ли смогу найти именно то где нашел, но, надеюсь, это сойдет. Локили это не локализация, а разделители десятичных чисел, нулей в многозначных числах, денежные величины и тому подобное. Кстати, я ошибся, это было в описании gnu c. Впрочем, с ним в той или иной степени совместимы и остальные диалекты. Заголовочный файл <locale.h>. На счет поддержки в cvavr тоже любопытно, если узнаете скажите.
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: CodeVision AVR в вопросах и ответах

Сообщение L.O.D »

COKPOWEHEU писал(а):Локили это не локализация, а разделители десятичных ...
Так бы и писали - locale.h. Но в CV его нет ("уж сколько раз твердили миру ..." © :)))), как минимум, до в.2.05.3, в котором присутствует хардкор - "*str++ ='.';".
COKPOWEHEU писал(а):На счет поддержки в cvavr тоже любопытно, если узнаете скажите.
На чей счет? Ах, да... Это исключено - на всякие "yet another programming language" нет ни времени, ни ... 'нигилизма'. :)))
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Владимир29
Родился
Сообщения: 4
Зарегистрирован: Пн мар 28, 2016 17:31:56

Re: CodeVision AVR в вопросах и ответах

Сообщение Владимир29 »

Мужики, помогите пожалуйста разобраться с термометром ничего в голову уже не лезет. Буду благодарен за помощь!

#include <mega8.h>
#include <delay.h>
#asm
.equ __w1_port=0x18 ;PORTB
.equ __w1_bit=2
#endasm
#include <1wire.h>
#include <ds18b20.h>

int temper;


int number = 0;
int number1 = 0;
int number2 = 0;
int number3 = 0;
int i=0;

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
PORTB.0=0;
PORTB.1=0;
PORTB.3=0;
PORTD.7=0;

if(i==0)
{
number=number1;
PORTB.1=1;
i++;
}
else if(i==1)
{
number=number2;
PORTD.7=1;
PORTB.0=1;
i++;

}
else if(i==2)
{
number=number3;
PORTB.3=1;
i=0;
}



//////////////Общий Анод///////////////////
switch(number)
{
case 0:{PORTD=0xC0; break;}
case 1:{PORTD=0xF9; break;}
case 2:{PORTD=0xA4; break;}
case 3:{PORTD=0xB0; break;}
case 4:{PORTD=0x99; break;}
case 5:{PORTD=0x92; break;}
case 6:{PORTD=0x82; break;}
case 7:{PORTD=0xF8; break;}
case 8:{PORTD=0x80; break;}
case 9:{PORTD=0x90; break;}

}
///////////////// END//////////////////////
if(i==2)PORTD.7=0;
}

void main(void)
{



PORTB=0x00;
DDRB=0b00001011;

PORTD=0x00;
DDRD=0b11111111;

PORTC=0x00;
DDRC=0x00;


TCCR1A=0x00;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x10;
OCR1AL=0x46;


TIMSK=0x10;
w1_init();

#asm("sei")

while (1)
{

temper=ds18b20_temperature(0);
if (temper>1000)
{
temper=4096.0-temper;
temper=-temper;
}
number1= (temper/100)%10;
number2= (temper/10)%10;
number3= temper%10;


};
}
Ответить

Вернуться в «AVR»