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

С нуля Программирование AVR Купил программатор и Контроллер Что дальше...


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

Скрытый текст

/*
 * ARV_PWM_array_ind.c
 *
 * Created: 22.03.2017 17:27:48
 */ 

#include <avr/io.h>
#define F_CPU 8000000UL

#define _0 (0b11000000)							/*(0b00111111)*/
#define _1 (0b11111001)							/*(0b00000110)*/
#define _2 (0b10100100)							/*(0b01011011)*/
#define _3 (0b10110000)							/*(0b01001111)*/
#define _4 (0b10011001)							/*(0b01100110)*/
#define _5 (0b10010010)							/*(0b01101101)*/
#define _6 (0b10000010)							/*(0b01111101)*/
#define _7 (0b11111000)							/*(0b00000111)*/
#define _8 (0b10000000)							/*(0b01111111)*/
#define _9 (0b10010000)							/*(0b01101111)*/

 #define BTN_UP_0 (0b11111110)				/*нажата кнопка "+" нулевого канала*/
#define BTN_DWN_0 (0b11111101)				/*нажата кнопка "-" нулевого канала*/	    
 #define BTN_UP_1 (0b11111011)				/*нажата кнопка "+" первого канала*/
#define BTN_DWN_1 (0b11110111)				/*нажата кнопка "-" первого канала*/
 #define BTN_UP_2 (0b11101111)				/*нажата кнопка "+" второго канала*/
#define BTN_DWN_2 (0b11011111)				/*нажата кнопка "-" второго канала*/
#define ENABLE (PINB == 0b11111111)			/*все кнопки отпущены*/
#define CHECK_BTN (0b11110000)				/*количество периодов проверки */
#define NEXT (1)
#define PREV (-1)
#define WIDTH_PWM_MAX (44)
#define WIDTH_PWM_MIN (0)
#define NUMBER_IND (0b00000110)				/* общее число разрядов индикации || число каналов Pwm * 2  */
#define IND_TENS_PWM_0 (0b00000001)			/*  индицируемый разряд индикаторами	*/
#define IND_ONES_PWM_0 (0b00000010)
#define IND_TENS_PWM_1 (0b00000100)
#define IND_ONES_PWM_1 (0b00001000)
#define IND_TENS_PWM_2 (0b00010000)
#define IND_ONES_PWM_2 (0b00100000)
//массив ширин Pwm (округлённая геометрическая прогрессия со знаменателем ~1.1)
 unsigned char width_Pwm[45] = {
	0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,18,19,21,24,26,28,31,34,38,42,46,50,55,61,67,74,81,89,98,108,119,131,144,158,174,192,211,232,255
	};		

void change_width_Pwm(unsigned char *b, const int a, const char c, const char d)
{				
	if(c == *b)	//	переход через минимум или максимум ширины
	
	{
		*b = d;
		}
		
    else
        
    {
    	*b += a;
        }
	}
											//массив единиц индикации
unsigned char ind_width_ones_Pwm[46] = {
_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_0,_1,_2,_3,_4,_0
};
											//массив десятков индикации
unsigned char ind_width_tens_Pwm[45] = {
_0,_0,_0,_0,_0,_0,_0,_0,_0,_0,_1,_1,_1,_1,_1,_1,_1,_1,_1,_1,_2,_2,_2,_2,_2,_2,_2,_2,_2,_2,_3,_3,_3,_3,_3,_3,_3,_3,_3,_3,_4,_4,_4,_4,_4
};
											//изменение индикации		
void change_ind_Pwm(unsigned char *tens, unsigned char *ones, unsigned char i_width_Pwm)
{			
	*ones = i_width_Pwm;			//индикация равна индексу ширины pwm
	*tens = i_width_Pwm;
	}
											//индикация
void ind_Pwm(unsigned char ind_width_Pwm[], unsigned char *ind)
{
	PORTA = ind_width_Pwm[*ind];
	}

int main()

{
	  DDRA = 0xFF;
	 PORTA = 0x00;

	  DDRB = 0x00;
	 PORTB = 0xFF;

      DDRC = 0xFF;
	 PORTC = 0x00;

	  DDRD = 0xFF;
	 PORTD = 0xFF;

register unsigned char state_Button = 0;	//состояние кнопок
register unsigned char counter_Button = 0;	//счётчик состояния кнопок	
		 unsigned char ind_Ones_0 = 0;		//индекс индикации десятков Pwm 0
		 unsigned char ind_Tens_0 = 0;		//индекс индикации единиц Pwm 0
		 unsigned char ind_Ones_1 = 0;
		 unsigned char ind_Tens_1 = 0;
	     unsigned char ind_Ones_2 = 0;
		 unsigned char ind_Tens_2 = 0;
		 unsigned char width_Pwm_0 = 0;		//индекс ширины Pwm 0
		 unsigned char width_Pwm_1 = 0;
		 unsigned char width_Pwm_2 = 0;										
register unsigned char counter_Pwm = 0;		//счётчик ширины pwm	
register unsigned char counter_ind_Pwm = 0;			//счётчик индикации
	     unsigned char enable_change_Pwm = 1;		//разрешение изменения pwm   
register unsigned char ind_state_Pwm = 0b00000010;	// счётчик динамической индикации
	 
	while(1)

	{	
		register unsigned char state_Pwm;							//состояние Pwm

		state_Pwm = ((1 << PORTD0) | (1 << PORTD1)| (1 << PORTD2));	//включаем 
		  
		if(counter_Pwm >= width_Pwm[width_Pwm_0])					//проверяем
		
		{
			state_Pwm &= (~(1 << PORTD0));							//готовимся погасить pwm_1
			}			
		
		if(counter_Pwm >= width_Pwm[width_Pwm_1])

		{
			state_Pwm &= (~(1 << PORTD1));
			}		
		
		if(counter_Pwm >= width_Pwm[width_Pwm_2])

		{
			state_Pwm &= (~(1 << PORTD2));										
			}
		 
		PORTD = state_Pwm;								//устанавливаем pwm_0, pwm_1 и pwm_2
		
		counter_Pwm ++;									//считаем ширину Pwm														    		
		if(counter_Pwm == 0)									//каждый период pwm
	
		{
//======================================динамическая индикация==================================
			counter_ind_Pwm ++;						//считаем индикацию

			if(counter_ind_Pwm == NUMBER_IND)										
			
			{
				counter_ind_Pwm = 0;
				}

			ind_state_Pwm = (1 << counter_ind_Pwm);	//последовательно мигаем индикаторами					
			PORTC = ind_state_Pwm;														
			switch(ind_state_Pwm)		
			
			{
				case IND_TENS_PWM_0 : ind_Pwm(ind_width_tens_Pwm, &ind_Tens_0);//выводим десятки
				break;
				case IND_ONES_PWM_0 : ind_Pwm(ind_width_ones_Pwm, &ind_Ones_0);//единицы
				break;
				case IND_TENS_PWM_1 : ind_Pwm(ind_width_tens_Pwm, &ind_Tens_1);
				break;
				case IND_ONES_PWM_1 : ind_Pwm(ind_width_ones_Pwm, &ind_Ones_1);
				break;
				case IND_TENS_PWM_2 : ind_Pwm(ind_width_tens_Pwm, &ind_Tens_2);
				break;
				case IND_ONES_PWM_2 : ind_Pwm(ind_width_ones_Pwm, &ind_Ones_2);
				break;
				} 
//==================================================антидребезг нажатия==========================			    
			state_Button = PINB;				//запоминаем состояние кнопок
			counter_Button ++;
			}

		if(counter_Button & CHECK_BTN)			//через CHECK_BTN периодов (антидребезг нажатия)
	
		{
			counter_Button = 0;						//сбрасываем счётчик кнопок
			if(state_Button == PINB)				//если состояние кнопок совпадает
		
			{
				if(enable_change_Pwm)				//если разрешено изменение		
				
				{						
					enable_change_Pwm = 0;									//сбрасываем разрешение
//=========================================обработка кнопок=========================================
					switch(state_Button)

					{
						case BTN_UP_0 : change_width_Pwm(&width_Pwm_0, NEXT, WIDTH_PWM_MAX, WIDTH_PWM_MIN);//увеличиваем ширину
										change_ind_Pwm(&ind_Tens_0, &ind_Ones_0, width_Pwm_0); //увеличиваем индикацию
						break;
						case BTN_DWN_0 : change_width_Pwm(&width_Pwm_0, PREV, WIDTH_PWM_MIN, WIDTH_PWM_MAX);//уменьшаем ширину
										 change_ind_Pwm(&ind_Tens_0, &ind_Ones_0, width_Pwm_0); //уменьшаем индикацию
						break;												
						case BTN_UP_1 : change_width_Pwm(&width_Pwm_1, NEXT, WIDTH_PWM_MAX, WIDTH_PWM_MIN);
										change_ind_Pwm(&ind_Tens_1, &ind_Ones_1, width_Pwm_1);		
						break;					
						case BTN_DWN_1 : change_width_Pwm(&width_Pwm_1, PREV, WIDTH_PWM_MIN, WIDTH_PWM_MAX);
										 change_ind_Pwm(&ind_Tens_1, &ind_Ones_1, width_Pwm_1);
						break;
						case BTN_UP_2 : change_width_Pwm(&width_Pwm_2, NEXT, WIDTH_PWM_MAX, WIDTH_PWM_MIN);
										change_ind_Pwm(&ind_Tens_2, &ind_Ones_2, width_Pwm_2);
						break;
						case BTN_DWN_2 : change_width_Pwm(&width_Pwm_2, PREV, WIDTH_PWM_MIN, WIDTH_PWM_MAX);
										 change_ind_Pwm(&ind_Tens_2, &ind_Ones_2, width_Pwm_2);
						break;
						}
//==================================================================================================
					}
				}
			}
//========================================антидребезг отпускания====================================
		state_Button = PINB;									//запоминаем состояние кнопок
		counter_Button ++;
		if(counter_Button & CHECK_BTN)									    //через CHECK_BTN периодов

		{
			counter_Button = 0;												//сбрасываем счётчик кнопок
			if(ENABLE)
		
			{	
				enable_change_Pwm = 1;    //если кнопки не нажаты (отпущены после нажатия и обработки) разрешаем изменения ширины
				}
			}
		}
	}

 

Вот это можно более вменяемо записать?..

void change_width_Pwm(unsigned char *b, const int a, const char c, const char d)
{				
	if(c == *b)//	переход через минимум или максимум ширины
	
	{
		*b = d;
		}
		
    else
        
    {
    	*b += a;
        }
	}

/////////////////////////////////////////////

case BTN_UP_0 : change_width_Pwm(&width_Pwm_0, NEXT, WIDTH_PWM_MAX, WIDTH_PWM_MIN);//увеличиваем ширину
				change_ind_Pwm(&ind_Tens_0, &ind_Ones_0, width_Pwm_0); //увеличиваем индикацию
break;
case BTN_DWN_0 : change_width_Pwm(&width_Pwm_0, PREV, WIDTH_PWM_MIN, WIDTH_PWM_MAX);//уменьшаем ширину
				change_ind_Pwm(&ind_Tens_0, &ind_Ones_0, width_Pwm_0); //уменьшаем индикацию
break;

 

Пионер - всем ребятам пример.

There should be information on the web about this, but it may take some digging.

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

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

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

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

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

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

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

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

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

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

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

  • Сообщения

    • Привет.  Хочу попробовать поработать с фоторезистом. Есть пару десятков ультрафиолетовых светодиодов, общей мощностью 4 вата. Хватит ли этой мощности для обработки платок размером 10 на 10 см или надо искать что-то дополнительно? 
    • Чтобы меньше было излучения, нужно мотать тороидальную. Возможно для повышения добротности по омическому сопротивлению лучше этот ТОР мотать в пару слоев. Если ее намотать на шило, то она вряд ли будет вообще работать как катушка.   Индуктивность прямо пропорциональна площади сечения, которая в свою очередь прямо пропорциональна квадрату диаметра. К тому же индуктивность в обратной пропорции с длиной намотки.
    • Я в ходе отладки выяснил, что сбоит в функции:  void w25qWritingByUSB(uint32_t dpagenum, uint8_t *bufByUSB) При чем поведение очень странное. Отладочные сообщения даже не выводятся в начале функции. В ходе экспериментов понял что связано это с объявлением массивов и решил объявить большие буферы которые на 4КБ и 0.25КБ: uint8_t current_sector_buf[4096]; uint8_t buf[256]; глобально. В оригинале, буферы объявлялись локально в функции. После изменения буквально двух строчек кода, все заработало. Также, в оригинальном проекте было сильно напутано из функциями. Я решил функции выкинуть из main.c и вставить в w25q.c Эти функции: void w25qEraseSector(uint16_t sector) void w25qWritingByUSB(uint32_t dpagenum, uint8_t *bufByUSB) Поиск данной проблемы реально отобрало кучу времени. На будущее буду знать что и такое бывает...
    • есть готовый  драйвер BTS7960 до 43А (долговременно до 10) с шим и все, что нужно и стоит недорого. И не надо изобретать  велосипед. Даже с учетом завышения параметров  уж 5А свободно.
    • А есть внятное описание этого M18? По моему он не очень "интегирируется" с микроконтроллером, да и нужно ли? По схеме выше - подключить его к U1C, выход U1C кинуть на +С12, U1D вообще выкинуть вместе с D1,D2 и R13.
    • Прежде чем сломя голову что-либо менять, следует задуматься о причинах выхода этого "чего-либо" из строя. В противном случае замененное отправится протоптанной тропой своих предшественников. Защитной лампой пользоваться умеете? Вот на нее и заменяйте для начала.
    • Это обрывные резисторы в роли предохранителей. Номинал на последнем фото похож на 470 Ом (желтый-фиолетовый-коричневый-золотой, если цвета правильно разглядел), но это многовато, вот 47 Ом - похоже на правду. Можно ставить в достаточно широком диапазоне, другое дело, что горят они не просто так. Скорее всего дальше где-то косяк. А мультиметром измеряли сопротивление? Что показывает?
  • Похожий контент

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