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

Обсуждаем контроллеры компании Atmel.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

К моменту выполнения инструкции SLEEP MCUCR=0, значит о сне можно забыть.
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

дамы и господа, возник вопрос:
есть дисплей nokia 5110, приехал, распаял, подключил.
схема такая:
CLK B0
DIN В1
DC B2
RST B3
CE B4

библиотеку взял от сюда: тут
почему при выводе изображений у меня во второй строке появляется мусор?
СпойлерИзображение


вот сам проект:
my program 2.rar
проект
(282 КБ) 189 скачиваний


а вот кусок кода из самой библиотеки по выводу изображения:

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

void lcd_image( flash unsigned char img[])
{
   char x,y;
   for(y=1;y < 7;y++)
   {
      lcd_gotoxy(0,y+1);
      for(x=0;x < 84;x++)
      lcd_send(img[y*84+x], LCD_DATA);
   }

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

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

Сообщение DataLife »

uk8amk, да, вы правы. Но проблема где-то глубже, ибо это я уже заметил какое-то время назад и попробовал исправить. Что только не перепробовал...
Сейчас вот так и всё одно не спит...
Спойлерif (SLEEP_BUTTON == 0)
{
delay_ms(100);
if (SLEEP_BUTTON == 0)
{
lcd_clear();
lcd_gotoxy(4,0);
lcd_putsf("Power OFF");

/**Выключаем прерывания по INT1, включаем по кнопке INT0**/

GICR = 0x40; // INT0 on
MCUCR = 0xA2; //0b10100010 Sleep ON, Power-Down, Falling Edge INT0

#asm("sei")
#asm("sleep")

/** ДЕЛАЕМ СБРОС МК СТОРОЖЕВОЙ СОБАКОЙ **/

WDTCR=0x1C; // включаем сторожа
while (1); // заставляем МК зависнуть
}
}

Кстати, заметил, что регистр MCUCR в ATmega8A и ATmega8(L) имеют различные биты ...
А-н-нет... опечатка в Даташите... Страницы 74 и 56 ... :dont_know:

После нескольких часов пласок с бубном проблему решил.
Вот так вот вышло:
Спойлерif (SLEEP_BUTTON == 0)
{
delay_ms(100);
if (SLEEP_BUTTON == 0)
{
delay_ms(500);
lcd_clear();
lcd_gotoxy(4,0);
lcd_putsf("Power OFF");

/**Выключаем прерывания по INT1, включаем по кнопке INT0**/

GICR = 0x40; // INT0 on
MCUCR = 0xA0; //0b10100000 Sleep ON, Power-Down, Low lavel INT0

#asm("sei")
#asm("sleep")

/** ДЕЛАЕМ СБРОС МК СТОРОЖЕВОЙ СОБАКОЙ **/

WDTCR=0x1C; // включаем сторожа
while (1); // заставляем МК зависнуть
}
}

Согласился МК просыпаться и засыпать только при MCUCR = 0xA0;
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

отвечу сам себе, разобрался))

сначала грешил на кусок кода инициализации, долго и упорно мучил эти пару на пару строчек, но в итоге дошло, что дисплей то выводит то что нужно, значит инициализируется правильно.
в итоге вернулся к коду вывода графики, и вот что надо было изменить:

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

void lcd_image( flash unsigned char img[])
{
   char x,y;
   for(y=0;y < 6;y++)
   
   {
      lcd_gotoxy(0,y);
      for(x=0;x < 84;x++)
      lcd_send(img[y*84+x], LCD_DATA);
   }
}

всего лишь сдвинуть по ординате вверх.

вот результат:
Спойлер
20160417_030549.jpg
яхууу
(49.54 КБ) 114 скачиваний


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

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

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

Добрый вечер

RS-485

после продолжительных поисков - на предмет (RS-485)
нечего вразумительного
это и...
viewtopic.php?f=61&t=119699
http://easyelectronics.ru/avr-uchebnyj- ... niyax.html
и это, кудаж без этого
http://www.avrfreaks.net/forum/codevision-rs485
особенно
http://www.avrfreaks.net/comment/801167#comment-801167

TXC Устанавливается в "1", когда передаваемый байт полностью "выдвинут" из UDR, включая стоп-бит. Если разрешено прерывание по пустому передатчику (установлен TXCIE в UCR), будет вызвано прерывание с вектором 14 ($00D) Сбрасывается при обработке прерывания или записью лог. "1" в этот бит
которая будет переводить на прием или передачу max485(2и3 выводы соедены вместе, как раз избовляемся от локального эха)

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

void rs485 (void) 
{DDRD=0x20;
if (TXC!=1) {PORTD.5=1;} else  {PORTD.5=0;};
};
// USART Transmitter buffer
#define TX_BUFFER_SIZE 8
char tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif


// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{   
if (tx_counter)
   {
   --tx_counter;
   UDR=tx_buffer[tx_rd_index];
   if (++tx_rd_index == TX_BUFFER_SIZE){ tx_rd_index=0; }
         
   };

}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+ 



void putchar(char c)
{
 rs485();

while (tx_counter == TX_BUFFER_SIZE);

#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
   {
   tx_buffer[tx_wr_index]=c;
   if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
   ++tx_counter;
   }
else
 UDR=c;
//    UCSRA |= TXC;    // manually clear TXC flag
//    while ( ( UCSRA & TXC ) == 0 );    // wait for all characters to be transmitted.

#asm("sei")
}; 
#pragma used-
#endif

вот и собственно вопрос - как/куда размещать в ихней коде_под-программе или нужно дописывать/допиливать еще одну под программу которая будт проверять
этот статус- TXC

интересный вариант
https://sourceforge.net/projects/freemo ... ios/files/

https://sourceforge.net/projects/freemo ... p/download

https://sourceforge.net/projects/freemo ... p/download
freemodbus-v0.4.zip/port/portserial.c


сразу предупреждаю
такой вариант
http://myrobot.ru/forum/topic.php?forum ... 1317282895
чтобы каждый раз перед отправкой не писать
ставить задежки, тоже не предлогать
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

господа, у кого нибудь есть библиотека ssd1306 под наш cvavr, но под экран 96х16, все что нахожу разрешением выше, и по каким то причинам вообще не работает...

добавлено:
и опять отвечаю сам себе - все получилось! =))
надо было переписать инициализацию согласно datasheet, я долго тупил, где двойные значения, но потом понял...

вот только вопросы все равно остались:
#define SSD1306_DEFAULT_SPACE - вот это что такое и на что влияет?

библиотека cvavr for ssd1306 96x16
Спойлер

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

#include <delay.h>

void LCD_init(void); // начальная инициализация дисплея
void LCD_Commmand(unsigned char ControByte, unsigned char DataByte); // команды дисплею или данные
void LCD_Goto(unsigned char x, unsigned char y); // установить координаты
void LCD_Goto2X(unsigned char x, unsigned char y); // установить координаты умноженые на 2
void LCD_Clear(void); // очистка всего дисплея
void LCD_Contrast(char set_contrast); // настройка контраста от 0 до 255
void LCD_Char(unsigned int c); // вывод символа
void LCD_Printf(unsigned char* buf, unsigned char size); // печатает строку с размерами: 0-нормальный, 1-большой
void LCD_DrawImage(unsigned char num_image); // выводит картинку из флеш
void LCD_Bat(unsigned char y,unsigned char x, unsigned char z); // рисует батарейку по координатам z - от 0 до 10 делений
void LCD_Mode(char set_mode); // 1 - inverted / 0 - normal
void LCD_Sleep(char set); // 1 - on sleep / 0 - off sleep

unsigned char LCD_X,LCD_Y;

#define SSD1306_I2C_ADDRESS                0x78
// size
#define SSD1306_LCDWIDTH                      96
#define SSD1306_LCDHEIGHT                     16
#define SSD1306_DEFAULT_SPACE                 0
// commands
#define SSD1306_SETCONTRAST                  0x81
#define SSD1306_DISPLAYALLON_RESUME          0xA4
#define SSD1306_DISPLAYALLON                 0xA5
#define SSD1306_NORMALDISPLAY                0xA6
#define SSD1306_INVERTDISPLAY                0xA7
#define SSD1306_DISPLAYOFF                   0xAE
#define SSD1306_DISPLAYON                    0xAF
#define SSD1306_SETDISPLAYOFFSET             0xD3
#define SSD1306_SETCOMPINS                   0xDA
#define SSD1306_SETVCOMDETECT                0xDB
#define SSD1306_SETDISPLAYCLOCKDIV           0xD5
#define SSD1306_SETPRECHARGE                 0xD9
#define SSD1306_SETMULTIPLEX                 0xA8
#define SSD1306_SETLOWCOLUMN                 0x00
#define SSD1306_SETHIGHCOLUMN                0x10
#define SSD1306_SETSTARTLINE                 0x40
#define SSD1306_MEMORYMODE                   0x20
#define SSD1306_COLUMNADDR                   0x21
#define SSD1306_PAGEADDR                     0x22
#define SSD1306_COMSCANINC                   0xC0
#define SSD1306_COMSCANDEC                   0xC8
#define SSD1306_SEGREMAP                     0xA1
#define SSD1306_CHARGEPUMP                   0x8D
#define SSD1306_SETLOWPWR                    0xD8
#define SSD1306_EXTERNALVCC                  0x1
#define SSD1306_SWITCHCAPVCC                 0x2
// scrolling #defines
#define SSD1306_ACTIVATE_SCROLL              0x2F
#define SSD1306_DEACTIVATE_SCROLL            0x2E
#define SSD1306_SET_VERTICAL_SCROLL_AREA     0xA3
#define SSD1306_RIGHT_HORIZONTAL_SCROLL      0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL       0x27
#define SSD1306_VERT_AND_RIGHT_HORIZ_SCROLL  0x29
#define SSD1306_VERT_AND_LEFT_HORIZ_SCROLL   0x2A

#define COMAND                               0x00
#define DATA                                 0x40

flash unsigned char image0[192] =
{
//пиши сюда картинку//
};


flash unsigned char LCD_Buffer[0x0500] =
{
0x00, 0x00, 0x00, 0x00, 0x00,// 00
0x00, 0x00, 0x5F, 0x00, 0x00,// 01
0x00, 0x07, 0x00, 0x07, 0x00,// 02
0x14, 0x7F, 0x14, 0x7F, 0x14,// 03
0x24, 0x2A, 0x7F, 0x2A, 0x12,// 04
0x23, 0x13, 0x08, 0x64, 0x62,// 05
0x36, 0x49, 0x55, 0x22, 0x50,// 06
0x00, 0x05, 0x03, 0x00, 0x00,// 07
0x00, 0x1C, 0x22, 0x41, 0x00,// 08
0x00, 0x41, 0x22, 0x1C, 0x00,// 09
0x14, 0x08, 0x3E, 0x08, 0x14,// 0A
0x08, 0x08, 0x3E, 0x08, 0x08,// 0B
0x00, 0x50, 0x30, 0x00, 0x00,// 0C
0x08, 0x08, 0x08, 0x08, 0x08,// 0D
0x00, 0x60, 0x60, 0x00, 0x00,// 0E
0x20, 0x10, 0x08, 0x04, 0x02,// 0F
0x00, 0x00, 0x00, 0x00, 0x00,// 10
0x00, 0x00, 0x5F, 0x00, 0x00,// 11
0x00, 0x07, 0x00, 0x07, 0x00,// 12
0x14, 0x7F, 0x14, 0x7F, 0x14,// 13
0x24, 0x2A, 0x7F, 0x2A, 0x12,// 14
0x23, 0x13, 0x08, 0x64, 0x62,// 15
0x36, 0x49, 0x55, 0x22, 0x50,// 16
0x00, 0x05, 0x03, 0x00, 0x00,// 17
0x00, 0x1C, 0x22, 0x41, 0x00,// 18
0x00, 0x41, 0x22, 0x1C, 0x00,// 19
0x14, 0x08, 0x3E, 0x08, 0x14,// 1A
0x08, 0x08, 0x3E, 0x08, 0x08,// 1B
0x00, 0x50, 0x30, 0x00, 0x00,// 1C
0x08, 0x08, 0x08, 0x08, 0x08,// 1D
0x00, 0x60, 0x60, 0x00, 0x00,// 1E
0x20, 0x10, 0x08, 0x04, 0x02,// 1F
0x00, 0x00, 0x00, 0x00, 0x00,// 20 space
0x00, 0x00, 0x5F, 0x00, 0x00,// 21 !
0x00, 0x07, 0x00, 0x07, 0x00,// 22 "
0x14, 0x7F, 0x14, 0x7F, 0x14,// 23 #
0x24, 0x2A, 0x7F, 0x2A, 0x12,// 24 $
0x23, 0x13, 0x08, 0x64, 0x62,// 25 %
0x36, 0x49, 0x55, 0x22, 0x50,// 26 &
0x00, 0x05, 0x03, 0x00, 0x00,// 27 '
0x00, 0x1C, 0x22, 0x41, 0x00,// 28 (
0x00, 0x41, 0x22, 0x1C, 0x00,// 29 )
0x14, 0x08, 0x3E, 0x08, 0x14,// 2a *
0x08, 0x08, 0x3E, 0x08, 0x08,// 2b +
0x00, 0x50, 0x30, 0x00, 0x00,// 2c ,
0x08, 0x08, 0x08, 0x08, 0x08,// 2d -
0x00, 0x60, 0x60, 0x00, 0x00,// 2e .
0x20, 0x10, 0x08, 0x04, 0x02,// 2f /
0x3E, 0x51, 0x49, 0x45, 0x3E,// 30 0
0x00, 0x42, 0x7F, 0x40, 0x00,// 31 1
0x42, 0x61, 0x51, 0x49, 0x46,// 32 2
0x21, 0x41, 0x45, 0x4B, 0x31,// 33 3
0x18, 0x14, 0x12, 0x7F, 0x10,// 34 4
0x27, 0x45, 0x45, 0x45, 0x39,// 35 5
0x3C, 0x4A, 0x49, 0x49, 0x30,// 36 6
0x01, 0x71, 0x09, 0x05, 0x03,// 37 7
0x36, 0x49, 0x49, 0x49, 0x36,// 38 8
0x06, 0x49, 0x49, 0x29, 0x1E,// 39 9
0x00, 0x36, 0x36, 0x00, 0x00,// 3a :
0x00, 0x56, 0x36, 0x00, 0x00,// 3b ;
0x08, 0x14, 0x22, 0x41, 0x00,// 3c <
0x14, 0x14, 0x14, 0x14, 0x14,// 3d =
0x00, 0x41, 0x22, 0x14, 0x08,// 3e >
0x02, 0x01, 0x51, 0x09, 0x06,// 3f ?
0x32, 0x49, 0x79, 0x41, 0x3E,// 40 @
0x7E, 0x11, 0x11, 0x11, 0x7E,// 41 A
0x7F, 0x49, 0x49, 0x49, 0x36,// 42 B
0x3E, 0x41, 0x41, 0x41, 0x22,// 43 C
0x7F, 0x41, 0x41, 0x22, 0x1C,// 44 D
0x7F, 0x49, 0x49, 0x49, 0x41,// 45 E
0x7F, 0x09, 0x09, 0x09, 0x01,// 46 F
0x3E, 0x41, 0x49, 0x49, 0x7A,// 47 G
0x7F, 0x08, 0x08, 0x08, 0x7F,// 48 H
0x00, 0x41, 0x7F, 0x41, 0x00,// 49 I
0x20, 0x40, 0x41, 0x3F, 0x01,// 4a J
0x7F, 0x08, 0x14, 0x22, 0x41,// 4b K
0x7F, 0x40, 0x40, 0x40, 0x40,// 4c L
0x7F, 0x02, 0x0C, 0x02, 0x7F,// 4d M
0x7F, 0x04, 0x08, 0x10, 0x7F,// 4e N
0x3E, 0x41, 0x41, 0x41, 0x3E,// 4f O
0x7F, 0x09, 0x09, 0x09, 0x06,// 50 P
0x3E, 0x41, 0x51, 0x21, 0x5E,// 51 Q
0x7F, 0x09, 0x19, 0x29, 0x46,// 52 R
0x46, 0x49, 0x49, 0x49, 0x31,// 53 S
0x01, 0x01, 0x7F, 0x01, 0x01,// 54 T
0x3F, 0x40, 0x40, 0x40, 0x3F,// 55 U
0x1F, 0x20, 0x40, 0x20, 0x1F,// 56 V
0x3F, 0x40, 0x38, 0x40, 0x3F,// 57 W
0x63, 0x14, 0x08, 0x14, 0x63,// 58 X
0x07, 0x08, 0x70, 0x08, 0x07,// 59 Y
0x61, 0x51, 0x49, 0x45, 0x43,// 5a Z
0x00, 0x7F, 0x41, 0x41, 0x00,// 5b [
0x02, 0x04, 0x08, 0x10, 0x20,// 5c Yen Currency Sign
0x00, 0x41, 0x41, 0x7F, 0x00,// 5d ]
0x04, 0x02, 0x01, 0x02, 0x04,// 5e ^
0x40, 0x40, 0x40, 0x40, 0x40,// 5f _
0x00, 0x01, 0x02, 0x04, 0x00,// 60 `
0x20, 0x54, 0x54, 0x54, 0x78,// 61 a
0x7F, 0x48, 0x44, 0x44, 0x38,// 62 b
0x38, 0x44, 0x44, 0x44, 0x20,// 63 c
0x38, 0x44, 0x44, 0x48, 0x7F,// 64 d
0x38, 0x54, 0x54, 0x54, 0x18,// 65 e
0x08, 0x7E, 0x09, 0x01, 0x02,// 66 f
0x0C, 0x52, 0x52, 0x52, 0x3E,// 67 g
0x7F, 0x08, 0x04, 0x04, 0x78,// 68 h
0x00, 0x44, 0x7D, 0x40, 0x00,// 69 i
0x20, 0x40, 0x44, 0x3D, 0x00,// 6a j
0x7F, 0x10, 0x28, 0x44, 0x00,// 6b k
0x00, 0x41, 0x7F, 0x40, 0x00,// 6c l
0x7C, 0x04, 0x18, 0x04, 0x78,// 6d m
0x7C, 0x08, 0x04, 0x04, 0x78,// 6e n
0x38, 0x44, 0x44, 0x44, 0x38,// 6f o
0x7C, 0x14, 0x14, 0x14, 0x08,// 70 p
0x08, 0x14, 0x14, 0x18, 0x7C,// 71 q
0x7C, 0x08, 0x04, 0x04, 0x08,// 72 r
0x08, 0x54, 0x54, 0x54, 0x20,// 73 s
0x04, 0x3F, 0x44, 0x40, 0x20,// 74 t
0x3C, 0x40, 0x40, 0x20, 0x7C,// 75 u
0x1C, 0x20, 0x40, 0x20, 0x1C,// 76 v
0x3C, 0x40, 0x30, 0x40, 0x3C,// 77 w
0x44, 0x28, 0x10, 0x28, 0x44,// 78 x
0x0C, 0x50, 0x50, 0x50, 0x3C,// 79 y
0x44, 0x64, 0x54, 0x4C, 0x44,// 7a z
0x00, 0x08, 0x36, 0x41, 0x00,// 7b <
0x00, 0x00, 0x7F, 0x00, 0x00,// 7c |
0x00, 0x41, 0x36, 0x08, 0x00,// 7d >
0x10, 0x08, 0x08, 0x10, 0x08,// 7e Right Arrow ->
0x78, 0x46, 0x41, 0x46, 0x78,// 7f Left Arrow <-
0x00, 0x00, 0x00, 0x00, 0x00,// 80
0x00, 0x00, 0x5F, 0x00, 0x00,// 81
0x00, 0x07, 0x00, 0x07, 0x00,// 82
0x14, 0x7F, 0x14, 0x7F, 0x14,// 83
0x24, 0x2A, 0x7F, 0x2A, 0x12,// 84
0x23, 0x13, 0x08, 0x64, 0x62,// 85
0x36, 0x49, 0x55, 0x22, 0x50,// 86
0x00, 0x05, 0x03, 0x00, 0x00,// 87
0x00, 0x1C, 0x22, 0x41, 0x00,// 88
0x00, 0x41, 0x22, 0x1C, 0x00,// 89
0x14, 0x08, 0x3E, 0x08, 0x14,// 8A
0x08, 0x08, 0x3E, 0x08, 0x08,// 8B
0x00, 0x50, 0x30, 0x00, 0x00,// 8C
0x08, 0x08, 0x08, 0x08, 0x08,// 8D
0x00, 0x60, 0x60, 0x00, 0x00,// 8E
0x20, 0x10, 0x08, 0x04, 0x02,// 8F
0x00, 0x00, 0x00, 0x00, 0x00,// 90
0x00, 0x00, 0x5F, 0x00, 0x00,// 91
0x00, 0x07, 0x00, 0x07, 0x00,// 92
0x14, 0x7F, 0x14, 0x7F, 0x14,// 93
0x24, 0x2A, 0x7F, 0x2A, 0x12,// 94
0x23, 0x13, 0x08, 0x64, 0x62,// 95
0x36, 0x49, 0x55, 0x22, 0x50,// 96
0x00, 0x05, 0x03, 0x00, 0x00,// 97
0x00, 0x1C, 0x22, 0x41, 0x00,// 98
0x00, 0x41, 0x22, 0x1C, 0x00,// 99
0x14, 0x08, 0x3E, 0x08, 0x14,// 9A
0x08, 0x08, 0x3E, 0x08, 0x08,// 9B
0x00, 0x50, 0x30, 0x00, 0x00,// 9C
0x08, 0x08, 0x08, 0x08, 0x08,// 9D
0x00, 0x60, 0x60, 0x00, 0x00,// 9E
0x20, 0x10, 0x08, 0x04, 0x02,// 9F
0x00, 0x00, 0x00, 0x00, 0x00,// A0
0x00, 0x00, 0x5F, 0x00, 0x00,// A1
0x00, 0x07, 0x00, 0x07, 0x00,// A2
0x14, 0x7F, 0x14, 0x7F, 0x14,// A3
0x24, 0x2A, 0x7F, 0x2A, 0x12,// A4
0x23, 0x13, 0x08, 0x64, 0x62,// A5
0x36, 0x49, 0x55, 0x22, 0x50,// A6
0x00, 0x05, 0x03, 0x00, 0x00,// A7
0x00, 0x1C, 0x22, 0x41, 0x00,// A8
0x00, 0x41, 0x22, 0x1C, 0x00,// A9
0x14, 0x08, 0x3E, 0x08, 0x14,// AA
0x08, 0x08, 0x3E, 0x08, 0x08,// AB
0x00, 0x50, 0x30, 0x00, 0x00,// AC
0x08, 0x08, 0x08, 0x08, 0x08,// AD
0x00, 0x60, 0x60, 0x00, 0x00,// AE
0x20, 0x10, 0x08, 0x04, 0x02,// AF
//0x3E, 0x51, 0x49, 0x45, 0x3E,// B0
0x00, 0x06, 0x09, 0x09, 0x06,
0x00, 0x42, 0x7F, 0x40, 0x00,// B1
0x42, 0x61, 0x51, 0x49, 0x46,// B2
0x21, 0x41, 0x45, 0x4B, 0x31,// B3
0x18, 0x14, 0x12, 0x7F, 0x10,// B4
0x27, 0x45, 0x45, 0x45, 0x39,// B5
0x3C, 0x4A, 0x49, 0x49, 0x30,// B6
0x01, 0x71, 0x09, 0x05, 0x03,// B7
0x36, 0x49, 0x49, 0x49, 0x36,// B8
0x06, 0x49, 0x49, 0x29, 0x1E,// B9
0x00, 0x36, 0x36, 0x00, 0x00,// BA
0x00, 0x56, 0x36, 0x00, 0x00,// BB
0x08, 0x14, 0x22, 0x41, 0x00,// BC
0x14, 0x14, 0x14, 0x14, 0x14,// BD
0x00, 0x41, 0x22, 0x14, 0x08,// BE
0x02, 0x01, 0x51, 0x09, 0x06,// BF
0x7E, 0x11, 0x11, 0x11, 0x7E,// C0 А
0x7F, 0x49, 0x49, 0x49, 0x31,// C1 Б
0x7F, 0x49, 0x49, 0x49, 0x36,// C2 В
0x7F, 0x01, 0x01, 0x01, 0x03,// C3 Г
0x60, 0x3E, 0x21, 0x21, 0x7F,// C4 Д
0x7F, 0x49, 0x49, 0x49, 0x41,// C5 Е
0x77, 0x08, 0x7F, 0x08, 0x77,// C6 Ж
0x22, 0x41, 0x49, 0x49, 0x36,// C7 З
0x7F, 0x10, 0x08, 0x04, 0x7F,// C8 И
0x7F, 0x10, 0x09, 0x04, 0x7F,// C9 И
0x7F, 0x08, 0x14, 0x22, 0x41,// CA К
0x40, 0x3E, 0x01, 0x01, 0x7F,// CB Л
0x7F, 0x02, 0x0C, 0x02, 0x7F,// CC М
0x7F, 0x08, 0x08, 0x08, 0x7F,// CD Н
0x3E, 0x41, 0x41, 0x41, 0x3E,// CE О
0x7F, 0x01, 0x01, 0x01, 0x7F,// CF П
0x7F, 0x09, 0x09, 0x09, 0x06,// D0 Р
0x3E, 0x41, 0x41, 0x41, 0x22,// D1 С
0x01, 0x01, 0x7F, 0x01, 0x01,// D2 Т
0x27, 0x48, 0x48, 0x48, 0x3F,// D3 У
0x1E, 0x21, 0x7F, 0x21, 0x1E,// D4 Ф
0x63, 0x14, 0x08, 0x14, 0x63,// D5 Х
0x3F, 0x20, 0x20, 0x3F, 0x60,// D6 Ц
0x07, 0x08, 0x08, 0x08, 0x7F,// D7 Ч
0x7F, 0x40, 0x7F, 0x40, 0x7F,// D8 Ш
0x3F, 0x20, 0x3F, 0x20, 0x7F,// D9 Щ
0x01, 0x7F, 0x48, 0x48, 0x30,// DA Ъ
0x7F, 0x48, 0x30, 0x00, 0x7F,// DB Ы
0x00, 0x7F, 0x48, 0x48, 0x30,// DC Ь
0x22, 0x41, 0x49, 0x49, 0x3E,// DD Э
0x7F, 0x08, 0x3E, 0x41, 0x3E,// DE Ю
0x46, 0x29, 0x19, 0x09, 0x7F,// DF Я
0x20, 0x54, 0x54, 0x54, 0x78,// E0 а
0x3C, 0x4A, 0x4A, 0x4A, 0x30,// E1 б
0x7C, 0x54, 0x54, 0x28, 0x00,// E2 в
0x7C, 0x04, 0x04, 0x04, 0x04,// E3 г
0x60, 0x38, 0x24, 0x24, 0x7C,// E4 д
0x38, 0x54, 0x54, 0x54, 0x18,// E5 е
0x6C, 0x10, 0x7C, 0x10, 0x6C,// E6 ж
0x00, 0x44, 0x54, 0x54, 0x28,// E7 з
0x7C, 0x20, 0x10, 0x08, 0x7C,// E8 и
0x7C, 0x21, 0x12, 0x09, 0x7C,// E9 й
0x7C, 0x10, 0x28, 0x44, 0x00,// EA к
0x40, 0x38, 0x04, 0x04, 0x7C,// EB л
0x7C, 0x08, 0x10, 0x08, 0x7C,// EC м
0x7C, 0x10, 0x10, 0x10, 0x7C,// ED н
0x38, 0x44, 0x44, 0x44, 0x38,// EE о
0x7C, 0x04, 0x04, 0x04, 0x7C,// EF п
0x7C, 0x14, 0x14, 0x14, 0x08,// F0 р
0x38, 0x44, 0x44, 0x44, 0x00,// F1 с
0x04, 0x04, 0x7C, 0x04, 0x04,// F2 т
0x0C, 0x50, 0x50, 0x50, 0x3C,// F3 у
0x08, 0x14, 0x7C, 0x14, 0x08,// F4 ф
0x44, 0x28, 0x10, 0x28, 0x44,// F5 х
0x3C, 0x20, 0x20, 0x3C, 0x60,// F6 ц
0x0C, 0x10, 0x10, 0x10, 0x7C,// F7 ч
0x7C, 0x40, 0x7C, 0x40, 0x7C,// F8 ш
0x3C, 0x20, 0x3C, 0x20, 0x7C,// F9 щ
0x04, 0x7C, 0x50, 0x50, 0x20,// FA ъ
0x7C, 0x50, 0x20, 0x00, 0x7C,// FB ы
0x00, 0x7C, 0x50, 0x50, 0x20,// FC ь
0x28, 0x44, 0x54, 0x54, 0x38,// FD э
0x7C, 0x10, 0x38, 0x44, 0x38,// FE ю
0x48, 0x54, 0x34, 0x14, 0x7C // FF я
};

void LCD_init(void) // инициализируем согласно datasheet ssd1306
{
 LCD_Commmand(COMAND, SSD1306_DISPLAYOFF);
 LCD_Commmand(COMAND, SSD1306_SETDISPLAYCLOCKDIV);
 LCD_Commmand(COMAND, 0x80);
 LCD_Commmand(COMAND, SSD1306_SETMULTIPLEX);
 LCD_Commmand(COMAND, 0x0F);
 LCD_Commmand(COMAND, SSD1306_SETDISPLAYOFFSET);
 LCD_Commmand(COMAND, 0x00);
 LCD_Commmand(COMAND, SSD1306_SETSTARTLINE);
 LCD_Commmand(COMAND, SSD1306_CHARGEPUMP);
 LCD_Commmand(COMAND, 0x14);
 LCD_Commmand(COMAND, SSD1306_SETLOWPWR);
 LCD_Commmand(COMAND, 0x05);
 LCD_Commmand(COMAND, SSD1306_SEGREMAP);
 LCD_Commmand(COMAND, SSD1306_COMSCANDEC);
 LCD_Commmand(COMAND, SSD1306_SETCOMPINS);
 LCD_Commmand(COMAND, 0x02);
 LCD_Commmand(COMAND, SSD1306_SETCONTRAST);
 LCD_Commmand(COMAND, 0xAF);
 LCD_Commmand(COMAND, SSD1306_SETPRECHARGE);
 LCD_Commmand(COMAND, 0xF1);
 LCD_Commmand(COMAND, SSD1306_SETVCOMDETECT);
 LCD_Commmand(COMAND, 0x20);
 LCD_Commmand(COMAND, SSD1306_DISPLAYALLON_RESUME);
 LCD_Commmand(COMAND, SSD1306_NORMALDISPLAY);
 LCD_Clear();
 LCD_Commmand(COMAND, SSD1306_DISPLAYON);
}

void LCD_Contrast(char set_contrast)
{
  LCD_Commmand(COMAND, SSD1306_DISPLAYOFF);
  delay_ms(10);
  LCD_Commmand(COMAND, SSD1306_SETCONTRAST);
  LCD_Commmand(COMAND, set_contrast);
  LCD_Commmand(COMAND, SSD1306_DISPLAYON);
}

void LCD_Mode(char set_mode)
{
 if(set_mode==0){ LCD_Commmand(COMAND, SSD1306_NORMALDISPLAY); }
 if(set_mode==1){ LCD_Commmand(COMAND, SSD1306_INVERTDISPLAY); }
}

void LCD_Sleep(char set)
{
  if(set==0){LCD_Commmand(COMAND,SSD1306_DISPLAYOFF);}
  if(set==1){LCD_Commmand(COMAND,SSD1306_DISPLAYON);}
}

void LCD_Commmand(unsigned char ControByte, unsigned char DataByte)
{
  i2c_start();
  i2c_write(SSD1306_I2C_ADDRESS);
  i2c_write(ControByte);
  i2c_write(DataByte);
  i2c_stop();
}

void LCD_Goto(unsigned char x, unsigned char y)
{
    LCD_X = x;
    LCD_Y = y;

    // установка  и настройка
    LCD_Commmand(COMAND, 0xB0 + y); // установить адрес начала координат
    LCD_Commmand(COMAND, x & 0xf); // установить нижний адрес столбца
    LCD_Commmand(COMAND,0x10 | (x >> 4)); // установить верхний адрес столбца
}

void LCD_Goto2X(unsigned char x, unsigned char y)
{
    LCD_X = x;
    LCD_Y = y;

    // установка  и настройка
    LCD_Commmand(COMAND, 0xB0 + y); // установить адрес начала координат
    LCD_Commmand(COMAND, 2*x & 0xf); // установить нижний адрес столбца
    LCD_Commmand(COMAND,0x10 | (2*x >> 4)); // установить верхний адрес столбца
}

void LCD_Clear(void)
{
    unsigned short i;
    unsigned short x=0;
    unsigned short y=0;
    LCD_Goto(0,0);

    for (i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) // (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8)
    {
        LCD_Char(' ');
        x ++;
        if(x>SSD1306_LCDWIDTH)
        {
            x =0;
            y++;
            LCD_Goto(0,y);
        }
    }
    LCD_X =SSD1306_DEFAULT_SPACE;
    LCD_Y =0;
}

void LCD_Char(unsigned int c)
{
  unsigned char x = 0;
  i2c_start();
  i2c_write(SSD1306_I2C_ADDRESS);
  i2c_write(DATA); // data mode
  for (x=0; x<5; x++)
    {
     i2c_write(LCD_Buffer[c*5+x]);
     }
  i2c_write(0x00); // пробел в одну точку между символами
  i2c_stop(); // стоп передаче

    LCD_X += 8;
    if(LCD_X>SSD1306_LCDWIDTH)
    {
     LCD_X = SSD1306_DEFAULT_SPACE;
    }
}


void LCD_CharBig(unsigned int c)
{
  unsigned char x = 0;
  unsigned int m = 0;

  i2c_start();
  i2c_write(SSD1306_I2C_ADDRESS);
  i2c_write(DATA); // data mode
  for (x=0; x<5; x++)
    {
     m = LCD_Buffer[c*5+x];
     i2c_write(m);
     i2c_write(m);
     }
  i2c_write(0x00); // пробел в одну точку между символами
  i2c_stop(); // stop transmitting
    LCD_X += 11;
    if(LCD_X>SSD1306_LCDWIDTH)
    {
     LCD_X = SSD1306_DEFAULT_SPACE;
    }
}

void LCD_Printf(unsigned char* buf, unsigned char size) // выводим строку из буфера
{
 while (*buf!=0)
    {
       if(size==0)
       {
        if((LCD_X>SSD1306_LCDWIDTH)||(LCD_X<5)){LCD_X=SSD1306_DEFAULT_SPACE;}
        LCD_Char(*buf++);
        }
       if(size==1)
       {
        if((LCD_X>SSD1306_LCDWIDTH)||(LCD_X<5)){LCD_X=SSD1306_DEFAULT_SPACE;}
        LCD_CharBig(*buf++);
       }
    }
}

void LCD_DrawImage(unsigned char num_image)
{
    unsigned int i;
    unsigned char x=0;
    unsigned char y=0;
    LCD_Goto(0,0);

    for (i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++)
    {
        if(num_image==0)
        {
        LCD_Commmand(DATA, image0[i]);
        }

        x++;
        if(x>=SSD1306_LCDWIDTH)
        {
            x=0;
            y++;
            LCD_Goto(0,y);
        }
    }
}

void LCD_Bat(unsigned char y,unsigned char x, unsigned char z)
{
 unsigned char i=0;

 LCD_Goto2X(x-1,y);
 LCD_Commmand(DATA, 0xFF); LCD_Commmand(DATA, 0xFF);
 LCD_Goto2X(x+2,y);
for (i=0; i<14; i++)
    {
       if(i<11)
       {
         if(z>=i){ LCD_Commmand(DATA, 0xBD); }
         else    { LCD_Commmand(DATA, 0x81); LCD_Commmand(DATA, 0x81); }
       }
       if(i==11)      {LCD_Commmand(DATA, 0xFF); LCD_Commmand(DATA, 0xFF);}
       if(i==12)      {LCD_Commmand(DATA, 0x3C); LCD_Commmand(DATA, 0x3C);}
       if(i==13)      {LCD_Commmand(DATA, 0x3C); LCD_Commmand(DATA, 0x3C);}
       LCD_Goto2X(x+i,y);
    }

}
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

дамы и господа, еще вот такой вот вопрос. делаю схему давилки паяльной пасты.
один потенциометр для изменения скорости у меня подключен по PC0, необходимо добавить второй потенциометр на PC1, но я так и не смог разобраться, как подключить второй.
при всех моих усилиях ножка PC1 не видится.

вот так подключаю первый:

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

// Инициализация АЦП
 ADCSRA |= (1 << ADEN) // Включение АЦП
 |(1 << ADPS1)|(1 << ADPS0); // Предделитель преобразователя на 8
 ADMUX |= (0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3) // Вход PC0
 |(1<<REFS0)|(0<<REFS1); // AVcc является опорным напряжением

 unsigned int u=0,t=0; // Переменные потенциометра и задержек
  while (1)
   {
    ADCSRA |= (1 << ADSC); // Начинаем преобразование
    while ((ADCSRA&(1 << ADIF))== 0) // Ждем флага окончания преобразования
    u = (ADCL|ADCH << 8); // Считываем ADC
    if (u > 128) {t=0; sp=0;} // 0.625V
    if (u > 256) {t=210; sp=1;} // 1.25V
    if (u > 384) {t=190; sp=2;} // 1.875V
    if (u > 512) {t=160; sp=3;} // 2.5V
    if (u > 640) {t=130; sp=4;} // 3.125V
    if (u > 768) {t=100; sp=5;} // 3.75V
    if (u > 896) {t=70; sp=6;} // 4.375V
    if (u > 990) {t=40; sp=7;} // 5V
   }


как подключить второй?
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

попытался подключить, нашел ну очень мудреный способ, реализовал, но не работает
вот код:

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

#include <mega328.h>
#include <delay.h>
#include <i2c.h>
#include <stdio.h>
#include "ssd1306.c"

//******* Глобальные переменные *******
int ch_1; //Переменная хранения данных ADC0
int ch_2; //Переменная хранения данных ADC1
//********* Переменные ADC ***********
#define FIRST_ADC_INPUT 0 //Первый кнал ADC ADC0
#define LAST_ADC_INPUT 1 //Следующийй канал ADC ADC1
#define ADC_VREF_TYPE 0xff
unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1]; //Переменная хранения ADC данных

//*** Обслуживания прерывания для автоматического сканирования каналов ***
interrupt [ADC_INT] void adc_isr(void)
 {
 register unsigned char input_index=0;
 adc_data[input_index]=ADCW; // Чтение результата АЦП преобразования
 if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) // Селективный выбор
 input_index=0; // следующего входа АЦП
 ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff))+input_index;
 delay_us(10); // Выдержка времени для стабилизации входного напряжения
 ADCSRA|=0x40; // Старт АЦП преобразования
 }

//******* Чтение результатов ADC преобразования *******
void adc_convers(void)
 {
 ch_1= adc_data[0];  //Запись в переменную ch_1 результата ADC 1-го канала
 ch_2= adc_data[1];  //Запись в переменную ch_2 результата ADC 2-го канала
 }

void main(void)
 {
 /*** Настройка портов ***/
 DDRC = 0x00; // Порт SW_rotate: PС0-SPEED. SW_push: PС1-BACK; PС2-FORWARD
 PORTC |= (1 << PORTC2); // Подключаем нагрузочный резистор к PC2
 PORTC |= (1 << PORTC3); // Подключаем нагрузочный резистор к PC3
 DDRB = 0xFF; // Порт конфигурируем на выход: Signal Lb1656 1,2; V_Power
 #asm
 .equ __i2c_port=0x0B ;PORTD
 .equ __sda_bit=4
 .equ __scl_bit=5
 #endasm


 // Crystal Oscillator division factor: 1
 //#pragma optsize-
 //CLKPR=0x80;
 //CLKPR=0x00;
 //#ifdef _OPTIMIZE_SIZE_
 //#pragma optsize+
 //#endif

 // Инициализация I2C Bus
 i2c_init();
 LCD_init();
 LCD_Clear();
 LCD_Contrast(1);
 LCD_DrawImage(0);
 delay_ms(3000);
 LCD_Clear();

  {
  char buff[40];  //буфер дисплея
  unsigned int u1=0,u2=0; // Переменные потенциометров
  unsigned int u=0; // Переменная потенциометра типа!!!
  unsigned int t=0; // Переменная задержек
  unsigned int sp=0; // Переменная скорости
  unsigned int v=0; // Переменная батареи

  while (1)
   {
   adc_convers(); //Чтение результатов ADC преобразования
   {
   unsigned int per=0, i=0, k=0; // Переменные счетчиков цикла
   u1=ch_1;
   if (u1 > 128) {t=0; sp=0;} // 0.625V
   if (u1 > 256) {t=210; sp=1;} // 1.25V
   if (u1 > 384) {t=190; sp=2;} // 1.875V
   if (u1 > 512) {t=160; sp=3;} // 2.5V
   if (u1 > 640) {t=130; sp=4;} // 3.125V
   if (u1 > 768) {t=100; sp=5;} // 3.75V
   if (u1 > 896) {t=70; sp=6;} // 4.375V
   if (u1 > 990) {t=40; sp=7;} // 5V
   u2=ch_2;
   if (u2 > 128) {v=0;} // 0.625V
   if (u2 > 256) {v=1;} // 1.25V
   if (u2 > 384) {v=2;} // 1.875V
   if (u2 > 512) {v=3;} // 2.5V
   if (u2 > 640) {v=4;} // 3.125V
   if (u2 > 768) {v=5;} // 3.75V
   if (u2 > 896) {v=6;} // 4.375V
   if (u2 > 990) {v=7;} // 5V
   LCD_Goto(0,0);
   sprintf(buff,"Speed: %i ",sp);
   LCD_Printf(buff,0); // Вывод на дисплей значения скорость
   if (sp<1)
    {
    LCD_Goto(0,1);
    sprintf(buff,"Change speed   ");
    LCD_Printf(buff,0);
    }
   else
    {
    LCD_Goto(0,1);
    sprintf(buff,"Ready to work   ");
    LCD_Printf(buff,0);
    }
   LCD_Bat(0,102,v); // Вывод значка батареи
}
}

почему не читает данные обоих потенциометров?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

какой-то лютый трэш...

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

static int get_adc(char chanel){
   ADMUX = ADC_VREF_TYPE | (chanel & 0x07);
   ADCSRA |= (1<<ADSC);
   while(ADCSRA & (1<<ADSC));
   return ADCW;
}

#define POROG_CNT   8

static int get_value(char res, int *val){
   static int porog[POROG_CNT] = {128,256,384,512,640,768,896,990};
   static int value[POROG_CNT] = {0,210,190,160,130,100,70,40};
   
   char i;
   int adc = get_adc(res);

   for(i=0; i<POROG_CNT; i++){
      if(adc > porog[i]){
         *val = value[i];
         return i;
      }
   }
   // если adc самое минимальное
   *val = 0; // ????
   return 0; // ????
}
там, где надо измерять оба канала, делать как-то так

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

int value1, value2;

// adc_X - соответственно номер канала АЦП
char level1 = get_value(adc_1, &value1);
char level2 = get_value(adc_2, &value2);
// в levelX у вас то, что раньше попадало sp
// в valueX у вас то, что раньше попадало в t
// где X - номер вашего "резистора"
// делайте с этими значениями, что хотите


само собой, до всего этого надо настроить режим работы АЦП
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

to ARV,
да, очень важно получать данные сразу с двух потенциометров.
переделываю шапку, как вы написали, зашел в wizard, там АЦП ставлю, но он в упор не видит PC0 и PC1, ругается на adc_1 и adc_2.

P.S.как работать с одним я разобрался, но с двумя в упор не понимаю, пробовал делать по аналогии, как с одним через MUX3, MUX2, MUX1, MUX0 но обрабатывает только один, второй повторитель. если же между ними ставить delay_ms() ругается на него.
у вас есть пример примитивной программы с двумя или больше потенциометрами? что бы понять, что к чему.
P.S.S. протеусом принципиально не пользуюсь, сразу на "железо" вывожу, так понятнее, что оно там делает.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

у вас изначально написан какой-то бред (возможно, я чего-то в CVAVR недопонимаю):

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

#define ADC_VREF_TYPE 0xff
ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff))+input_index;

в связи с этим надо начать с того, что задать корректно значение ADC_VREF_TYPE - это должно быть число (байт), в котором установлены только биты, отвечающие за выбор нужного источника опорного напряжения, все остальные должны быть обнулены.

затем настраиваете режим работы АЦП, т.е. включаете его, задаете выравнивание результата, указываете частоту тактирования. как вы это сделаете - при помощи визарда или без, - меня не интересует, главное, чтобы было сделано, что я написал.

затем берете мой код и пользуетесь функцией get_adc для получения значения нужного вам канала АЦП. просто передаете этой функции в качестве параметра НОМЕР канала АЦП и получаете результат. т.е. если первый резистор подключен к ADC0, то обращаетесь к функции так get_adc(ADC0); я не уверен, что CVAVR корректно отработает ADC0, если что - просто пишите 0. надо опросить 5-й канал, пишите get_adc(5);

так вы можете получить значения с любого из входов АЦП. одновременно с двух или более не получится, но можно почти одновременно, путем последовательного опроса каналов.

затем вы что-то там вычисляете на основе полученных значений - ваш код неоптимальный, я предложил чуть более оптимальный, но это не догма. главное, вы получили значения с двух каналов, а дальше - творите, что хотите.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

to ARV, вообще не понимаю, уже и инструкции надыбал, что есть что, к примеру тут, как раз для моей отладочной платы arduino nano 3 на atmega 328(p) - индекс 'p', как я понял добавляет лишь измерение собственной температуры к atmega328.
и по инструкции разобрался, но как последовательно их опрашивать в упор не понимаю.
первоначальный вариант кода такой: (то, что вверху это мои попытки добавить второй)

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

#include <mega328p.h>
#include <delay.h>
#include <i2c.h>
#include <stdio.h>
#include "ssd1306.c"

void main(void)
 {
 /*** Настройка портов ***/
 DDRC = 0x00; // Порт SW_rotate: PС0-SPEED. SW_push: PС1-BACK; PС2-FORWARD
 PORTC |= (1 << PORTC0); // Разрешаем внешние прерывания на PC0
 PORTC |= (1 << PORTC1); // Разрешаем внешние прерывания на PC1
 PORTC |= (1 << PORTC2); // Подключаем нагрузочный резистор к PC2
 PORTC |= (1 << PORTC3); // Подключаем нагрузочный резистор к PC3
 DDRB = 0xFF; // Порт конфигурируем на выход: Signal Lb1656 1,2; V_Power
 #asm
 .equ __i2c_port=0x0B ;PORTD
 .equ __sda_bit=4
 .equ __scl_bit=5
 #endasm
 #asm("sei")   // или SREG |= (1<<7);  Status Register, 7 бит разрешает общие прерывания.

 // Crystal Oscillator division factor: 1
 #pragma optsize-
 CLKPR=0x80;
 CLKPR=0x00;
 #ifdef _OPTIMIZE_SIZE_
 #pragma optsize+
 #endif

 // Инициализация АЦП
 ADCSRA |= (1 << ADEN) // Включение АЦП
 |(1 << ADPS1)|(1 << ADPS0); // Предделитель преобразователя на 8
 ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0) // Вход PC0
 |(1<<REFS0)|(0<<REFS1); // AVcc является опорным напряжением

 // Инициализация I2C Bus
 i2c_init();
 LCD_init();
 LCD_Clear();
 LCD_Contrast(1);
 LCD_DrawImage(0);
 delay_ms(3000);
 LCD_Clear();

  {
  char buff[40];  //буфер дисплея
  unsigned int u=0,t=0; // Переменные потенциометра и задержек
  unsigned int sp=0; // Переменная скорости
  unsigned int out=0; // Переменная батареи

  while (1)
   {
   unsigned int per=0, i=0, k=0; // Переменные счетчиков цикла
    {
    ADCSRA |= (1 << ADSC); // Начинаем преобразование
    while ((ADCSRA&(1 << ADIF))== 0) // Ждем флага окончания преобразования
    u = (ADCL|ADCH << 8); // Считываем ADC
    if (u > 128) {t=0; sp=0;} // 0.625V
    if (u > 256) {t=210; sp=1;} // 1.25V
    if (u > 384) {t=190; sp=2;} // 1.875V
    if (u > 512) {t=160; sp=3;} // 2.5V
    if (u > 640) {t=130; sp=4;} // 3.125V
    if (u > 768) {t=100; sp=5;} // 3.75V
    if (u > 896) {t=70; sp=6;} // 4.375V
    if (u > 990) {t=40; sp=7;} // 5V
    LCD_Goto(0,0);
    sprintf(buff,"Speed: %i ",sp);
    LCD_Printf(buff,0); // Вывод на дисплей значения скорость
    LCD_Bat(0,102,sp); // Вывод значка батареи
    if (sp<1)
     {
     LCD_Goto(0,1);
     sprintf(buff,"Change speed   ");
     LCD_Printf(buff,0);
     }
    else
     {
     LCD_Goto(0,1);
     sprintf(buff,"Ready to work   ");
     LCD_Printf(buff,0);
     }
дальше идет опрос кнопок и обработка необходимых мне действий

это кусок кода исключительно с опросом одного АЦП
и ведь он работает идеально, но вот, как два сделать, не понимаю в упор.
у вас есть простая программа с двумя или более АЦП, что бы разобраться, как их переключать.
как я понимаю их надо просто последовательно опрашивать записывая полученное значение, вот только проблема в том, что я не понимаю, как их опрашивать последовательно.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

я вам написал 90% кода, и рассказал, как надо. ваш код - лютый отжиг.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

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

flimp писал(а):... но вот, как два сделать, не понимаю в упор. у вас есть простая программа с двумя или более АЦП, что бы разобраться, как их переключать. как я понимаю их надо просто последовательно опрашивать записывая полученное значение, вот только проблема в том, что я не понимаю, как их опрашивать последовательно.

Для начала, прочтите страницы 314-315 в ДШ, где начинается раздел:
29.5. Changing Channel or Reference Selection
    The Analog Channel Selection bits (MUX) and the Reference Selection bits (REFS) bits in the ADC
    Multiplexer Selection Register (ADCMUX.MUX[3:0] and ADCMUX.REFS[1:0]) are ...

29.5.1. ADC Input Channels
    When changing channel selections, the user should ...

Ах да, еще блок-схему на странице 311.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

открыл datasheet, там по указанной странице что то совсем не то - "30.2.1 ATmega48PA DC Characteristics – Current Consumption", но нужное нашел, спасибо.

и в итоге сделал, таки сам.
ну почти все сам (лишь пару кусочков кода дернул из сети и в итоге слепил франкенштейна).
но работает.
а вот этот гад "ADC_VREF_TYPE" особенно мозг вынес... (вроде писал все верно, а вот не работало из за вот него)
Спойлер

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

#include <mega328p.h>
#include <delay.h>
#include <i2c.h>
#include <stdio.h>
#include "ssd1306.c"



// Глобальные переменные
int ch_0; // Переменная хранения данных ADC0
int ch_1; // Переменная хранения данных ADC1
char buff[40];  //буфер дисплея


// Переменные ADC
#define FIRST_ADC_INPUT 0 // ADC0
#define LAST_ADC_INPUT 1 // ADC1
#define ADC_VREF_TYPE 0x40
unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1]; // Переменная хранения ADC данных


// Обслуживания прерывания для автоматического сканирования каналов
interrupt [ADC_INT] void adc_isr(void)
{
static unsigned char input_index=0;
adc_data[input_index]=ADCW; // Читаем результат АЦП
if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) // Селективный выбор
input_index=0;                                        // следующего входа АЦП
ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff))+input_index;
delay_ms(1); // Стабилизация входного напряжения через delay
ADCSRA |=0x40; // Старт АЦП преобразования
}

// Чтение результатов ADC преобразования
void adc_convers(void)
{
ch_0= adc_data[0]; // Запись в переменную ch_1 из ADC0
ch_1= adc_data[1]; // Запись в переменную ch_2 из ADC1
}

void main(void)
{
 /*** Настройка портов ***/
 DDRC = 0x00; // Порт SW_rotate: PС0-SPEED. SW_push: PС1-BACK; PС2-FORWARD
 PORTC |= (1 << PORTC0); // Разрешаем внешние прерывания на PC0
 PORTC |= (1 << PORTC1); // Разрешаем внешние прерывания на PC1
 PORTC |= (1 << PORTC2); // Подключаем нагрузочный резистор к PC2
 PORTC |= (1 << PORTC3); // Подключаем нагрузочный резистор к PC3
 DDRB = 0xFF; // Порт конфигурируем на выход: Signal Lb1656 1,2; V_Power



// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff);
ADCSRA=0xCB;

// Global enable interrupts
#asm("sei")

 // I2C Bus functions
#asm
.equ __i2c_port=0x0B ;PORTD
.equ __sda_bit=4
.equ __scl_bit=5
#endasm



// I2C Bus initialization
i2c_init();
LCD_init();
LCD_Clear();
LCD_Contrast(1);
//LCD_DrawImage(0);
//delay_ms(3000);
//LCD_Clear();

while (1)
{
adc_convers(); //Чтение результатов ADC преобразования
LCD_Goto(0,0);
       sprintf(buff,"ADC0=%i ",ch_0);
       LCD_Printf(buff,0);  //  вывод на дисплей
       LCD_Goto(0,1);
       sprintf(buff,"ADC1=%i ",ch_1);
       LCD_Printf(buff,0);  //  вывод на дисплей
};
}

выводит на экран две строчки в режиме реального времени и показаниями каждого потенциометра от 0 до 1023. только вот почему не до 1024?

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

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

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

flimp писал(а):почему у меня показания потенциометров так колбасит?
Добавьте примитивные RC-фильтры на входе АЦП, должны помочь. Либо сделайте программные.

flimp писал(а):только вот почему не до 1024?
Потому что максимальное число у 10 бит - 1023, а не 1024.
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

to Аlex, добавил простейший аппаратный фильтр на двух конденсаторах, по 68nF каждый, и действительно - дергаться перестал.
вот только это лишнее место на текстолите, который и так уже получается достаточно большим.
пойду искать программный способ.

и еще, похоже из за этой части кода:

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

// ADC initialization
 // ADC Clock frequency: 125,000 kHz
 // ADC Voltage Reference: AREF pin
 ADMUX=FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0x07);
 ADCSRA=0xCB;

глобальная частота стала 125кГц, а нужен 1мГц, как вернуть? (что бы не повлияло на АЦП)
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

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

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

flimp писал(а):открыл datasheet, там по указанной странице что то совсем не то - "30.2.1 ATmega48PA DC Characteristics – Current Consumption" ...
Нужно пользоваться актуальными ДШ, а не архивными.
flimp писал(а):... похоже из за этой части кода:

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

...
 ADCSRA=0xCB;

глобальная частота стала 125кГц, а нужен 1мГц, как вернуть?
Убрать делитель клока на 8 (ADPS[2:0], стр 323)
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
flimp
Прорезались зубы
Сообщения: 242
Зарегистрирован: Вс май 24, 2015 19:10:41

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

Сообщение flimp »

а можно ссылку на актуальный датащит о котором вы говорите.
MEGAORC
Родился
Сообщения: 11
Зарегистрирован: Чт фев 04, 2016 13:54:47

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

Сообщение MEGAORC »

Подскажите как в CVAVR по SPI прочитать байт не изменяя его. Мне нужно прочитать состояние радиомодуля RFM23BP. На сколько я понимаю, прочитать байт, можно только отправив на модуль любой другой байт. Но тогда в модуле, о его состоянии появятся ложные данные, которые я отправил. Боюсь это может дать сбой в модуле.
Как записать понятно, например
spi (0x7F, 0xFF); \\ записать 8 единиц в регистр 0x7F
А как только прочитать, не перезаписывая данные в нем?

В интернете был пример с программным SPI. И там для чтения писалось просто:
temp = SPI_READ(0x03);

Код программного SPI
Спойлер

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

#define nIRQ PINC.3   //PINB.3
#define nSEL PORTC.2  //PORTB.2
#define nSCK PORTC.1  //PORTB.1
#define nSDI PORTC.0  //PORTB.0
#define nSDO PINB.2   //PIND.6


void SPI_WRITE(unsigned char Addr, unsigned char data)
{
unsigned char i=0;
Addr=Addr|0x80;         
nSEL=0;
delay_us(10);
for (i=0; i<8; i++)
        {
        nSDI=(Addr>>(7-i))&0x01;
        delay_us(10);
        nSCK=1;
        delay_us(30);
        nSCK=0;
        delay_us(20);
        }
for (i=0; i<8; i++)
        {
        nSDI=(data>>(7-i))&0x01;
        delay_us(10);
        nSCK=1;
        delay_us(30);
        nSCK=0;
        delay_us(20);
        }
nSEL=1;                 
delay_us(20);
}

unsigned char SPI_READ(unsigned char Addr)
{
unsigned char i=0;
unsigned char data=0;
Addr=Addr&0x7F;         

nSEL=0;
delay_us(10);
for (i=0; i<8; i++)
        {
        nSDI=(Addr>>(7-i))&0x01;
        delay_us(10);
        nSCK=1;
        delay_us(30);
        nSCK=0;
        //delay_us(200);
        delay_us(20);
        //if (i==8) LED_OUT(255);
        }
for (i=0; i<8; i++)
        {
        nSCK=1;
        delay_us(30);
        data=data<<1;
        data|=(nSDO);
        nSCK=0;
        delay_us(20);
        }
nSEL=1;               
delay_us(20);
return data;
}

Заранее спасибо.
Ответить

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