Вс дек 19, 2010 14:18:57
#include <mega16.h>
#include <m8_128.h>
#include <delay.h>
#include <stdio.h>
char pwm = 0; // Величина ШИМ начальная PWM в %
u32 pwm_val; // для хранения величины ШИМ PWM в 1/1024
void main(void)
{
PORTA=0x00; DDRA=0x00;
PORTB=0x00; DDRB=0x00;
PORTC=0x00; DDRC=0x00;
PORTD=0x00; DDRD=0x30;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0xA3;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH = 0x00; // PWM(PD4) OCR1B / 10.23 (%)
OCR1BL = 0xFF; // PWM(PD4) 255 / 10.23 = 24.9 (%)
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
MCUCSR=0x00;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;
while (1){
if (pwm > 102) { //если ШИМ уже более 100 %
pwm = 0; // обнулить величину ШИМ
};
pwm_val = ((1023 * (u32)pwm)/100);
// pwm_val - это число от 0 до 1023
// PWM(PD5) = OCR1A / 10.23 (%)
OCR1AH = (char)(pwm_val>>8);
OCR1AL = (char)pwm_val;
if(PINA.0==1){
pwm += 10; //увеличим ШИМ на 10%
}
delay_ms(20); // пауза
};
}
OCR1BH = 0x00; // PWM(PD4) OCR1B / 10.23 (%)
OCR1BL = 0xFF; // PWM(PD4) 255 / 10.23 = 24.9 (%)
Пн дек 20, 2010 00:43:21
Пн дек 20, 2010 12:51:08
unsigned char b;
void pow (unsigned char port0,unsigned char port1,unsigned char port2,unsigned char port3)
{
if ( TCNT1>port0)PORTB.0 =0;
else PORTB.0 =1;
if ( TCNT1>port1)PORTB.1 =0;
else PORTB.1 =1;
if ( TCNT1>port2)PORTB.2 =0;
else PORTB.2 =1;
if ( TCNT1>port3)PORTB.3 =0;
else PORTB.3 =1;
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
}
.
.
.
while (1)
{
pow(20, 40, 60, 78);
};
Ср дек 22, 2010 00:45:49
Ср дек 22, 2010 01:25:11
void B1_SUB(void)
{
if ((PIND&(1<<6))==0) //на порте D6 висит кнопка, проверяем нажата ли
__{
____B1++;//инкремент переменной подсчета кол-ва периодов нажатия
____ if (B1==B1_N)//если продержали долгое время и переменная дошла до необходимого значения
_____{
______B1_PUSHED=1;//выставляем флаг нажатой кнопки
______MODE=1;//выполняем действие по нажатию кнопки (у меня 2 команды)
______MODE_CHGD=1;
_____}
__}
else//если кнопка не нажата, очищаем переменную подсчета кол-ва периодов нажатия
B1=0;
if(B1_PUSHED)//теперь проверяем флаг нажатой кнопки, он означает что была нажата кнопка и было выполнено действие по нажатию
__{
___B1=0;//если он установлен (кнопка была нажата и действие по нажатию уже было выполнено), очищаем переменную подсчета кол-ва периодов нажатия
___if(PIND&(1<<6)) //теперь, если она уже отпущена
____{
_____B1_PUSHED=0; //очищаем флаг нажатой кнопки
_____MODE=0;//и выполняем действие по отпусканию кнопки (у меня их 2)
_____MODE_CHGD=1;
____}
__}
}
//вставлять действия "по отпускании" и "по нажатию" по Вашему усмотрению, можно одно исключить
//эта программа должна вызываться по таймеру либо в главном цикле вертеться
//число B1_N рассчитывается исходя из максимального времени дребезга контактов, Tдр.
//B1_N = Tдр.* Tвыз., время в одинаковых единицах. Tвыз. - период вызова функции.
Пт сен 23, 2011 16:57:12
Пн янв 16, 2012 04:37:19
#include <ioavr.h>
#include <intrinsics.h>
#include <stdlib.h>
int interval = 200;
int delitel = 5;
int effect = 0;
void delay(long unsigned int Pause)
{
long int i;
long int i2;
i2=Pause*100;
for(i=0; i<i2; ++i )
asm("nop");
}
int main( void )
{
__enable_interrupt();
char del;
int i;
PORTB = 0xFF;
DDRB = 0xFF;
PORTD = 0xFF;
DDRD = 0x00;
/* if (PIND == 0x01)
// if((PIND &(1<<0))==0) ;// если нажата pd3 на корпус
{
interval = interval - 200;
}
if (PIND == 0x02)
{
delitel++;
}
if (PIND == 0x04)
{
delitel--;
}
if (PIND == 0x08)
{
interval = interval + 200;
}
//if (PIND == 0x10)
if((PIND &(1<<PINd.bit4))==1) ;// если нажата pd3 на корпус
{
effect++;
if (effect > 4) effect = 0;
}*/
if (PIND != 0)
//if ((PIND & (1<<4))==1)
{
delay(50);
effect++;
if (effect >4) effect=0;
};
switch(effect)
{
case 0: PORTB=0x00;
break;
case 1:
PORTB=0xFF;
break;
case 2:
PORTB=0xFF;
del = 5 / delitel;
i = interval * del ;
delay(i);
PORTB=0x00;
i = interval * (1/del);
delay(i);
break;
case 3:
PORTB=0xFF;
delay(1<<interval);
PORTB=0x00;
delay(1>>interval);
break;
}
return 0;
}
Пн янв 16, 2012 06:50:41
Пн янв 16, 2012 13:20:17
int main( void )
{
__enable_interrupt();
char del;
int i;
PORTB = 0xFF;
DDRB = 0xFF;
PORTD = 0xFF;
DDRD = 0x00;
while(1)
{
/* if (PIND == 0x01)
// if((PIND &(1<<0))==0) ;// если нажата pd3 на корпус
{
interval = interval - 200;
}
if (PIND == 0x02)
{
delitel++;
}
if (PIND == 0x04)
{
delitel--;
}
if (PIND == 0x08)
{
interval = interval + 200;
}
//if (PIND == 0x10)
{
effect++;
if (effect > 4) effect = 0;
}*/
if ((PIND & (1<<4))==1)
{
delay(50);
effect++;
if (effect >4) effect=0;
};
switch(effect)
{
case 0: PORTB=0x00;
break;
case 1:
PORTB=0xFF;
break;
case 2:
PORTB=0xFF;
del = 5 / delitel;
i = interval * del ;
delay(i);
PORTB=0x00;
i = interval * (1/del);
delay(i);
break;
case 3:
PORTB=0xFF;
delay(1<<interval);
PORTB=0x00;
delay(1>>interval);
break;
}
}
return 0;
}
Пн янв 16, 2012 13:27:50
if ((PIND & (1<<4))==1)
{
delay(50);
effect++;
if (effect >4) effect=0;
};
if (PIND & (1<<4))
{
delay(50);
effect++;
if (effect >4) effect=0;
};
Пн янв 16, 2012 13:31:51
while(1){ // бесконечный цикл
switch(get_key_pressed()){ // при помощи функции get_key_pressed получаем код нажатой кнопки
case KEY_1:
// увеличение переменной
effect++;
break;
case KEY_2:
// уменьшение переменной
effect--;
break;
}
}
Пн янв 16, 2012 13:46:22
if (PIND & (1<<4))
{
delay(50);
effect++;
if (effect >4) effect=0;
};
Пн янв 16, 2012 14:44:55
#define KEY_1 (1<<PB0)
#define KEY_2 (1<<PB1)
// и так далее хоть все 8 кнопок
#define ANY_KEY (KEY_1 | KEY_2) /* тут надо перечислить все существующие кнопки, и не слушайте тех, кто скажет, что скобки лишние */
#define NO_KEY 0
// настройка порта на ввод с подтяжками - делается где-то в начале main()
DDRB &= ~ANY_KEY;
PORTB |= ANY_KEY;
// функция получения кода нажатых кнопок
unsigned char get_key_pressed(void){
unsigned char key;
key = ~(PINB & ANY_KEY);
delay_ms(15); // задержка для подавления дребезга
if(key == ~(PINB & ANY_KEY))
return key;
else
return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка
}
Пн янв 16, 2012 15:55:18
Мастер Ломастер писал(а):не можете поймать нажатие кнопки? поступайте, как я вам рассказывал итак, задача: есть порт МК, к которому на землю подключено до 8 кнопок. надо отловить их нажатия. как поступить? заранее настроить порт на ввод с встроенными подтяжками, тогда чтение порта с ненажатыми кнопками вернет единицы во всех разрядах байта, а если будет что-то нажато - в том месте будет ноль. кнопка может "дребезжать", т.е. некоторое время (10-25 мс) не иметь постоянного контакта - этого нужно избежать. как? опрашиваем порт, запоминаем результат. ждем 10-25 мс и снова опрашиваем порт, сравнивая результат с запомненным: если они совпали, значит, дребезг уже закончился (или не начинался) и считаны именно данны о нажатых кнопках. теперь, когда на словах разобрались с алгоритмом, опишем его на языке Си, вспоминая ранее данные рекомендации о кодах кнопок:
- Код:
#define KEY_1 (1<<PB0)
#define KEY_2 (1<<PB1)
// и так далее хоть все 8 кнопок
#define ANY_KEY (KEY_1 | KEY_2) /* тут надо перечислить все существующие кнопки, и не слушайте тех, кто скажет, что скобки лишние */
#define NO_KEY 0
// настройка порта на ввод с подтяжками - делается где-то в начале main()
DDRB &= ~ANY_KEY;
PORTB |= ANY_KEY;
// функция получения кода нажатых кнопок
unsigned char get_key_pressed(void){
unsigned char key;
key = ~(PINB & ANY_KEY);
delay_ms(15); // задержка для подавления дребезга
if(key == ~(PINB & ANY_KEY))
return key;
else
return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка
}
разумеется, лучше кодам кнопок давать более осмысленные имена, например не KEY_1, а NEXT_EFFEKT_KEY и т.п. - это позволит получить более читабельную программу.
вопросы?
Пн янв 16, 2012 16:39:38
Пн янв 16, 2012 17:01:21
BerZerK-ku писал(а):Вместо PD, PB в IAR используйте PORTB0, PORTD1 и т.п.
И включите опцию General Options->System->Enable bit definition in I/O-Include files.
Пн янв 16, 2012 17:02:01
#include <ioavr.h>
#include <intrinsics.h>
#include <stdlib.h>
#define KEY_1 (1<<PIND0)
#define KEY_2 (1<<PIND1)
#define KEY_3 (1<<PIND2)
#define KEY_4 (1<<PIND3)
#define KEY_5 (1<<PIND4)
#define ANY_KEY (KEY_1 | KEY_2 | KEY_3 | KEY_4 | KEY_5 )
#define NO_KEY 0
int interval = 200;
int delitel = 5;
int effect = 0;
void delay(long unsigned int Pause)
{
long int i;
long int i2;
i2=Pause*100;
for(i=0; i<i2; ++i )
asm("nop");
}
// функция получения кода нажатых кнопок
unsigned char get_key_pressed(void)
{
unsigned char key;
key = ~(PIND & ANY_KEY);
delay(15); // задержка для подавления дребезга
if(key == ~(PIND & ANY_KEY))
return key;
else
return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка
}
int main( void )
{
char del;
int i;
PORTB = 0xFF;
DDRB = 0xFF;
DDRD &= ~ANY_KEY;
PORTD |= ANY_KEY;
while(1)
{
switch(get_key_pressed()) // при помощи функции get_key_pressed получаем код нажатой кнопки
{
case KEY_5:
// след.эффект
effect++;
if (effect>3) effect = 0;
break;
}
switch(effect)
{
case 0:
PORTB=0x00;
break;
case 1:
PORTB=0xFF;
break;
case 2:
PORTB=0xFF;
del = 5 / delitel;
i = interval * del ;
delay(i);
PORTB=0x00;
i = interval * (1/del);
delay(i);
break;
}
}
return 0;
}
Пн янв 16, 2012 18:01:33
void main(void)
{
PORTB = 0xFF;
DDRB = 0xFF;
DDRD = 0;
PORTD = 0xFF;
while(1)
{
PORTB = PIND;
}
}
Пн янв 16, 2012 21:22:58
Вт янв 17, 2012 05:19:11
if ( (PIND & 0x1F) != 0x1F )
PORTB = (1 << PORTB7);
else
PORTB = 0;