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

BT201 схема подключения и управление из под ATMEGA8


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

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

22 минуты назад, tifaso сказал:

Вот это как раз таки рабочий код это я могу сказать с полной уверенностью.

Ну сколько можно? :rake: В очередной раз советую написать и отладить функцию вывода числа на LCD. :wall:

Для проверки функции, вместо lcd_str(dec) напиши lcd_str(10), lcd_str(233). Когда добьешься на экране отображения чисел 10, 233, сможешь продвинуться дальше.
О какой полной уверенности речь :unknw:
 

С уважением, Владимир

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

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

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

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

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

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

2 минуты назад, Геннадий сказал:

В противном случае, используя рекомендации статьи, Вам придется обнулять dec каждый раз.

Зачем вообще трогать переменную dec в неё по окончанию перевода числа в десятичное записываем полученное десятичное число и всё. В ней должен хранится полученный результат то есть десятичное число. Переменную dec будем уже использовать для вывода полученного числа далее.

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

Hongfa для различных применений в Компэл. Большой выбор в наличии!

Компания HONGFA - это не только крупнейший в мире производитель электромеханических реле, но также производитель конденсаторов, вакуумных прерывателей, трансформаторов и низковольтного коммутационного оборудования. На складе КОМПЭЛ регулярно поддерживаются около 100 самых популярных позиций электромеханических реле. Реле Hongfa могут заместить многие изделия производства недоступных брендов. Подробнее>>

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

8 минут назад, tifaso сказал:

Если char не подходит volatile тоже забраковали

char - это тип переменной

volatile - это НЕ тип !

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

С уважением, Владимир

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

Тренды и лучшие решения для разработки зарядных станций в России

К 2029 году в России прогнозируется увеличение числа зарядных станций до 40 000. При этом отечественный рынок электротранспорта имеет климатические, потребительские и географические особенности. Для успешной разработки и построения инфраструктуры станций заряда в России идеальным вариантом является использование решений и электронных компонентов китайских производителей – лидеров индустрии электротранспорта и возобновляемой энергетики, которые уже представлены в КОМПЭЛ. Подробнее>>

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

11 минут назад, tifaso сказал:

Зачем вообще трогать переменную dec

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

12 минут назад, ДядяВован сказал:

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

Да все получится. Tifaso "варит кашу из топора", а остальные "ингредиенты" мы накидаем постепенно.

У меня внучка домашние задания по математике так делала. Спрашиваю : "Сколько будет трижды три"? А она в ответ: "Пять..., восемь..., двенадцать...". И смотрит внимательно на мою реакцию, когда угадает. Вот так и Tifaso программирует. Кинет затравку "не получается..., не пойму..., а как иначе то". И мы всем скопом копаемся, ищем причины, советуем...:) 

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

Секреты депассивации литиевых батареек FANSO EVE Energy

Самыми лучшими параметрами по энергоемкости, сроку хранения, температурному диапазону и номинальному напряжению обладают батарейки литий-тионилхлоридной электрохимической системы. Но при длительном хранении происходит процесс пассивации. Разберем в чем плюсы и минусы, как можно ее избежать или уменьшить последствия и как проводить депассивацию батареек на примере продукции и рекомендаций компании FANSO EVE Energy. Подробнее>>

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

11 минут назад, Геннадий сказал:

Tifaso "варит кашу из топора"

Ну что "из топора" это понятно. Но если мы уже вторую неделю переводим строку в число, а потом пытаемся вывести число на экран (без преобразования в строку!), то я не представляю сроков реализации этого софта.

 

15 минут назад, Геннадий сказал:

мы накидаем постепенно

Напомнило Жванецкого:
"Тот кто хочет всё и сразу, получает "ничего" и постепенно."

С уважением, Владимир

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

3 часа назад, korsaj сказал:

long dec = CharToInt(rx_buf[3]);

dec = dec*16 + CharToInt(rx_buf[4]);

dec = dec*16 + CharToInt(rx_buf[5]);

Я уже тут сколько времени сижу и пытаюсь понять зачем тут вообще в данном то моменте переменная dec в неё ведь вообще нужно записать полученное десятичное число с которым в дальнейшем пойдут другие пересчёты в случае с временем и дальнейший вывод на дисплей. Но я никак не могу понять каким боком она тут сейчас. Если от функции результат получаем в переменной chl и именно эту переменную и нужно умножать на степень из 16. Как я говорил уже выше согласно статьи. Надеюсь объясните что и как правильно записать уже две недели с этими числами голову себе ломаю, но результата пока не видно.

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

2 hours ago, Геннадий said:

Кинет затравку "не получается...,

Если бы так, то ещё было бы желание помогать ...

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

Это стиль такой. С уверенным видом заявлять откровенную чушь, и у читателей тут же возникает энтузиазм опровергнуть и дать правильный ответ. Не знаю, как у остальных, но у меня лично пока такой энтузиазм возникает :) .

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

Посидел поигрался.

По уарт прилетела такая строка M1+000001A6\r\nM2+00000225\r\nMT+00000125\r\nMK+00000010\r\n, вывел на экран, хрень полная этот 1602, толком ничего не выведешь. В нижнем углу еще режим можно вывести плэй, пауза...

Спойлер
// ****************************************************************************************************************************
void CommandProcessor()
{
	char func;
	char *message;
	char s;
	uint32_t param;
	char str_print[11];
	//
	if (keyOut && (keyOut ^ key_pres_prev))
		key_pres = keyOut;
	key_pres_prev = key_pres;
	//
	switch (regimLCD)
	{	// в зависимости от режима соответственно выводится информация на экран
		case 1:
			LCD_Command(0x80);
			LCD_String(strTime);
			LCD_Command(0xC0);
			LCD_String(strFile);
			regimLCD = 0;			
			break;
		case 2:
		
			break;
	}
	//
	if (MessageRX_cnt)
	{	// если есть сообщение принятое по USART, то обрабатываем его
		message = buf_messageRX;
		func = GetFuncNum(message);
		message += 3;
		do 
		{
			s = *(message++);
			if (s == 0x0D)
				*(--message) = 0;
		} while (s != 0x0D);
		message = buf_messageRX + 3;
		//		
		switch ((uint8_t)func)	
		{
			case M1:	// получили ответ на функцию M1
				if (HexStrToUint32(message, &param))
				{
					IntToStr(str_print, param); 
					LCD_String_xy(1, 5, str_print);	
					LCD_String_xy(1, 8, strM);	
				}						
				break;
			case M2:	// получили ответ на функцию M2
				if (HexStrToUint32(message, &param))
				{
					IntToStr(str_print, param);
					LCD_String_xy(1, 9, str_print);
				}			
				break;	
			case MT:	// получили ответ на функцию MT
				if (HexStrToUint32(message, &param))
				{
					IntToTimeStr(str_print, param);
					LCD_String_xy(0, 10, strM);
					LCD_String_xy(0, 5, str_print);
				}			
				break;
			case MK:	// получили ответ на функцию MK
				if (HexStrToUint32(message, &param))
				{
					IntToTimeStr(str_print, param);
					LCD_String_xy(0, 11, str_print);
				}				
				break;
					}
		MessageRX_cnt = 0;
	}
	else
	{	// иначе обрабатываем нажатые клавиши
		switch ((uint8_t)key_pres)
		{
			case klava1:
			
				break;
			case klava2:
			
				break;
			case klava3:
			
				break;
			case klava4:
			
				break;
			case klava5:
			
				break;
			case klava6:
			
				break;
			case klava7:
			
				break;
			case klava8:
			
				break;
										
		}
		key_pres = 0;							// после обработки клавиши сбросить ее		
	}
}

 

 

Безымянный21.png

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

Наверняка это не для AVRа, а так она мне и нафик не нужна, предполагаю она весит в районе килобайта (как и strtol), я себе на 15 строчек кода нарисовал, мне хватает.

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

11 минут назад, donec сказал:

Наверняка это не для AVRа

А этой функции пофиг АВР или ПЫХ

 

14 минут назад, donec сказал:

предполагаю она весит в районе килобайта

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

Спойлер
#include	<stdlib.h>
	
char *
itoa(char * buf, int val, int base)
{
	char *	cp = buf;

	if(val < 0) {
		*buf++ = '-';
		val = -val;
	}
	utoa(buf, val, base);
	return cp;
}

char *
utoa(char * buf, unsigned val, int base)
{
	unsigned	v;
	char		c;

	v = val;
	do {
		v /= base;
		buf++;
	} while(v != 0);
	*buf-- = 0;
	do {
		c = val % base;
		val /= base;
		if(c >= 10)
			c += 'A'-'0'-10;
		c += '0';
		*buf-- = c;
	} while(val != 0);
	return ++buf;
}

 

 

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

long dec = CharToInt(rx_buf[3]);
dec = dec*16 + CharToInt(rx_buf[4]);
dec = dec*16 + CharToInt(rx_buf[5]);

Есть строка например 1С2 (видим число строке).
теперь когда отправим в функцию CharToInt символ '1' этой строки она нам вернет число 1, мы его поместили в  переменную dec. Получаем dec = 1.
теперь посылаем в функцию CharToInt символ 'С', вернет число 12. Но как мы помним что число 1 у нас занимает старший разряд по отношению к 12. Потому вначале dec умножаем на 16, получаем dec = 16 (и в шестнадцатеричном формате  будет выглядеть так 0х10). теперь прибавляем к нему результат преобразования символа 'С' и получаем 16+12=28 (и в шестнадцатеричном формате  будет выглядеть так 0х1С). Повторяем все тоже самое для следующего символа '2', все также умножаем dec на 16, получаем 448 (0х1С0) и теперь прибавляем нашу полученную 2. В итоге имеем в dec = 450 (0х1С2). То есть у нас была строка "1С2" а после всех манипуляций мы получили число 450 (0х1С2) с которым можно дальше оперировать.

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

15 минут назад, IMXO сказал:

А этой функции пофиг АВР или ПЫХ

Я ставил 7 студию, на 6 не знаю не видел, если проблемы с itoa будут расскажешь где ее взять и как к Студии для AVR подключить, а мне повторяю и нафик не нужна.

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

35 минут назад, tifaso сказал:

переменные будет объявить

Если несколько типов переменных, каждый тип занимает определенное количество байт, соответственно тем самым ограничивается диапазон значений переменной. Например ваш любимый char занимает 1 байт. И принимает значение от -127 до 127, если это unsigned char - занимает все тот же байт но значения от 0 до 255. 

int занимает 2 байта, long 4 байта.

Есть ещё типы для переменных с плавающей запятой float, double.

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

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

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

@korsaj А как собственно нужно объявить в моей ситуации переменные. Их же я так понимаю в зависимости что хочешь от переменной получить так и нужно объявлять.

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

@korsaj Прописал в код твой вариант вызова функции.

Спойлер
#define F_CPU 7372800UL
#define BAUND 9600L
#define UBRRL_value (F_CPU/(BAUND*16))-1

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define MAIN_H_
#define LCD_H_

#define LCD_DDR DDRA
#define LCD_PORT PORTA
#define LCD_PIN PINA

#define DATA 0b11110000
#define RS PA2
#define E PA3

#define E1 LCD_PORT|=(1<<E)
#define E0 LCD_PORT&=~(1<<E)

#define RS1 LCD_PORT|=(1<<RS)
#define RS0 LCD_PORT&=~(1<<RS)

void lcd_ini(void);
void lcd_str(char* str);
void lcd_pos(uint8_t line, uint8_t pos);
void lcd_num(uint8_t num, uint8_t line, uint8_t pos);
uint8_t n=0;
char ind7=0;
char ind6=0;
char ind5=0;
char ind4=0;
char ind3=0;
char ind2=0;
char ind1=0;
char ind0=0;
char dec=0;
char chl=0;


void write(uint8_t n)
{
	n<<=4;
	E1; //линию Е в 1
	LCD_PORT&=~DATA; //удалить предыдущую отправку
	LCD_PORT|=n; //выставить значение на пины управления дата битами
	_delay_us(1);
	E0; //линию Е в 0
}

void send_byte(uint8_t byte, uint8_t tip)
{
	if (tip) //если тип данные на линии RS 1
	{
		RS1;
	}
	else //иначе тип команда и на линии RS 0
	{
		RS0;
	}
	
	write(byte>>4); //передача старшего полубайта
	_delay_us(250);
	write(byte); //передача младшего полубайта
	_delay_us(250);
}

void lcd_ini(void)
{
	LCD_DDR|=DATA | (1<<RS) | (1<<E);
	_delay_ms(20);
	RS0;
	write(3);
	_delay_ms(5);
	write(3);
	_delay_us(150);
	write(3);
	_delay_us(50);
	write(2);
	_delay_us(50);
	
	send_byte(40,0);
	_delay_us(50);
	
	send_byte(12,0);
	_delay_us(50);
	
	send_byte(1,0);
	_delay_ms(2);
	
	send_byte(6,0);
	_delay_us(50);
}

void lcd_str(char* str)
{
	uint8_t n=0;
	while(str[n])
	{
		send_byte(str[n],1);
		n++;
	}
}

void lcd_pos(uint8_t line, uint8_t pos)
{
	uint8_t adress=(line*0x40+pos)|0x80;
	send_byte(adress,0);
	_delay_us(50);
}

void init_pin(void);

#define C_PC0 (~PINC&(1<<PC0))
#define C_PC1 (~PINC&(1<<PC1))
#define LED_1_ON() PORTD|=(1<<PD2)
#define LED_1_OFF() PORTD&=~(1<<PD2)
#define LED_2_ON() PORTD|=(1<<PD3)
#define LED_2_OFF() PORTD&=~(1<<PD3)

#define FLAG_END_RX (1<<3)
#define FLAG_ERR_RX (1<<4)
#define BUF_SIZE 20

char rx_buf[BUF_SIZE];
char buf_index = 0;
char rxb;

volatile start=1, flags;

ISR(USART_RXC_vect)
{
	char rxb = UDR;
	if(!(flags & FLAG_END_RX))
	{
		rx_buf[buf_index]=rxb;
		if(rx_buf[buf_index] == 0x0D)
		{
			flags |= FLAG_END_RX;
			return;
		}
		buf_index++;
		if(buf_index >= BUF_SIZE)
		{
			buf_index = 0;
			flags |= FLAG_ERR_RX;
		}
	}
}

void init_UART()
{
	UBRRL = UBRRL_value;
	UBRRH = UBRRL_value>>8;
	UCSRB|=(1<<TXEN);
	UCSRB|=(1<<RXEN);
	UCSRC|=((1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1));
	UCSRB|=(1<<RXCIE);
	sei();
	flags = 0;
}

void send_UART(char value)
{
	while(!(UCSRA&(1<<UDRE)));
	UDR=value;
}

char CharToInt(char c)
{
	char chl=0;
	if ('0' <= c && c <= '9')
	{
		chl=c-48;
	}
	else if ('A' <= c && c <= 'F')
	{
		chl=c-55;
	}
	return chl;
}

int main(void)
{
	init_pin();
	init_UART();
	
	_delay_ms(500);
	send_UART('O');
	send_UART('K');
	send_UART('!');
	send_UART(0x0D);
	send_UART(0x0A);
	_delay_ms(10);
	flags = 0;
	
	DDRB = 0b10000000;
	PORTB = 0b11111111;
	lcd_ini();
	
	while(1)
	{
		if (~PINB & (1<<1))
		{
			send_UART('P');
			send_UART('B');
			send_UART('1');
			send_UART(0x0D);
			send_UART(0x0A);
			_delay_ms(250);
			lcd_pos(0,0);
			send_byte('A',1);
			lcd_pos(1,0);
			lcd_str("PORT B1");
			lcd_pos(0,10);
			lcd_str("BT201");
		}
		if (~PINB & (1<<2))
		{
			send_UART('P');
			send_UART('B');
			send_UART('2');
			send_UART(0x0D);
			send_UART(0x0A);
			_delay_ms(250);
			lcd_pos(0,0);
			send_byte('B',1);
			lcd_pos(1,0);
			lcd_str("PORT B2");
			lcd_pos(0,10);
			lcd_str("BT201");
		}
		if (~PINB & (1<<3))
		{
			send_UART('P');
			send_UART('B');
			send_UART('3');
			send_UART(0x0D);
			send_UART(0x0A);
			_delay_ms(250);
			lcd_pos(0,0);
			send_byte('C',1);
			lcd_pos(1,0);
			lcd_str("PORT B3");
			lcd_pos(0,10);
			lcd_str("BT201");
		}
		if (~PINB & (1<<4))
		{
			send_UART('P');
			send_UART('B');
			send_UART('4');
			send_UART(0x0D);
			send_UART(0x0A);
			_delay_ms(250);
			lcd_pos(0,0);
			send_byte('D',1);
			lcd_pos(1,0);
			lcd_str("PORT B4");
			lcd_pos(0,10);
			lcd_str("BT201");
		}
		
		char i = 0;
		if (rx_buf[i] == 'M'){
			i++;
			if (rx_buf[i] == '1')
			{	
				LED_1_ON();
				LED_2_OFF();
				
				long dec = CharToInt(rx_buf[3]);
				dec = dec*16 + CharToInt(rx_buf[4]);
				dec = dec*16 + CharToInt(rx_buf[5]);
				dec = dec*16 + CharToInt(rx_buf[6]);
				dec = dec*16 + CharToInt(rx_buf[7]);
				dec = dec*16 + CharToInt(rx_buf[8]);
				dec = dec*16 + CharToInt(rx_buf[9]);
				dec = dec*16 + CharToInt(rx_buf[10]);
				
				lcd_pos(0,0);
				send_byte(rx_buf[3],1);
				lcd_pos(0,1);
				send_byte(rx_buf[4],1);
				lcd_pos(0,2);
				send_byte(rx_buf[5],1);
				lcd_pos(0,3);
				send_byte(rx_buf[6],1);
				lcd_pos(0,4);
				send_byte(rx_buf[7],1);
				lcd_pos(0,5);
				send_byte(rx_buf[8],1);
				lcd_pos(0,6);
				send_byte(rx_buf[9],1);
				lcd_pos(0,7);
				send_byte(rx_buf[10],1);
				
				lcd_pos(1,0);
				lcd_str(dec);
			}
			else if (rx_buf[i] == '2')
			{
				
				LED_1_OFF();
				LED_2_ON();
			}
			else if (rx_buf[i] == 'T')
			{
				
				LED_1_ON();
				LED_2_ON();
			}
			else if (rx_buf[i] == 'K')
			{
				
				LED_1_OFF();
				LED_2_OFF();
			}
		}

		if (C_PC0)
		{
			send_UART('P');
			send_UART('C');
			send_UART('0');
			send_UART(0x0D);
			send_UART(0x0A);
			_delay_ms(250);
			lcd_pos(0,0);
			send_byte('E',1);
			lcd_pos(1,0);
			lcd_str("PORT C0");
			lcd_pos(0,10);
			lcd_str("BT201");
		}
		
		if (C_PC1)
		{
			send_UART('P');
			send_UART('C');
			send_UART('1');
			send_UART(0x0D);
			send_UART(0x0A);
			_delay_ms(250);
			lcd_pos(0,0);
			send_byte('F',1);
			lcd_pos(1,0);
			lcd_str("PORT C1");
			lcd_pos(0,10);
			lcd_str("BT201");
		}
	}
}

void init_pin(void)
{
	DDRC = 0b00000000;
	PORTC = 0b11111111;
	DDRD |= ((1<<2)|(1<<3));
	PORTD &=~ ((1<<2)|(1<<3));
}

 

Но пока не понятно правильно ли это. Результата пока не видно. Чтоб в дальнейшем сделать пересчёт для времени и вывести на дисплей нужно будет конвертировать полученное число в аски.

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

26 минут назад, tifaso сказал:

конвертировать полученное число в аски.

Ну вы еще на шаг ближе к гуру

В коде (весь не просматривал)  функция используется верно.

29 минут назад, tifaso сказал:

число в аски

Сможете без подсказки? Если нет, мысли свои пишите..

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

@korsaj Для того чтобы конвертировать полученное значение в аски я так понимаю нужно создать массив с полученным числом и написать функцию конвертации. В данном случае при переводе в аски нужно к имеющемуся значению прибавлять 48 для чисел это так работает как я понял.

Но в случае с временем там посложней. Там ещё нужно будет разбираться в каком там виде время приходит. Делать пересчёт на минуты и секунды. Но я ещё посмотрю где то я видел как это делается. Мне на глаза просто уже попадался такой код. Нужно будет просто поискать.

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

Гость
Эта тема закрыта для публикации ответов.
  • Последние посетители   0 пользователей онлайн

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

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