Перейти к содержанию

Видеокурс по AVR-микроконтроллерам для начинающих


Рекомендуемые сообщения

В подходе. Причем у обоих. Что за издевательство над контроллером? Научитесь уже хотя бы минимальной оптимизации.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

У кого научиться????? С кого можно вытянуть хоть пол слова??? На критику, все умны, а подсказать впадляк

Что означает в подходе???

Как оптимизировать код???

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

БОШКА кипит...

Мой код

#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#include "n5110.h"
#include <stdlib.h>
void presets(){
Lcd_init();
ADCSRA |=(1<<ADEN)
| (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
ADMUX |=(1<<REFS1) | (1<<REFS0);

DDRD = 0xF0; //PD0;PD1;PD2;PD3-входа. PD4;PD5;PD6;PD7-выхода  
PORTD= 0x0F; //PD0;PD1;PD2;PD3-входа с резистором. PD4;PD5;PD6;PD7-выхода с нолем
}

int readADC(unsigned int out){
unsigned char set_admux = ADMUX;

set_admux &= ~((1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0));

switch (out)// функция свитч
{
case 1: set_admux |= ((0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0));break;
case 2: set_admux |= ((0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0));break;
case 3: set_admux |= ((0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0));break;
case 4: set_admux |= ((0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (0<<MUX0));break;
default:break;

}
ADMUX = set_admux;
_delay_us(100);
int output = 0;
for (int i=0;i<20;i++)
{
ADCSRA |=(1<<ADSC);//запуск преобразования
while((ADCSRA & (1<<ADSC))); // ожидание окончания преобразования
output += ADC;//output=output+ADC;
}
return output/20;

}

int main(void)
{

presets();	 

   while(1)	 
 {
  Lcd_clear();  // Очистка дисплея
  Lcd_prints(0,1,FONT_2X,(unsigned char*)PSTR("V"));
  //Lcd_prints(13,1,FONT_2X,(unsigned char*)PSTR("|"));
  Lcd_prints(0,3,FONT_2X,(unsigned char*)PSTR("A"));
  Lcd_prints(0,4,FONT_1X,(unsigned char*)PSTR("п-А  п-V  Ваты"));
  // Lcd_printf(5,1,FONT_2X,((readADC(0)*2.56*(30/2.56))/1023),1);
  Lcd_printf(4,1,FONT_2X,(readADC(0)*0.02932),1);//Вольты
  //Lcd_printf(5,3,FONT_2X,((readADC(1)*2.56*1.47*(10/2.56))/1023),1);
  Lcd_printf(4,3,FONT_2X,(readADC(1)*0.0098),1);//Амперы
  // Lcd_printf(6,5,FONT_1X,(((readADC(2)*2.56*100*(3.73/2.56))/1023)-273.15),0);
  // Lcd_printf(0,5,FONT_1X,((readADC(2)*0.364613)-273.15),0);//Температура , некуда прилепить
  Lcd_printf(10,5,FONT_1X,((readADC(1)*0.0098)*(readADC(0)*0.02932)),0);//VA //Ватт метр
  //порог по вольтажу переменный резистор
  Lcd_printf(5,5,FONT_1X,(readADC(3)*0.02932),1);
  //порог по амперажу переменный резистор
  Lcd_printf(0,5,FONT_1X,((readADC(4)*2.56*(10/2.56))/1023),1);
  Lcd_update();
  int p = 0;						  
  if (readADC(0)>=readADC(3))		
	 {PORTD |=(1<<PD7);				   
	 PORTD &= ~(1 << PD5);}			 
  if (readADC(1)>=readADC(4))		  
	 {PORTD |=(1<<PD6);				  
	 PORTD &= ~(1 << PD5);}		   
  if((PIND&(1 << PD0)) == 0)		
   {while((PIND&(1 << PD0)) == 0){}
	  _delay_ms(200);				   
	 PORTD &= ~((1 << PD7) | (1 << PD6) | (1 << PD5)); }
	 if((PIND&(1 << PD1)) == 0)			 
	  {while((PIND&(1 << PD1)) == 0){}   
	    p++;}								   
	 if(p==1)							   
	  {PORTD |=(1<<PD5);}	 
	    _delay_ms(200);						 
 }
}

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

si4karuk

ну думаю для начала схему вашу нарисуйте с подключением нагрузки.

В подходе. Причем у обоих. Что за издевательство над контроллером? Научитесь уже хотя бы минимальной оптимизации.

Это тема для начинающих. Вы им покажите и обьясните как оптимизировать данный кусок кода :)

коплю на мечту - Днепр К750

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Только что проверил.. Даже без комутации. Просто включаю и на дисплее временами проскакивают кряки. Когда рядом в другую розетку тыкаю трансформатор, дисплей тухнет. По поводу кряк, может что за дисплей вылазит? И у меня шлейф к дисплею около 20см

Так я включаю релю

55555555555555555_240.jpgi.gif

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

Это тема для начинающих. Вы им покажите и обьясните как оптимизировать данный кусок кода :)
Это Ваша тема, могли бы сразу правильно научить, чтобы не пришлось другим переучивать.
Только что проверил.. Даже без комутации. Просто включаю и на дисплее временами проскакивают кряки
Может, случайно переключаете соответствующие выводы контроллера на вход? У них тогда огромное сопротивление, вот любая помеха и развлекается. Можно попробовать заэкранировать - обернуть шлейф фольгой и замотать скотчем для изоляции. Мне в аналогичной ситуации помогло. Ах да, фольгу, разумеется, на землю.
Что означает в подходе???

Как оптимизировать код???

Вот именно поэтому я и считаю, что изучать контроллер надо с ассемблера. Быстро становятся понятны внутренности. А Си слишком абстрактный для такого эффекта. Насчет кода:

1. Использование чисел с плавающей точкой в контроллере - плохая идея (за исключением единичных случаев).

2. Вычисление float x = (int)1*0.01*200; в зависимости от компилятора может проходить с приведением типа к входному операнду, то есть в целых числах. Объяснять, что это даст неверный результат, надо? Если бы это была компьютерная программа - я бы делал так: float x = (int)1; x=x*0.01*200; или float x = (float)((int)1)*0.01*200; то есть с явным приведением типов. Но, см.1, в данном случае использование float неоправданно.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Кажется проблему решил. Тут я виноват. Запитал микросхему от пяти вольт, а дисплей от три и три.

:unsure: Прошу прощения за мою тупость... Мне почему то казалось что так лучше.

Теперь другой вопрос, надо на LM358 пять вольт тулить...

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

Где оптимизация? Во-первых, отказ от чисел с плавающей точкой, во-вторых - от деления:

unsigned int voltage=readADC(0);

voltage=(voltage*30)>>10;

А можно и чуть поднять точность измерения, точнее, точность отображения информации.

unsigned long voltage=readADC(0);
voltage=(voltage*300)>>10;
char buf[5];
itoa(volt,buf,5);
if(buf[0]!='0'){//ноль, просто ноль. Преобразовывать бессмысленно, все равно нулем останется.
if(buf[1]==0){buf[2]=buf[0]; buf[3]=0; buf[0]='0'; buf[1]='.';}//однозначное число, было x, стало 0.x
else if(buf[2]==0){buf[2]=buf[1]; buf[3]=0; buf[1]='.';}//двузначное число, было xx, стало x.x
else {buf[3]=buf[2]; buf[4]=0; buf[2]='.'}//трехзначное число, было xxx, стало xx.x, все равно voltage больше 300 не получится.
}

Изменено пользователем COKPOWEHEU

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

1) Курс закончен?

2) Помогите, пожалуйста. Как вывести переменную на LCD 16x2? Если можно, то на примитивном примерчике)

Судя из библиотеки я понял, что нужно использовать функцию

void lcd_string(uint8_t*, uint8_t);

?

Ссылка на комментарий
Поделиться на другие сайты

Что писать в скобках?
А как Вы поняли, что нужно использовать эту функцию ?

Почитайте в гугле про "строки в языке Си" и "преобразование чисел в строку". И всё сразу станет ясно.

PS: Не ленитесь искать литературу, читать, изучать, пробовать, ...

Ссылка на комментарий
Поделиться на другие сайты

Значит :

Почитайте в гугле про "строки в языке Си" и "преобразование чисел в строку".

:)

ЗЫ: А что это за библиотека ? Не понятно для чего второй параметр при выводе строки. Неужели длина :huh:

Ссылка на комментарий
Поделиться на другие сайты

#ifndef LCD_LIB
#define LCD_LIB

#include <inttypes.h>
//Uncomment this if LCD 4 bit interface is used
//******************************************
#define LCD_4bit
//***********************************************

#define LCD_RS 0  //define MCU pin connected to LCD RS
#define LCD_RW 1  //define MCU pin connected to LCD R/W
#define LCD_E 2 //define MCU pin connected to LCD E
#define LCD_D4 4 //define MCU pin connected to LCD D3
#define LCD_D5 5 //define MCU pin connected to LCD D4
#define LCD_D6 6 //define MCU pin connected to LCD D5
#define LCD_D7 7 //define MCU pin connected to LCD D6
#define LDP PORTD //define MCU port connected to LCD data pins
#define LCP PORTD //define MCU port connected to LCD control pins
#define LDDR DDRD //define MCU direction register for port connected to LCD data pins
#define LCDR DDRD //define MCU direction register for port connected to LCD control pins

#define LCD_CLR             0 //DB0: clear display
#define LCD_HOME            1 //DB1: return to home position
#define LCD_ENTRY_MODE      2 //DB2: set entry mode
#define LCD_ENTRY_INC       1 //DB1: increment
#define LCD_ENTRY_SHIFT     0 //DB2: shift
#define LCD_ON_CTRL         3 //DB3: turn lcd/cursor on
#define LCD_ON_DISPLAY      2 //DB2: turn display on
#define LCD_ON_CURSOR       1 //DB1: turn cursor on
#define LCD_ON_BLINK        0 //DB0: blinking cursor
#define LCD_MOVE            4 //DB4: move cursor/display
#define LCD_MOVE_DISP       3 //DB3: move display (0-> move cursor)
#define LCD_MOVE_RIGHT      2 //DB2: move right (0-> left)
#define LCD_FUNCTION        5 //DB5: function set
#define LCD_FUNCTION_8BIT   4 //DB4: set 8BIT mode (0->4BIT mode)
#define LCD_FUNCTION_2LINES 3 //DB3: two lines (0->one line)
#define LCD_FUNCTION_10DOTS 2 //DB2: 5x10 font (0->5x7 font)
#define LCD_CGRAM           6 //DB6: set CG RAM address
#define LCD_DDRAM           7 //DB7: set DD RAM address
// reading:
#define LCD_BUSY            7 //DB7: LCD is busy
#define LCD_LINES 2 //visible lines
#define LCD_LINE_LENGTH 16 //line length (in characters)
// cursor position to DDRAM mapping
#define LCD_LINE0_DDRAMADDR 0x00
#define LCD_LINE1_DDRAMADDR 0x40
#define LCD_LINE2_DDRAMADDR 0x14
#define LCD_LINE3_DDRAMADDR 0x54
// progress bar defines
#define PROGRESSPIXELS_PER_CHAR 6


void lcd_dat(uint8_t); //forms data ready to send to 74HC164
void lcd_com(uint8_t); //forms data ready to send to 74HC164
void lcd_init(void); //Initializes LCD
void lcd_clr(void); //Clears LCD
void lcd_home(void); //LCD cursor home
void lcd_string(uint8_t*, uint8_t); //Outputs string to LCD
void lcd_gotoxy(uint8_t, uint8_t); //Cursor to X Y position
void copy_string_to_lcd(const uint8_t*, uint8_t, uint8_t);//copies flash string to LCD at x,y
void lcd_definechar(const uint8_t *,uint8_t);//write char to LCD CGRAM 
void lcd_shift_right(uint8_t); //shift by n characters Right
void lcd_shift_left(uint8_t); //shift by n characters Left
void lcd_cursor_on(void); //Underline cursor ON
void lcd_cursor_blink(void); //Underline blinking cursor ON
void lcd_cursor_off(void); //Cursor OFF
void lcd_blank(void); //LCD blank but not cleared
void lcd_visible(void); //LCD visible
void lcd_cursor_left(uint8_t); //Shift cursor left by n
void lcd_cursor_right(uint8_t); //shif cursor right by n
void lcd_progress_bar(uint8_t progress, uint8_t maxprogress, uint8_t length);

#endif

Ссылка на комментарий
Поделиться на другие сайты

?

#include "lcd_lib.h"
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

const uint8_t lcd_customchar[] PROGMEM=//define 6 custom LCD chars
{
0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b0, // 0. 0/5 full progress block
0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b0, // 1. 1/5 full progress block
0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b0, // 2. 2/5 full progress block
0b11100,0b11100,0b11100,0b11100,0b11100,0b11100,0b11100,0b0, // 3. 3/5 full progress block
0b11110,0b11110,0b11110,0b11110,0b11110,0b11110,0b11110,0b0, // 4. 4/5 full progress block
0b11111,0b11111,0b11111,0b11111,0b11111,0b11111,0b11111,0b0, // 5. 5/5 full progress block
};

//*****************************************************************************
void lcd_dat(uint8_t ch) //Sends Char to LCD
{
LDP=(ch&0b11110000);
LCP|=1<<LCD_RS;
LCP|=1<<LCD_E;
_delay_ms(1);
LCP&=~(1<<LCD_E);
LCP&=~(1<<LCD_RS);
_delay_ms(1);
LDP=((ch&0b00001111)<<4);
LCP|=1<<LCD_RS;
LCP|=1<<LCD_E;
_delay_ms(1);
LCP&=~(1<<LCD_E);
LCP&=~(1<<LCD_RS);
_delay_ms(1);
}
//*****************************************************************************
void lcd_com(uint8_t cmd) //Sends Command to LCD
{
LDP=(cmd&0b11110000);
LCP|=1<<LCD_E;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
LDP=((cmd&0b00001111)<<4);
LCP|=1<<LCD_E;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);

}
//*****************************************************************************
void lcd_init(void)//Инициализация дисплея
{
_delay_ms(15);
LDP=0x00;
LCP=0x00;
LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4;
LCDR|=1<<LCD_E|1<<LCD_RW|1<<LCD_RS;
//---------one------
LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //4 bit mode
LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
//-----------two-----------
LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //4 bit mode
LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
//-------three-------------
LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|0<<LCD_D4; //4 bit mode
LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
//--------4 бит 2 строки---------------
lcd_com(0x28);
//-----increment address, invisible cursor shift------
lcd_com(0x0C);

//init 8 custom chars
uint8_t ch=0, chn=0;
while(ch<64)
{
lcd_definechar((lcd_customchar+ch),chn++);
ch=ch+8;
}
}
//*****************************************************************************
void lcd_clr(void) // Очистить дисплей
{
lcd_com(1<<LCD_CLR);
}
//****************************************************************************
void lcd_home(void) //LCD cursor home
{
lcd_com(1<<LCD_HOME);
}
//*****************************************************************************
void lcd_string(uint8_t* data, uint8_t nBytes) // Вывод строки на дисплей
{
register uint8_t i;
// check to make sure we have a good pointer
if (!data) return;
// print data
for(i=0; i<nBytes; i++)
{
lcd_dat(data[i]);
}
}
//*****************************************************************************
void lcd_gotoxy(uint8_t x, uint8_t y) // Переместить курсор в позицию XY
{
register uint8_t DDRAMAddr;
// remap lines into proper order
switch(y)
{
case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
}
// set data address
lcd_com(1<<LCD_DDRAM | DDRAMAddr);
}
//*****************************************************************************
//Вывод строки из памяти в позицию XY
void copy_string_to_lcd(const uint8_t *FlashLoc, uint8_t x, uint8_t y)
{
uint8_t i;
lcd_gotoxy(x,y);
for(i=0;(uint8_t)pgm_read_byte(&FlashLoc[i]);i++)
{
lcd_dat((uint8_t)pgm_read_byte(&FlashLoc[i]));
}
}
//*****************************************************************************
// создание собственного символа
void lcd_definechar(const uint8_t *pc,uint8_t char_code)
{
uint8_t a, pcc;
uint16_t i;
a=(char_code<<3)|0x40;
for (i=0; i<8; i++){
pcc=pgm_read_byte(&pc[i]);
lcd_com(a++);
lcd_dat(pcc);
}
}
//*****************************************************************************
void lcd_shift_left(uint8_t n) //Scrol n of characters Right
{
for (uint8_t i=0;i<n;i++)
{
lcd_com(0x1E);
}
}
//*****************************************************************************
void lcd_shift_right(uint8_t n) //Scrol n of characters Left
{
for (uint8_t i=0;i<n;i++)
{
lcd_com(0x18);
}
}
//*****************************************************************************
void lcd_cursor_on(void) //displays LCD cursor
{
lcd_com(0x0E);
}
//*****************************************************************************
void lcd_cursor_blink(void) //displays LCD blinking cursor
{
lcd_com(0x0F);
}
//*****************************************************************************
void lcd_cursor_off(void) //turns OFF cursor
{
lcd_com(0x0C);
}
//*****************************************************************************
void lcd_blank(void) //blanks LCD
{
lcd_com(0x08);
}
//*****************************************************************************
void lcd_visible(void) //Shows LCD
{
lcd_com(0x0C);
}
//*****************************************************************************
void lcd_cursor_left(uint8_t n) //Moves cursor by n poisitions left
{
for (uint8_t i=0;i<n;i++)
{
lcd_com(0x10);
}
}
//*****************************************************************************
void lcd_cursor_right(uint8_t n) //Moves cursor by n poisitions left
{
for (uint8_t i=0;i<n;i++)
{
lcd_com(0x14);
}
}
//*****************************************************************************
//adapted fro mAVRLIB
void lcd_progress_bar(uint8_t progress, uint8_t maxprogress, uint8_t length)
{ //уровень шкалы, max уровень шкалы,длина шкалы
uint8_t i;
uint16_t pixelprogress;
uint8_t c;

pixelprogress = ((progress*(length*PROGRESSPIXELS_PER_CHAR))/maxprogress);
for(i=0; i<length; i++)
{
if( ((i*(uint16_t)PROGRESSPIXELS_PER_CHAR)+5) > pixelprogress )
{
if( ((i*(uint16_t)PROGRESSPIXELS_PER_CHAR)) > pixelprogress )
{
c = 0;
}
else
{
c = pixelprogress % PROGRESSPIXELS_PER_CHAR;// this is a partial block
}
}
else
{
c = 5;// this is a full block
}
lcd_dat(c);// write character to display
}
}

Ссылка на комментарий
Поделиться на другие сайты

void lcd_string(uint8_t* data, uint8_t nBytes) // Вывод строки на дисплей
{
register uint8_t i;
// check to make sure we have a good pointer
if (!data) return;
// print data
for(i=0; i<nBytes; i++)
{
lcd_dat(data[i]);
}
}

Неужели строка for(i=0;i<nBytes;i++) ни о чем не говорит? Собственно, мне она не говорит об одном - нафига так делать? Что мешало использовать реализацию строк из языка и заставило городить свою? Укажу еще на несколько недостатков этой библиотеки:

2. LCD_RW объявлен, но нигде не используется (настройки порта на ввод-вывод не в счет), все на задержках. Какой смысл отводить на него пин контроллера?

3. LCD_D4 - LCD_D7 объявлены по отдельности, а вот используются вместе: LDP=((cmd&0b00001111)<<4); Хоть бы величину сдвига указали, так нет, выводы 4-7 и никаких разговоров. На кой тогда выносить в настройки?

4. В процедуре copy_string_to_lcd(): в названии не указано, что копировать оно будет из флеш; зачем-то pgm_read_byte() делается два раза: первый - чтобы определить, не кончилась ли строка, принятая в Си (тут религия, видимо, отказала, и строку было решено делать по стандарту), второй - собственно для вывода.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

У автора может и работала, а свои косяки не слишком бросаются в глаза. Может, у него и были причины задавать длину строки при выводе. Но вообще-то протокол у этого дисплея не настолько сложный, чтобы не изобретать его каждый раз заново, под свои задачи. Например, когда оказалось, что на один порт такой дисплей не повесить (контроллер ATmega8, остальные выводы уже заняты), я написал свою версию, где выводы RS и E можно конфигурировать как угодно, в результате первый уехал на PB0 а второй - на PD3, при том, что линии данных висят на PD4-PD7, но можно переместить хоть на PC1-PC4, с поддержкой двух- и четырехстрочного дисплея.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Брал отсюда: http://radioparty.ru/index.php/prog-avr/program-c/361-lesson-lib-lcd

С помощью примеров в коде и данной библиотеки у меня хоть получилось вывести что-либо на lcd. Есть и другие, но не получилось вывести...

P.S. Не пинайте сильно, я сам пару недель назад вообще впервые увидел этот lcd, и неделю назад начал интересоваться, как так что и как выводится....

Сложно, блин....

Ссылка на комментарий
Поделиться на другие сайты

Ещё раз настоятельно рекомендую Вам почитать про строки в Си. Затем, когда сможете ими спокойно манипулировать, почитайте про преобразование переменных в строку. Для этого есть стандартные библиотечные функции, а можно придумать что-нибудь и самому.

Не ленитесь, больше читайте...

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

  • Сообщения

    • У меня больше всего вопросов вызвала необычная схема обеспечения отрицательного питания. Автор этой обстоятельной заметки пишет: For this supply to work correctly, the transformer must have a secondary voltage of at least 18V RMS.  Почему? Что будет не так с отрицательным питанием, если напряжение на трансформаторе будет меньше 18В?   https://tinyurl.com/23mlwxtt - я в простейшей эмуляции ставлю 12В пикового напряжения для трансформатора и на стабилитроне все как положено: -5.6В.
    • Согласен, очень криво объяснил. Это работа трёх вольтовой линии, просто на диод шотки сдвоенный, на один анод приходит сигнал напрямую с трансформатора, а на второй через дроссель. Вольт/деление 5 вольт в клетке, тайминг по моему 10 МС. Третья фотография это сигнал на катодах уровень земли ровно по центру экрана. Но все линии по итогу в порядке 3.3 в, 5, в, 12 в и -12 в. Нагрузить все линии не могу сразу ,так как тут же выгорают транзисторы (имеется нагрузка 250 ватт по 10 ампер на каждую линию за исключением-12в), поэтому нагружаю 3.3 вольтовую линию на 10 ампер,  подключаю переменный резистор 50 ватт на 15 ом на 5 вольтовую линию и постепенно довожу до той той картины с перекосом (это гдето  50 ватт общее). По поводу микросхемы, вверху имеется скрин где между импульсами проскакивает мини импульс, если так можно сказать, он проскакивает и на одной  и на второй ноге (7,8). Микросхема не tl 494, а lw4933/abx942.1/c9421646. Далее они приходят на базы транзисторов 945g  коллекторы этих транзисторов соединены с  выводами трансформатора. Просто схема типовая, легче мне кажется просто привести фото самого блока, для тех кто разбирается будет гораздо информативне.  Диод шотки по 12 вольтовой линии был подгоревший, заменил на донора. Приводить скрины не буду что бы не захламлять тему. В итоге, пока все так же, при достижении определенной нагрузки суммарно где-то 50 ватт, появляется этот "выброс и перекос". По этому имеются мысли на два варианта, это микросхема , этот мини импульс между периодами, на низкой нагрузке особо не влияет, но при достижении определенной приводит с самовозбуждению входной цепи и непроизвольному открытию транзистора нижнего плеча. Либо дело в "горячей части", плавающий дефект в обвязке силовых ключей.  Спасибо за ответ.
    • @Gomerchik а вы контролировали как меняется уровень сигнала на А1 ардуины?
    • Спасибо за совет. Автором данного проекта я не являюсь, мне нужно было воссоздать уличный датчик для метеостанции взамен пропавшего(( Из разного найденного в интернете этот проект работает с моей станцией Орегон (спасибо автору). В понедельник попробую последовать Вашему совету. Но все равно куча непоняток  как блин это работает)) Если дело в неправильной отправки команды, то как на это влияет подключение датчика температуры? Если совсем не подключать таймер, то передача идет один раз (как и прописано в программе), станция принимает и отображает, но минут через сколько-то естественно станция уже ни чего не показывает, но с таймером питание полностью не пропадает с ардуинки, но передача сигнала каким-то образом работает по таймеру.  В моем понимании данная команда подается один раз потому, что таймер должен отключать питание МК после передачи сигнала и каждые 43 сек снова подавать питание (так того требует станция).  Ардуино передает показания температуры отключается полностью и 43 секунды мк не работает.  Сейчас у меня питание пока сделано на подпитке от солнечной батареи, но пару пасмурных дней и аккумулятор съедается до отключения(
    • thickman Так и сделаю. Вытащу из бу БП.  Буду знать, как отличить. Благодарю. Заменил транзисторы на IRFB20N50K. Картина стала, совсем другой.  Похоже трудность не в драйвере, на момент подвозбуда, переходные процессы, в нем, завершены. Увеличил затворные резисторы до 50ом, стало немного лучше.  Не понятно, почему верхний ключ греется несколько сильнее. Возможно, стоит посмотреть ток в коллекторе.  Снабберные емкости временно удалил, изменений не произошло.  Замена ТГР на другой, на кольце MSTN-16A-TH, так же, результата не принесла.   irfb20n50k.pdf
    • А что нить из ассортимента активных щупов производства СССР..))
  • Похожий контент

×
×
  • Создать...