Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

uldemir писал(а):Вообще-то, menu_item - это константная структура и ей в ОЗУ делать нечего. Как её заставить разместиться в ПЗУ? модификатора const будет достаточно?
По-моему да, компил кейла наверняка в память программ засунет, но лучше проверить.
uldemir писал(а):Это получается, что я получил переполнение стека?? Но при компиляции мне никто никаких предупреждений не выдал. Что делать и как этого избежать в дальнейшем?
Наверное же есть файл стартапа? Поглядите как там инициализация указателя стека оформлена. Я уже сталкивался и это обсуждалось в ARMом разделе, что по умолчанию в стартапе указаетель инициализируется вовсе на конец памяти. MSP432 я совсем не знаю, если что :).
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Что-то мне кажется, что unsigned char todisplay[16] недостаточно для хранения тех строк. У них у всех длина 17 (с учётом конца строки).
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Хм. Про null-terminated я как-то и позабыл. Но, похоже, что компилятор понял, что я хотел. Вот уже переволок в ПЗУ. помимо const пришлось еще и вытащить наружу из функции (сделать глобальной).
Изображение Изображение
Надо сделать ревизию по проекту, может еще где такая плюха всплывёт. А то на прошлой неделе уже ловил в этом проекте GPF, может это и было причиной (Потому как, снова, таходатчик оказался замешан)?
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Компилятор, скорее всего, этот 17-й 0 просто перезаписывает следующим элементом структуры (указателем), так что оно, казалось бы, ничего страшного. Но тогда функция вывода на экран уже не может опираться на то, что это строка (на null-терминатор), а должна быть искусственно ограничена при выводе 16-ю символами.

А вообще хороший компилятор должен об этом, как минимум, предупредить. А лучше бы выставить такие флаги компиляции, чтобы вообще всё летело в ошибки.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Если добавить еще один символ, предупреждение выдается. И я не пользуюсь функциями вывода. это всё копируется ручками в экранную область.

в startupе нашел только размер стека. в репорте - адрес. Приеду домой, посмотрю в книжке, куда у этих кортексов растет стек, вверх или вниз по адресам?
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

uldemir писал(а):в startupе нашел только размер стека. в репорте - адрес. Приеду домой, посмотрю в книжке, куда у этих кортексов растет стек, вверх или вниз по адресам?
Нормально там все, вниз как у всех.
https://radiokot.ru/forum/viewtopic.php ... 0%B5%D0%BA
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Ну, тогда, я начал понимать что означают эти цифры в репорте.

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

    videobuffer                              0x200004d0   Data         128  configure.o(.bss)
    .bss                                     0x20000550   Section      912  main.o(.bss)
    .bss                                     0x200008e0   Section     4500  maze.o(.bss)
    .bss                                     0x20001a74   Section       24  tachometer.o(.bss)
    .bss                                     0x20001a8c   Section       96  libspace.o(.bss)
    HEAP                                     0x20001af0   Section        0  startup_msp432p401r_uvision.o(HEAP)
    STACK                                    0x20001af0   Section      512  startup_msp432p401r_uvision.o(STACK)
    Heap_Mem                                 0x20001af0   Data           0  startup_msp432p401r_uvision.o(HEAP)
    Stack_Mem                                0x20001af0   Data         512  startup_msp432p401r_uvision.o(STACK)
    __initial_sp                             0x20001cf0   Data           0  startup_msp432p401r_uvision.o(STACK)
В стартапе было написано, что размер стека 512 байт (это всего 128 элементов можно положить?). Вот только не нашел, где бы в настройках это можно было бы изменить. Ну, зато я могу в остальном ОЗУ забабахать буфер для отладочной информации.
Главное, проблему понял. Все эти длинные наборы данных перетащил в ПЗУ. Спасибо за разъяснения.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

нашел еще место, где у меня не хватает памяти в стеке. Хоть я его и увеличил с 0x200 до 0x800 одна функция хапает память. И вот допустим, я хочу ей выделить память в куче.
я так понимаю, что надо звать malloc и оно вернёт мне указатель на эту память. Вопрос первый, как вычислить размер требуемой памяти?

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

map_cell_t map[100];  // для этого надо выделить память.

//а вот их определение:
typedef struct coordinate{
    int    east;
    int north;
} coordinate_t;

typedef struct {
    struct coordinate coordinate;
    unsigned int node_link[4];
    unsigned int pass_count[4];
} map_cell_t;
Так то я могу прикинуть, что один элемент таблицы требует 40 байт, значит 100 => 4000 байт. Но как это написать так, чтобы если я изменю структуру, всё-равно выделялось бы правильно.

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

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

	for (i=0; i<data.map_size; i++) {
		if (map[i].coordinate.north > maxY) maxY = map[i].coordinate.north;
		if (map[i].coordinate.north < minY) minY = map[i].coordinate.north;
		if (map[i].coordinate.east  > maxX) maxX = map[i].coordinate.east;
		if (map[i].coordinate.east  < minX) minX = map[i].coordinate.east;
	}
ok, с первым вроде понятно - malloc(sizeof(map_cell_t)*100);
Но вот со вторым... совсем не понятно как поступить, так как через указатели - придётся весь код переписывать.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Друг Кота
Аватара пользователя
Сообщения: 3386
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

uldemir писал(а):нашел еще место, где у меня не хватает памяти в стеке. Хоть я его и увеличил с 0x200 до 0x800 одна функция хапает память. И вот допустим, я хочу ей выделить память в куче.
В куче есть лишняя память?
Объявите массив глобальным (или статическим если работа в одной функции) или увеличьте стек чтобы в него все поместилось.
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Как обойти проблему - я знаю. просто хочу научиться использовать еще один метод. В куче место должно быть - я ею никогда раньше не пользовался (и stdlib.h нигде не подключал). Да и данная функция не критичная - всего-навсего отрисовывает карту на экране. Если для этого не хватит памяти - не беда. А вот из-за того, что стек налазит куда не нужно, у меня при отрисовке мотор дёргается - это хуже.
Последний раз редактировалось uldemir Чт дек 26, 2019 21:45:05, всего редактировалось 1 раз.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Первое - правильно. Второе как-то так:

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

map_cell_t *map = malloc(sizeof(map_cell_t)*100);
Но это только выделит память на структуру. На сами элементы тоже придется выделять:

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

int i;
for(i = 0; i < 100; ++i)
  map[i] = malloc(sizeof *map[i]);
Но вообще динамическое распределение памяти и куча на МК - очень плохая идея.

Добавлено after 5 minutes 29 seconds:
В куче место должно быть
Эмм... значит и для стека место должно быть )
Изображение
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Пройдите по ссылке из этого сообщения https://radiokot.ru/forum/viewtopic.php ... 7#p3756997 Там есть тема, с которой я тоже сейчас борюсь. Почему-то Keil вершину стека ставит через 512 байт (по умолчанию) после последней переменной, оставляя память над стеком и до конца ОЗУ совершенно пустой. И, компилятор, почему-то совершенно не предупреждает или как-то иначе указывает, что размера стека недостаточно для автоматических переменных. Вот теперь выяснилось, что увеличение стека с 0x200 до 0x800 мало - один этот массив отъедает в два раза больше памяти (как выяснилось). Собственно, мне даже такой большой массив и не нужен - пока карты у меня имели размеры от 12 до 28 элементов. Поэтому и интересно выделить столько сколько нужно, а не все 100 элементов.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

uldemir, да если еще дальше по ссылке пройти, всё объяснено. Но вы ведь разобрались уже как размер стека увеличить. Раз в вашем камне осталась еще память для кучи, значит и стек можно еще увеличивать.
Вы размер карты на этапе компиляции будете ведь знать - так и задавайте там, чтобы в стеке лежало. Динамическое распределение памяти и malloc() выгодны на ПК, где памяти много и процесс может динамически запрашивать и освобождать память. На МК такую роскошь себе позволить нельзя. Надо понимать, что свопа никто не добавит, когда закончится физическая память. Поэтому буфер должен быть максимально такого размера, сколько может быть данных и хватает памяти. Ротацию данных внутри буфера можно и без динамической памяти устроить.
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Увы и нет. Размер карты выясняется на этапе выполнения (смотреть самый конец сообщения). Но, конечно, я лукавлю. Не нужен мне реально malloc(). Меня интересует метод, как разместить массив в любом месте памяти и с ним комфортно работать. Потому как функция создающая карту использует глобальную переменную для которой статически уже выделена память, затем, эта карта переносится во флеш память для хранения и только потом я из флеш памяти её достаю для отображения. Так что, реально, я могу просто использовать уже выделенный кусок памяти или, хочется научиться использовать данные, которые сохранил во флеш-памяти не вытаскивая оттуда. Ваше предложение создать массив указателей сейчас обдумывается.

Конечно, исходная проблема, как узнать, что размер стека маловат - до сих пор не выяснена. И в той, теме, куда была приведена ссылка, этот вопрос так и не был решен. Была распальцовка, было указание увеличить стек, потом опять распальцовка, а вот как проконтролировать - так и не было сказано. Возможно, это недостаток Кейла, но в нём я так и не нашел репорт, где написано "max stack usage". С другой стороны, если бы Кейл знал это, что ему мешало бы самому выделить под стек необходимую память.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="uldemir",url="/forum/viewtopic.php?p=3763803#p3763803"]Возможно, это недостаток Кейла, но в нём я так и не нашел репорт, где написано "max stack usage".[/uquote]--info=stack
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

Всем добрый вечер. Пытаюсь откомпилировать код, найденный на просторах интернета. Сижу в AtmelStudio. Код для МКонтроллера AVR. МКонтроллер Attiny (малолапчатый)
main.cpp
Спойлер

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

#include <avr/io.h>
#include <avr/interrupt.h>
#include "shiftreg.h"
/* macro definition which returns the number of elements in an arraay */
//#define GetArrayElements(x)	sizeof(x)/sizeof(x[0])

/* 7 Segment Codes */
#define ZERO	0x3F
#define ONE	0x06
#define TWO	0x5B
#define THREE	0x4F
#define FOUR	0x66
#define FIVE 	0x6D
#define SIX	0x7D
#define SEVEN	0x07
#define EIGHT	0x7F
#define NINE	0x6F

int main(void)
{
	//unsigned short counter = 0;
	//unsigned char temp;
	//unsigned char digits[] = {ZERO,ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE};
	//unsigned char display[4];
	SHIFTREG_register reg;
	reg = SHIFTREG_InitRegister(&DDRB, &PORTB, PB0, PB1, PB2);
	sei();
    while (1) {  }
}
shiftreg.h
Спойлер

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

/******************************************************************************
* File Name     : shiftreg.h
* Author        : D.Gotic
* Version       : V0.1
* Date          : 03/12/2010
* Description   : This file contains all the functions prototypes 
*                 and structure definitions for the 74HC595 shit register driver
******************************************************************************/
/* Define to prevent recursive inclusion ------------------------------------*/
#ifndef SHIFTREG_H
#define SHIFTREG_H
/* Includes ------------------------------------------------------------------*/
#include <inttypes.h>
/* a structure which defines the interface  from the uC to the SHIFT REGISTER */
typedef struct _SHIFTREG_register
{
volatile uint8_t *DDR_addr;	/* address of the uC Data Direction Register      */
volatile uint8_t *PORT_addr;	/* address of the uC PORT Register                */
         uint8_t DS_pin;		/* Pin number to which the DS pin is connected 	  */
         uint8_t ST_CP_pin;		/* Pin number to which the ST_CP pin is connected */
         uint8_t SH_CP_pin;		/* Pin number to which the SH_CP pin is connected */
} SHIFTREG_register;
/*	Function prototypes -----------------------------------------------------------*/
SHIFTREG_register SHIFTREG_InitRegister(
volatile uint8_t *ddr_addr,
volatile uint8_t *port_addr,
         uint8_t ds_pin,
         uint8_t st_cp_pin,
         uint8_t sh_cp_pin
);

void SHIFTREG_OutputValue(
SHIFTREG_register *reg,
unsigned char *bytes,
unsigned char nbytes
);

#endif	/* SHIFTREG_H */

/************************** END OF FILE **************************/
shiftreg.c
Спойлер

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

/****************************************************************************
* File Name    : shiftreg.c
* Author       : D.Gotic
* Version      : V0.1
* Date         : 03/12/2010
* Description  : This file contains all the functions definitions 
*                      for the 74HC595 shit register driver 
*****************************************************************************/
/* Includes ----------------------------------------------------------------*/
#include "shiftreg.h"
#include "macros.h"

#define BIT_MASK 0x80

/* Private macros-----------------------------------------------------------*/
/* Private functions -------------------------------------------------------*/
#define shift_in_pulse(port,reg_pin)     sbi(port,reg_pin); cbi(port,reg_pin)
#define parallel_out_pulse(port,reg_pin) sbi(port,reg_pin); cbi(port,reg_pin)
//
// Function Name : SHIFTREG_InitRegister
// Description   : Initializes the interface from the uC to the shift register
// Input         : DDR adress and PORT adress of the interface and pin numbers
//                 of the uC interface
// Return        : initialized register structure 
//
SHIFTREG_register SHIFTREG_InitRegister(
volatile uint8_t *ddr_addr,
volatile uint8_t *port_addr,
         uint8_t ds_pin,
         uint8_t st_cp_pin,
         uint8_t sh_cp_pin)
{
	SHIFTREG_register tmp_reg;
	
	tmp_reg.DDR_addr 		= ddr_addr;
	tmp_reg.PORT_addr 		= port_addr;
	tmp_reg.DS_pin			= ds_pin;
	tmp_reg.ST_CP_pin		= st_cp_pin;
	tmp_reg.SH_CP_pin		= sh_cp_pin;
	
	sbi(*(tmp_reg.DDR_addr),tmp_reg.DS_pin);				
	sbi(*(tmp_reg.DDR_addr),tmp_reg.ST_CP_pin);		
	sbi(*(tmp_reg.DDR_addr),tmp_reg.SH_CP_pin);		

	return tmp_reg;
}
/****************************************************
* Function Name  : SHIFTREG_OutputValue
* Description    : Transmits nbytes bytes to nbytes shift registers and outputs 
*		         : the values
* Input          : shift register structure, bytes to transmit, number of bytes
*		         : to transmit
* Return         : None
******************************************************/
void SHIFTREG_OutputValue(
SHIFTREG_register *reg,
unsigned char *bytes,
unsigned char nbytes )
{	
		unsigned char mask, i, j;

		for (i=0; i<nbytes; i++)
		{
			mask = BIT_MASK;

			for (j = 0; j< 8; j++)
			{
				/* mask bit
				 * if bit 0 output 0
				 * else output 1
				 * shift bit mask one place right */
				if (bytes[i] & mask)
				{
					sbi(*(reg->PORT_addr),reg->DS_pin);
					shift_in_pulse(*(reg->PORT_addr),reg->SH_CP_pin);
				}
				else
				{
					cbi(*(reg->PORT_addr),reg->DS_pin);
					shift_in_pulse(*(reg->PORT_addr),reg->SH_CP_pin);
				}
				mask = (mask >> 1);
			}
		}
		parallel_out_pulse(*(reg->PORT_addr),reg->ST_CP_pin);
}
/***********************END OF FILE***********************/
macros.h
Спойлер

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

/*************************************************************************
* File Name   : shiftreg.h
* Author      : D.Gotic
* Version     : V0.1
* Date        : 03/12/2010
* Description : Helper macros for setting and clearing a bit in a register
**************************************************************************/
#ifndef MACROS_H
#define MACROS_H
#define cbi(addr,bit)	addr &= ~(1 << bit)
#define sbi(addr,bit)	addr |= (1 << bit)
#endif	/* MACROS_H */
/****************************END OF FILE**********************************/
В данном случае хочу разобраться в структурах, типах передаваемых данных, ссылках и указателях в аргументах и параметрах функции.
При компиляции в AtmelStudio ошибка:
Error undefined reference to
"SHIFTREG_InitRegister(unsigned char volatile*, unsigned char volatile*, unsigned char, unsigned char, unsigned char)"
Ошибка неопределенной ссылки на ...

Фрагмент кода с прототипом функции

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

/* ----------------- Function prototypes ------------------------------------------------*/
SHIFTREG_register SHIFTREG_InitRegister(volatile uint8_t *ddr_addr, volatile uint8_t *port_addr,uint8_t ds_pin, uint8_t st_cp_pin, uint8_t sh_cp_pin);
В функцию необходимо передать в качестве параметров DDRB, PORTB, PB0, PB1, PB3 (порт и пины к которым подключается регистр 74HC595)
ErrorList.png
ErrorList
(17.29 КБ) 220 скачиваний
Attinu_74HC595.png
(20.23 КБ) 232 скачивания
И что за unsigned char - ясно же сказано uint8_t
Может быть преобразование типов в компиляторе происходит не корректно? :dont_know:
Ссылка -> Подобная ошибка, но машинный перевод
P.S. Аксиома "Код, скачаный из интернета, никогда сразу не работает"
Последний раз редактировалось Эйлер Леонард Сб дек 28, 2019 22:45:29, всего редактировалось 2 раза.
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

unsigned char и uint8_t - одно и то же.

undefined reference - функция определена в файле shiftreg.c, а раз такая ошибка - то его, похоже, забыли добавить в список для компиляции.
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

Нет, все файлы подключены.
Файлы проекта ....
2019-12-29_004423.png
(20.08 КБ) 263 скачивания
Первоначально файл shiftreg был типом .C , а у меня проект как CPP. Изменил тип файла на CPP и вроде бы как скомпилировалось без ошибок.
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

У С и С++ различаются способы подключения хидер-файлов. Я в этом не эксперт, просто сам нарвался, когда хотел править ардуиновский скетч...
Вот пример хидер-файла:

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

#ifdef __cplusplus
extern "C" {
#endif

int sumI(int a, int b);
float sumF(float a, float b);

#ifdef __cplusplus
} // end extern "C"
#endif
Эти ifdef/endif разделяют способ, как компиляторы его будут видеть.
компилятор C:

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

int sumI(int a, int b);
float sumF(float a, float b);
компилятор C++ :

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

extern "C" {

int sumI(int a, int b);
float sumF(float a, float b);

} // end extern "C"
Т.е. main.cpp должен видеть второй вариант.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

ОК! Всё фурычит.
Test-30(1)_74HC595.png
Тестирование 74HC595 (счетчик)
(35.8 КБ) 261 скачивание
Поправил main.cpp
Спойлер

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

#include <avr/io.h>
#include <avr/interrupt.h>
#include "shiftreg.h"
/* macro definition which returns the number of elements in an arraay */
#define GetArrayElements(x)	sizeof(x)/sizeof(x[0])

#define Prescaler_No   (1<<CS00) //No prescaling)
#define Prescaler_8    (1<<CS01)
#define Prescaler_64   (1<<CS01)|(1<<CS00)
#define Prescaler_256  (1<<CS02)
#define Prescaler_1024 (1<<CS00)|(1<<CS02);

/* 7 Segment Codes */
#define ZERO	0x3F
#define ONE		0x06
#define TWO	    0x5B
#define THREE	0x4F
#define FOUR	0x66
#define FIVE 	0x6D
#define SIX		0x7D
#define SEVEN	0x07
#define EIGHT	0x7F
#define NINE	0x6F

volatile uint8_t increment_counter = 0;

ISR(TIM0_COMPA_vect)
{
	cli();
	increment_counter = 1;
	sei();
}

int main(void)
{	
	unsigned short counter = 0;
	unsigned char temp;
	unsigned char digits[] = {ZERO,ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE};
	unsigned char display[4];
	
	SHIFTREG_register reg;
	
	TCNT0 = 0; //Очищаем счетный регистр (на ваякий случай)
	OCR0A = (256-1)-0;//Регистр сравнения, (256-1)-число
	TCCR0A = (1<<WGM01);// Сброс при совпадении.
	TIFR0 = (1<<OCF0A); // Регистр флагов прерываний таймера счетчика
	TIMSK0 = (1<<OCIE0A); //Разрешение прерывания по совпадению таймера/счётчика 0A
	TCCR0B = Prescaler_No;// Делитель частоты
//	                                           ds_pin,st_cp_pin,sh_cp_pin
	reg = SHIFTREG_InitRegister(&DDRB, &PORTB, PB0,   PB1,      PB2);
	sei();
    while (1) {
		
if(increment_counter)
{
++counter;
if(counter > 9999){	counter = 0; }
increment_counter = 0;
}
		temp	   =  counter / 1000;
		display[0] =  digits[temp];
		temp	   =  (counter / 100) % 10;
		display[1] =  digits[temp];
		temp	   =  (counter / 10)  % 10;
		display[2] =  digits[temp];
		temp	   =  counter % 10;
		display[3] =  digits[temp];	
	
	SHIFTREG_OutputValue(&reg,display,GetArrayElements(display));
	}
return 0;
}
Ответить

Вернуться в «Разные вопросы по МК»