Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб апр 16, 2016 17:08:47
К моменту выполнения инструкции SLEEP MCUCR=0, значит о сне можно забыть.
Здесь можно немножко помяукать :)
https://radiokot.ru/forum/

Код: Выделить всё
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);
}Код: Выделить всё
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);
}
} Код: Выделить всё
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
Код: Выделить всё
#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);
}
}Код: Выделить всё
// Инициализация АЦП
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
}
Код: Выделить всё
#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); // Вывод значка батареи
}
}Код: Выделить всё
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 - номер вашего "резистора"
// делайте с этими значениями, что хотите
Код: Выделить всё
#define ADC_VREF_TYPE 0xff
ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff))+input_index;Код: Выделить всё
#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);
}
дальше идет опрос кнопок и обработка необходимых мне действий
Для начала, прочтите страницы 314-315 в ДШ, где начинается раздел:flimp писал(а):... но вот, как два сделать, не понимаю в упор. у вас есть простая программа с двумя или более АЦП, что бы разобраться, как их переключать. как я понимаю их надо просто последовательно опрашивать записывая полученное значение, вот только проблема в том, что я не понимаю, как их опрашивать последовательно.
Ах да, еще блок-схему на странице 311.29.5. Changing Channel or Reference Selection29.5.1. ADC Input Channels
- 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 ...
- When changing channel selections, the user should ...
Код: Выделить всё
#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); // вывод на дисплей
};
}Добавьте примитивные RC-фильтры на входе АЦП, должны помочь. Либо сделайте программные.flimp писал(а):почему у меня показания потенциометров так колбасит?
Потому что максимальное число у 10 бит - 1023, а не 1024.flimp писал(а):только вот почему не до 1024?
Код: Выделить всё
// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0x07);
ADCSRA=0xCB;Нужно пользоваться актуальными ДШ, а не архивными.flimp писал(а):открыл datasheet, там по указанной странице что то совсем не то - "30.2.1 ATmega48PA DC Characteristics – Current Consumption" ...
Убрать делитель клока на 8 (ADPS[2:0], стр 323)flimp писал(а):... похоже из за этой части кода:глобальная частота стала 125кГц, а нужен 1мГц, как вернуть?Код: Выделить всё
... ADCSRA=0xCB;
Код: Выделить всё
#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;
}