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

Вопросы от начинающих по МК


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

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

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

Учение - изучение правил. Опыт - изучение исключений.

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

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

  • Ответов
  • Создана
  • Последний ответ

Топ авторов темы

Образовалась загвоздка.Если выношу код в цикл while, то код в операторе if не выполняется.Если переношу этот же код в функцию margal(); то все работает.

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/interrupt.h>

#define BAUD 9600UL // Скорость обмена данными
#define UBRRL_value (F_CPU/(BAUD*16))-1 //Согластно заданной скорости подсчитывает
#define BEEP 30
void init_USART() {
	UBRRL = UBRRL_value;       //Младшие 8 бит UBRRL_value
	UBRRH = UBRRL_value >> 8;  //Старшие 8 бит UBRRL_value
	UCSRB |=(1<<RXEN)|(1<<RXCIE);         //Бит разрешения приема
	UCSRC |=(1<< URSEL)|(1<< UCSZ0)|(1<< UCSZ1); //Устанавливем формат 8 бит данных
}




 int xu,zzz,dec,decp;
 int fns,fend,fg,fp,fv,no,alla;
 char GPS[40];
 char mass,masss ,ix, ii;
 char i=0;
 
 
// установка лог. "1" на линии E 
#define LCD_E_SET    PORTB|=0x02
/* установка лог. "0" на линии E */
#define LCD_E_CLR    PORTB&=0xFD
/* установка лог. "1" на линии RS */
#define LCD_RS_SET   PORTB|=0x01
/* установка лог. "0" на линии RS */
#define LCD_RS_CLR   PORTB&=0xFE
 
/* макрос, указывающий функции, что
передаются команды */
#define LCD_COMMAND  0
/* макрос, указывающий функции, что
передаются данные */
#define LCD_DATA     1
 
#define lcd_putc(x)  lcd_putbyte(x, LCD_DATA)
 
/* инициализация портов,
подключенных к жки */
void init_port()
{
	DDRB=0xFF;
    PORTB=0x00;
	DDRC=0xFF;
    
}
 
/* функция передачи тетрады в жки */
void lcd_putnibble(char t)
{
    t<<=4;
    LCD_E_SET;
    _delay_us(50);
    PORTB&=0x0F;
    PORTB|=t;
    LCD_E_CLR;
    _delay_us(50);
}
 
/* функция передачи байта в жки.
char c - сам байт
char rs - переменная, указывающая что передается:
     rs = 0 - команда (устанавливается линия RS)
	 rs = 1 - данные (сбрасывается линия RS) */
void lcd_putbyte(char c, char rs)
{
    char highc=0;
    highc=c>>4;
	if (rs==LCD_COMMAND) LCD_RS_CLR;
	else                 LCD_RS_SET;
    lcd_putnibble(highc);
    lcd_putnibble(c);
}
 
void lcd_putchar(char c)
{
    char highc=0;
    highc=c>>4;
	LCD_RS_SET;
    lcd_putnibble(highc);
    lcd_putnibble(c);
	
}
 
/* функция инициализации работы жки
в 4-битном режиме, без курсора */
void lcd_init()
{
    _delay_ms(15);
    lcd_putnibble(0b00000011);
    _delay_ms(4);
    lcd_putnibble(0b00000011);
    _delay_us(100);
    lcd_putnibble(0b00000011);
	 _delay_ms(1);
    lcd_putnibble(0b00000010);
	_delay_ms(1);
    lcd_putbyte(0x28, LCD_COMMAND);
    _delay_ms(1);
    lcd_putbyte(0x0C, LCD_COMMAND);
    _delay_ms(1);
    lcd_putbyte(0x06, LCD_COMMAND);
    _delay_ms(1);
}
 
/* функция очистки дисплея и возврата
курсора в начальную позицию*/
void lcd_clear()
{
    lcd_putbyte(0x01, LCD_COMMAND);
    _delay_us(1500);
}

ISR(USART_RXC_vect)   // $GPVTG,165.48,T,,M,0.03,N,0.06,K,A*37 CR(carriage return) LF (Line feed)
{
	zzz=UDR;
	
	dec=zzz;
	lcd_putchar(zzz);
	ii++;
	
	if (dec=='7')
	{
		i=1;
	}
	if (dec=='8')
	{
		i=0;
	}
	if (ii>15)
	{
		lcd_clear();
		lcd_gotoxy(0,0);
		ii=0;
	}

}


void margal(void)
{
	
	if ( i==1 )
	{
		
		PORTC=0b00000001;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(BEEP);
		PORTC=0b00000001;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(BEEP);
		PORTC=0b00000001;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(250);
		PORTC=0b00000010;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(BEEP);
		PORTC=0b00000010;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(BEEP);
		PORTC=0b00000010;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(250);
		
	}
	
}

 
/* функция перемещения курсора в заданную позицию
col - номер знакоместа по горизонтальной оси (от 0 до 15)
row - номер строки (0 или 1) */
void lcd_gotoxy(char col, char row)
{
  char adr;
  adr=0x40*row+col;
  adr|=0x80;
  lcd_putbyte(adr, LCD_COMMAND);
}
 
void lcd_putstring (char stroka[])
{  
   char i;
   for(i=0;stroka[i]!='\0';i++)
   lcd_putchar(stroka[i]);
}	
 

int main(void)
{
	// иничиализируем порт B
    init_port();
	init_USART();
	_delay_ms(100);
	
 
	// инициализируем ЖКИ десплей
    lcd_init();
	_delay_ms(100);
	lcd_clear();
	lcd_gotoxy(0,0);
	sei();
	
	while(1)
{
	margal();
	
/*	if ( i==1 )
	{
		
		PORTC=0b00000001;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(BEEP);
		PORTC=0b00000001;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(BEEP);
		PORTC=0b00000001;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(250);
		PORTC=0b00000010;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(BEEP);
		PORTC=0b00000010;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(BEEP);
		PORTC=0b00000010;
		_delay_ms(BEEP);
		PORTC=0;
		_delay_ms(250);
		
	}*/
	
}
}

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

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

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

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

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

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

Все переменные, используемые одновременно в обработчике прерываний и в главном цикле (или где-то еще), должны быть объявлены volatile

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

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

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

7 часов назад, Alexeyslav сказал:

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

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

Чего там проверять то в МК? И причем тут компьютерные системы? 

В МК прохождение сброса контролируется на счет "раз". Простой ловушкой с определением причин сброса.

Можно ловушку поставить в конце флеша... И размеры программы, а так же ее сложность никак на это не повлияют.

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

 

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

戦う前に相手のベルトの色に注目

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

Утро доброе! Помогите запихнуть массив в память программ и считать данные. Делаю вот так:

//создаю подключаемый файл
//Font16.c
#include "Font16.h"
const uint8_t mas1[]PROGMEM={1,2,3};
const uint8_t mas2[]PROGMEM={4,5,6,7,8};
const uint8_t* const mass[]PROGMEM={mas1,mas2};

//Font16.h
#ifndef FONT16_H_
#define FONT16_H_
#include "main.h"
extern const uint8_t* const mass[]PROGMEM;//
#endif /* FONT16_H_ */

//main.h
#ifndef MAIN_H_
#define MAIN_H_
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include "Font16.h"
#endif /* MAIN_H_ */
 
//основной файл
//main.c
#include "main.h"
uint8_t a;
  int main(void)
{
		a=pgm_read_byte(&(mass[0])[0]);
}

Не получается таким способом, в AtmelStudio6 переменная а=12, но если массивы пишу в главном файле перед функцией main, все работает как надо. Хотел сделать именно так, чтобы можно было шрифты менять ну и не захламлять main.c. 

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

Во-первых, если версия компилятора у вас 4.х.х или свежее (лично й меня 6.3.0), то вместо PROGMEM описания переменных вы можете использовать __flash перед нею, и тогда работа с такими "переменными" будет полностью прозрачной, pgm_read_xxxx не потребуется вообще. Будут правильно обработаны и указатели на такие штуки.

Во-вторых, у вас есть массив mass, хранимый в PROGMEM. это значит, что извлекать из него элемент придется функцией pgm_read_xxxx - вы это делаете. Но элементы этого массива - это указатели на другие массивы, тоже хранимые в PROGMEM, т.е. извлекать те данные тоже надо pgm_read_xxxx - у вас этого нет.

В-третьих, для считывания указателя из массива нельзя использовать pgm_read_byte, потому что размер указателя равен размеру int, т.е. не 1 байт, а 2. надо применять pgm_read_word.

В итоге у вас должно быть так: pgm_read_byte(pgm_read_word(&mass[0]));

Но лучше - как я написал в первом предложении, тогда было бы так:

const __flash uint8_t mas1[] = {1,2,3};
const __flash uint8_t mas2[] = {4,5,6,7,8};
const __flash const __flash uint8_t * mass[] = {mas1,mas2};

a = mass[0][0];

 

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

В итоге у вас должно быть так: pgm_read_byte(pgm_read_word(&mass[0]));

Спасибо, это помогло, еще вопросик остался, таким образом мы прочитали первый байт mas1[], а как прочитать следующий байт этого массива?

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

Во-первых, если версия компилятора у вас 4.х.х или свежее (лично й меня 6.3.0), то вместо PROGMEM описания переменных вы можете использовать __flash

Пишу в AtmelStudio6.2, не знаю какая версия компилятора, __flash не понимает.

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

Еще интересный момент, если сделать вот так

//main.c
const uint8_t d[]PROGMEM={1,0,0,0};
const uint8_t v[]PROGMEM={5,6,8,5,6};
const uint8_t* const sum[]PROGMEM={d,v};
uint8_t a;
int main(void)

{			
		a=pgm_read_byte( &(sum[1])[0]);// число 5
		a=pgm_read_byte( &(sum[1])[1]);// 6
		a=pgm_read_byte( &(sum[1])[2]);// 8
		a=pgm_read_byte( &(sum[1])[3]);// 5
		a=pgm_read_byte( &(sum[1])[4]);// 6
}

т.е. сделать все объявления в главном файле, то все вроде как работает...

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

55 минут назад, Demonrostov сказал:
1 час назад, ARV сказал:

В итоге у вас должно быть так: pgm_read_byte(pgm_read_word(&mass[0]));

Спасибо, это помогло, еще вопросик остался, таким образом мы прочитали первый байт mas1[], а как прочитать следующий байт этого массива?

Вроде разобрался. Вот так в студии  работает

pgm_read_byte(pgm_read_word(&mass[0]));//первый байт

pgm_read_byte(pgm_read_word(&mass[0])+1);//второй байт...

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

В 13.11.2017 в 03:42, my504 сказал:

кода, который линкер по каким то причинам оторвал от сплошной прошивки - это частный случай.

Ну да, бутлоадеры это сейчас уже частный случай? Это как раз и есть "отрывок" от прошивки находящийся в конце адресного пространства.

Учение - изучение правил. Опыт - изучение исключений.

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

11 час назад, Alexeyslav сказал:

Ну да, бутлоадеры это сейчас уже частный случай? Это как раз и есть "отрывок" от прошивки находящийся в конце адресного пространства.

Во первых, бутлоадер далеко не всегда в конце, а чаще в начале, либо вообще в защищенном адресном пространстве. 

Во вторых, выход в бутлоадер не может остаться незамеченным. 

То есть фокусы с перехватом управления тут не прокатят. 

戦う前に相手のベルトの色に注目

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

Подскажите пожалуйста есть ли такая возможность с помощью оператора цикла сделать так, чтобы при подачи питания на мк программа делала один цикл, а при отключении питания и снова подключении она снова делала один цикл. Атмега 8 atmel studio 6.2 язык С

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

Вы сами то поняли, что спросили ? :)
Чем это :

8 минут назад, ya.kutier сказал:

а при отключении питания и снова подключении она делала один цикл

отличается от этого :

8 минут назад, ya.kutier сказал:

при подачи питания на мк программа делала один цикл

?

Выходит, что при каждом включении, Вам нужен делать какой-то цикл. В чём тогда проблема ?

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

Только что, Alex сказал:

Вы сами то поняли, что спросили ? :)

Чем это отличается от :

?

Выходит, что при каждом включении, Вам нужен делать какой-то цикл. В чём тогда проблема ?

Да нужно сделать один цикл и все, куда копать?

 

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

@ya.kutier если исполняется один раз, то это не цикл.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

Ну не знаю цикл или нет, а вопрос есть.

15 минут назад, Дмитрий Вас сказал:

Он так всегда делает

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

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

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

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

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

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

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

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

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

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

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

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

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