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

С нуля Программирование 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 пользователей онлайн

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

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