pliss

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

202 сообщения в этой теме

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

/*
 * 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;

 

Поделиться сообщением


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

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

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

  Разрешено не более 75 смайлов.

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

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

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

Загрузка...

  • Похожие публикации

    • Автор: zhukkey
      Всем привет.
      Решил собрать свою переносную колонку но не знаю как это сделать.
      У меня есть два динамика от JetBalance JB-631. Мощность колонок 15 Вт.
      Хочу сделать коробку с двумя динамиками и как понял надо еще плату и аккумулятор (помогите еще разобраться для таких колонок лучше от 220v питать или можно аккум сделать). Помогите в это всем разобраться. Может уже есть такие гайды скиньте сюда или объясните.   
    • Автор: abr_avr
      Добрый день!
      Программирую в Arduino IDE, программатор Arduino ISP, других к сожалению нету.
      Решил поменять скорость работы контроллера ATTiny13A при помощи смены fuse. Менял через Arduino IDE, которая подставила такую команду
      C:\Program Files\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files\Arduino\hardware\tools\avr/etc/avrdude.conf -v -v -pattiny13 -cstk500v1 -PCOM3 -b19200 -e -Uhfuse:w:0xFF:m -Ulfuse:w:0x7b:m После чего достучатся до контроллера теперь никак не могу. Вот, что пишет avrdude: 
      avrdude: Version 6.3, compiled on Dec 16 2016 at 13:33:19 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch System wide configuration file is "C:\Program Files\Arduino\hardware\tools\avr/etc/avrdude.conf" Using Port : COM3 Using Programmer : stk500v1 Overriding Baud Rate : 19200 AVR Part : ATtiny13 Chip Erase delay : 4000 us PAGEL : P00 BS2 : P00 RESET disposition : dedicated RETRY pulse : SCK serial program mode : yes parallel program mode : yes Timeout : 200 StabDelay : 100 CmdexeDelay : 25 SyncLoops : 32 ByteDelay : 0 PollIndex : 3 PollValue : 0x53 Memory Detail : Block Poll Page Polled Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- eeprom 65 5 4 0 no 64 4 0 4000 4000 0xff 0xff flash 65 6 32 0 yes 1024 32 32 4500 4500 0xff 0xff signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00 lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 calibration 0 0 0 0 no 2 0 0 0 0 0x00 0x00 lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 Programmer Type : STK500 Description : Atmel STK500 Version 1.x firmware Hardware Version: 2 Firmware Version: 1.18 Topcard : Unknown Vtarget : 0.0 V Varef : 0.0 V Oscillator : Off SCK period : 0.1 us avrdude: PAGEL and BS2 signals not defined in the configuration file for part ATtiny13, using dummy values avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.01s avrdude: Device signature = 0x000000 (retrying) Reading | ################################################## | 100% 0.02s avrdude: Device signature = 0x000000 (retrying) Ошибка при записи загрузчика. Reading | ################################################## | 100% 0.01s avrdude: Device signature = 0x000000 avrdude: Yikes! Invalid device signature. Double check connections and try again, or use -F to override this check. avrdude done. Thank you. Опция -F, которую предлагает avrdude, не помогает. Пробовал менять битрейт (опция -b), но в таком случае выдаёт ошибку stk500_getsync, что обычно бывает, если битрейт выбран неправильно.
      Судя по фьюзам http://www.engbedded.com/fusecalc/, я просто убрал CKDIV8, что должно ускорить внутренний таймер в 8 раз, и убрал флаг CKSEL0, что вместе со снятым CKSEL1 устанавливает частоту контроллера в 128 КГц (вместо заводских 9.6 МГц). Вобще ничего не говорит о том, что контроллер залочился. Приконнекчен к программатору по такой схеме

      Причём, до замены фьюзов работало и без кондёра. А после не работает и с ним.
      Что можно попробовать? Можно ли вернуть контроллер к заводским настройкам и как вобще поменять внутреннюю скорость таймера без таких вот багов?
    • Автор: daiver
      Добрый день, возникла неприятная проблема с фьюзами. Первоначаль у меня была схема с контроллером AtMega8 с кварцевым резонатором на 16Mhz. Мне пришлось сменить Atmega8 на Atmega168. Но тут возникла проблема с прошивкой. Первоначально фьюзы CKSEL3..0 были выставлены в 0010. то есть частота от внутреннего источника. С помощью Uniprof я прошил эти фьюзы на 0101. Теперь контроллер не откликается и не работает. Умер... соответственно фьзы обратно прошить не могу.
      Программатор Громмова, чтобы прошить я вытаскиваю контроллер из моей сзхемы и вставляю в программатор, кварцевого резонатора в программаторе нет.
      Можно ли реанимировать устройство?
    • Автор: Wabbs_2016
      Доброго Всем! Выяснилась проблема при дебаггинге в Atmel Studio 7, пропала желтая стрелочка отслеживающая положение дебаггера.
    • Гость Иван
      Автор: Гость Иван
      Собирая данную игрушку http://cxem.net/avto...onics/4-127.php
      я наткнулся на следующую проблему:
      программатор Pic k150
      МК Pic16f628
      устанавливаю на ЗИФку программатора как показанно на рисунке в окне программы DIY K150
      Нажимаю "Program"
      МК шьется, но в конце вылезает алерт "Error"

      Фьюзы ни как не настраивал... как я понял при настройке "Auto Updata Files" фьюзы автоматически выставляются, согласно предуставновкам в прошивке

      при нажатии на кнопку "Fuses" появляется следующее окно (из него я как раз и понял, что описал выше про Auto Updata Files)

      В итоге я имею прошитый МК, но схема работает не правильно
      Правильный алгоритм
      А у меня при коротком нажатии ничего не происходит.... при длительном (через 1.5 - 2 сек.)
      КН1 - крякалка,
      КН2 - Сирена № 1 , при следующем тоже Сирена № 1
      КН3 - окончание сирены
      пока удерживаю кнопки... как только кнопку отпустишь, звук пропадает
      связанно ли это свыше описанной ошибкой и как с ней бороться?
      другие прошивки на 16F628 - программатор шьет на ура
      Программатор покупной