pliss

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

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

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

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

 

0

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


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

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

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

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

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

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

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

Загрузка...

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

    • Автор: 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, пропала желтая стрелочка отслеживающая положение дебаггера.
    • A
      Автор: Гость Иван
      Собирая данную игрушку 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 - программатор шьет на ура
      Программатор покупной
    • Автор: Dmitriy_2214
      Всем привет!
      Ну, кто тут начинает осваивать AVRки?
      Тогда вам просто необходимо обезопасить себя от первых неудачных экспериментов с фьюзами.
      Представляю свою версию Atmega fusebit doctor

      Есть несколько собранных экземпляров. Небольшая платка в SMD + разноцветный шлейф с подписанными пинами. Также есть адаптеры для подключения контроллеров в DIP и TQFP корпусах. Всё проверено, работает.
      Цена устройства 800р.
      Москва, доставка в регионы почтой и транспортными компаниями.
      Пишите в личку либо на dklab24(гав)gmail.com
  • Сообщения

    • ему "эти" помогали
    • Кто ни будь пробовал для плавного пуска вместо реле что то типа MOC3063 + mac15-10 ?
    • Большое спасибо за ответы дорогие форумчане. Но боюсь на осваивание темы компараторов и транзисторов у меня уйдет куча времени. А его у меня последнее время крайний дефицит. Я прошу вас набросать готовую схемку хоть на транзисторах, хоть на компараторе, большой разницы нет.  Тема почти автомобильная, точнее зажигание двухтактного двигателя скутера 20 лет назад снятого с производства. Оригинальных запчастей на него нет и не будет, приходится прикручивать то что  есть. Беда в том что на этом скутере итальянцы поэксперементировали один раз - получилось достаточно компактно но не надежно и на других моделях такую схему больше нигде не использовали. Сопротивление обмотки датчика положения с которого идет импульс 600 ом, Максимальное число оборотов 14000 об/мин. На оборотах выше 3000 отрицательные импульсы начинают выпрыгивать в плюсовую сторону до 0.5v, соответственно  порог срабатывания надо подобрать 0.7- 0.8v Готов отблагодарить материально за практическую помощь.
    • не думаю, что у кого-то хватит "УМА" на ЭТО Он и даром как изделие никому не нужен!
    • Нарисовал схемы кодера, декодера и регуля. Кодер согласно ссылке Жмяк  ,Согласно усовершенствованию автора добавлены подстроечники, их попробую поменьше купить, а то эти огромные. Три пина слева- для передатчика, воткну пока самый дешевый и наверное самый бородатый китайские передатчик и приемник (комплект на 315Мгц) Декодер по ссылке Жмяк с некоторыми доработками, питание 5В, резистор светодиода 330 Ом и по все выходам поставил токоограничивающие по 300 Ом, вычитал что максимальный ток порта 20мА, с резисторами должен быть не более 16,6мА, вроде запас есть. 4 отдельных пина- для приемника Регулятор по ссылке тык . Плечи моста не симметричные, ибо в одну сторону двигаться будет всяко больше модель, чем в другую, значит на одном плече сэкономим. Мосфеты P и N канальные, в Dpack корпусе(или ТО252, вроде так). Вместо управляющего P-мосфетами полевика воткнул биполярник мелкий(sot23), должно хватить с током коллектора макс 0,15А. Расположение деталей с двух сторон будет, на мосфеты если что удобно будет радиатор приспособить, дорожки может потом еще проводом утолщу, по калькуляторам ширина маловата (раза в два). Резистор на 1кОм не стал оставлять как в исходной схеме, раз на выходе приемника уже стоят токоограничивающие, то счел здесь ненужным еще один (может не прав). И конденсатор по питанию электролит на 100 мкФ, т.к. своего стабилизатора до 5В не предусматриваю на регуле, питание для мк браться будет с приемника, а там уже толстый стаб стоит. Размер плат, кроме регуля, устраивает вполне. Регуль большой получился, но меньше делать не умею, возможны ошибки в правильности разводки плат. Если кого заинтересовало, то вот еще спринт файл плат, там по вкладкам, как в экселе, все три платы. Принципиальные схемы рисовать отдельно лень, все элементы и так подписаны   Передатчик.lay6
    • Если отсоединить шлейф, то всё получится.
    • у меня пока несколько вопросов осталось ) 1. Я заметно убрал вторую гармонику и добился вполне хорошего показателя - от 0,04% THD. Вернулся в начало темы, посмотрел показатели Василича... Не, ну это фантастика. Хотя, возможно, если убрать фон максимально и понять, как убрать 3-ю гармонику, плюс учесть, что искажения вносятся реверсом - обратным корректором и на компе звуковой картой, так как сам комп вносит ооочень много своих шумов, что слышно при подключении наушников в параллель с фоником ко входу ЗК (уши 150 Омов - ну очень чувствительны ко всему). Собственно, вопрос - каковы варианты убрать 3-ю, самую противную, гармонику? Я даже вторую опустил ниже её. И, судя по тому, что в одном канале она ещё в два раза ниже, чем в другом, то можно и ещё опустить. Но третья остаётся как вкопанная. И всегда равна по каналам. И только ну очнеь большое увеличение 2-й начинает поднимать 3-ю. Но после какого-го момента борьбы со второй, 3-я замирает и всё. Что на неё влияет, что можно покрутить? 2. Возможно фон, как он указан выше, и правда есть. Вспомнилось, что я как-то делал оцифровку (https://yadi.sk/d/R2jzx3hc3JokBd) своим корректором и брендовым от АТ: первопресса Wall: И получил такой вот отзыв: Не об это ли лишнем нч-гуле говориться? (( эх (( Вроде бы петель не делаю по земле, придерживаюсь в этом плане рекомендаций Василича (вроде бы )))),а откуда 50Гц в таком количестве, не знаю (   Да, по THD надо будет попробовать 1кгц пустить с компа точно такого же уровня по амплитуде, как и при измерениях в RMAA, и тогда посмотреть на THD осциллографом.