|
|
| ||||||||
|
|
|
29021
46
2
0
|
|
Опции темы | Поиск в этой теме |
|
1
|
|
Новичок
Регистрация: 24.04.2012 Последняя активность: 25.05.2012 10:56
Сообщений: 13
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Здравсвуйте! Нужна програмка для Attiny13A, которая будет работать с 5-ю диодами, поочерёдно зажигая каждый из них с промежутком в 30 секунд, и один как индикация работы устройства, т.е. 4 мигают, один светится как индикация.
Спасибо. |
|
|
|
|
|
2
|
|
Ветеран Фонарёвки
Регистрация: 07.04.2011 Последняя активность: 05.07.2019 16:52
Сообщений: 2816
Сказал(а) спасибо: 25
Поблагодарили: 402 раз(а) в 189 сообщениях
|
frotnline, С в помощь.
|
|
|
|
|
|
3
|
|
Завсегдатай Фонарёвки
Регистрация: 16.02.2011 Последняя активность: 22.05.2017 13:07
Сообщений: 729
Сказал(а) спасибо: 4
Поблагодарили: 177 раз(а) в 92 сообщениях
|
Готов помочь, при условии что 50% работы сделаешь сам.
Для затравки 50% программы: Код:
#include <attiny13.h>
void delay(unsigned char);
main()
{
DDRB=0x1F;
for()
{
PORTB = 0x0E;
delay(30);
PORTB = 0x0D;
delay(30);
PORTB = 0x0B;
delay(30);
PORTB = 0x07;
delay(30);
}
}
|
|
|
|
|
|
4
|
|
Консультант
![]() Регистрация: 15.11.2010 Последняя активность: 27.06.2025 10:19
Сообщений: 7980
Сказал(а) спасибо: 1077
Поблагодарили: 1714 раз(а) в 912 сообщениях
|
frotnline, просто и доступно про основы программирование МК на С, можно почитать здесь: http://forum.*********/showt...
|
|
|
|
|
5
|
|
Новичок
Регистрация: 24.04.2012 Последняя активность: 25.05.2012 10:56
Сообщений: 13
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Спасибо большое, кстати у меня есть код,именно того что мне надо сделать в итоге, который должен работать, но почему-то светятся все светодиоды одновременно, я подозреваю что дело в fuse bits, можно ли их как-то подобрать, так как код не мой и как именно надо выставлять fuse я не знаю. Если что могу выложить код!
Спасибо! |
|
|
|
|
|
6
|
|
Консультант
![]() Регистрация: 15.11.2010 Последняя активность: 27.06.2025 10:19
Сообщений: 7980
Сказал(а) спасибо: 1077
Поблагодарили: 1714 раз(а) в 912 сообщениях
|
Цитата:
|
|
|
|
|
|
7
|
|
Завсегдатай Фонарёвки
Регистрация: 16.02.2011 Последняя активность: 22.05.2017 13:07
Сообщений: 729
Сказал(а) спасибо: 4
Поблагодарили: 177 раз(а) в 92 сообщениях
|
|
|
|
|
|
8
|
|
Новичок
Регистрация: 24.04.2012 Последняя активность: 25.05.2012 10:56
Сообщений: 13
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Вот кусочек схемы необходимого устройства:
![]() Вот код,который имеется: Код HTML:
#include <avr/io.h> #include <avr/interrupt.h> #define PreloadLow 0x0C //0x8C #define PreloadHugh 0x0F //0x11 #define sc 15 //signal counter //Bit oriented macros unsigned char bits[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; #define set_bit(x,y) x|=bits[y] //Macros set bit Y in variable X #define clear_bit(x,y) x&=~bits[y] //Macros clear bit Y in variable X #define inv_bit(x,y) x^=bits[y] //Macros inversion bit Y in variable X /*Signal definition oD array define time of signal, oS array define type of signal 0x0F=pause 0x0E=Dz/s 0x0D=Z 0x0B=Dz 0x07=KPTS-1315 Dz Z KP Z KP Dz KP DzS p KP p Dz p Z p DzS*/ unsigned char oD[sc+1]={20, 20, 10, 30, 10, 20, 20, 30, 10, 30, 10, 30, 20, 20, 40, 30}; unsigned char oS[sc+1]={0x0B,0x0D,0x07,0x0D,0x07,0X0B,0x07,0x0E,0x0F,0x07,0x0F,0x0B,0x0F,0x0D,0x0F,0x0E}; unsigned char i=sc; //index unsigned char duration; //signal duration unsigned char TCNT1; //Hihg byte of timer ISR (SIG_OVERFLOW0) { if(!TCNT--) { TCNT1=PreloadHigh; TCNT0=PreloadLow; if(!duration--) //if time of signal is ended { if(!i--) { i=sc; inv_bit(PORTB,5); } duration=oD[i]; //change signal on PORTB PORTB=oS[i]; } inv_bit(PORTB,4); } } int main (void) { CLKPR=0x80; CLKPR=0x00; //Port B initialization //Func5=In Func4=Out Func3=Out Func2=out Funcs1=Out Func0=Out DDRB=0x3F; PORTB=oS[i]; //output first signal duration = oD[i]; // TIFR0=0; ACSR=0x80; //Analog Comparator initialization ADCSRB=0x00; //Analog Comparator: Off //External Interrupt(s) initialization //INTO:Off //Interrupt on any change on pins PCINTO-5: Off GIMSK=0x00; MCUCR=0x00; //Timer/Counter 0 initialization //Clock source: System Clock //Clock value: 4,492 kHz //Mode: Normal top=FFh //OC0A output: Disconnected //OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x05; TCNT1=PreloadHigh; TCNT0=PreloadLow; OCR0A=0x00; OCR0B=0x00; TIMSK0=0x02; //Timer Counet 0 Interrupt(s) initialization GIFR=0; sei(); while(1) } |
|
|
|
|
|
9
|
|
Завсегдатай Фонарёвки
Регистрация: 16.02.2011 Последняя активность: 22.05.2017 13:07
Сообщений: 729
Сказал(а) спасибо: 4
Поблагодарили: 177 раз(а) в 92 сообщениях
|
Замечательно, давай начнём со схемы. У ATtiny13A питание на 8-ю ногу подаётся, а не на 5-ю. Программу чуть позже гляну. С виду она даже скомпилироваться не должна.
- while(1) должно быть while(1); - PreloadHigh не определено - TCNT не определено [Исправлено: VladislavS, 27.04.2012 в 15:23] |
|
|
|
|
|
10
|
|
Завсегдатай Фонарёвки
Регистрация: 16.02.2011 Последняя активность: 22.05.2017 13:07
Сообщений: 729
Сказал(а) спасибо: 4
Поблагодарили: 177 раз(а) в 92 сообщениях
|
Предлагаю для начала выкинуть из программы всё ненужное и организовать/проверить прерывания с периодом 1 секунда. Для удобства программирования.
Код:
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char bits[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
#define set_bit(x,y) x|=bits[y]
#define clear_bit(x,y) x&=~bits[y]
#define inv_bit(x,y) x^=bits[y]
ISR (SIG_OUTPUT_COMPARE0A)
{
inv_bit(PORTB,4);
}
int main (void)
{
DDRB=0x1F;
PORTB=0x1F;
TCCR0A=0x02; // WGM01=1 WGM00=0; Режим CTC=0-OCRA
TCCR0B=0x05; // 128кГц / 1024 = 125 Гц
OCR0A=125; // 1 Гц по CompareA
TIMSK0=0x04; // Compare Match A Interrupt
sei();
for(;;);
}
Подразумевается что компилятор у тебя есть ![]() Саму программу миганий предлагаю чуть удобней переписать так Код:
typedef enum { pause=0x0F, DzS=0x0E, Z=0x0D, Dz=0x0B, KP=0x07} STATES;
typedef struct
{
STATES oS;
unsigned char oD;
} PROGRAM;
const PROGRAM program[]={{Dz,20},{Z,20},{KP,10},{Z,30},{KP,10},{Dz,20},{KP,20},{DzS,30},{pause,10},{KP,30},{pause,10},{Dz,30},{pause,20},{Z,20},{pause,40},{DzS,30}};
Код:
ISR (SIG_OUTPUT_COMPARE0A)
{
static unsigned char program_counter;
static unsigned char delay_counter;
if(++delay_counter==program[program_counter].oD)
{
delay_counter=0;
if(++program_counter==sizeof(program)){ program_counter=0; };
PORTB=(PORTB&0x10)|program[program_counter].oS;
}
inv_bit(PORTB,4);
}
[Исправлено: VladislavS, 27.04.2012 в 16:53] |
|
|
|
|
|
11
|
|
Завсегдатай Фонарёвки
Регистрация: 16.02.2011 Последняя активность: 22.05.2017 13:07
Сообщений: 729
Сказал(а) спасибо: 4
Поблагодарили: 177 раз(а) в 92 сообщениях
|
sizeof(program) правильнее заменить на sizeof(program)/sizeof(PROGRAM)
|
|
|
|
|
|
12
|
![]() |
VladislavS,
Что-то длинно и не наглядно. Как я понял ему нужно типа бегущего огня на 4-х диодах и один просто горит пока программа работает (или нет?). Я бы сделал через сдвиг бита. |
|
|
|
|
|
13
|
|
Завсегдатай Фонарёвки
Регистрация: 28.05.2010 Последняя активность: 22.12.2013 16:40
Сообщений: 837
Сказал(а) спасибо: 0
Поблагодарили: 80 раз(а) в 53 сообщениях
|
Подбирайте: ATtiny13
Принимая во внимание ошибки в схеме и коде, заниматься этим можно до посинения. |
|
|
|
|
|
14
|
|
Завсегдатай Фонарёвки
Регистрация: 16.02.2011 Последняя активность: 22.05.2017 13:07
Сообщений: 729
Сказал(а) спасибо: 4
Поблагодарили: 177 раз(а) в 92 сообщениях
|
Ну просто товарищ сам не может сформулировать задачу. Посмотри приведённый им код. Там не просто диоды мигают, а выполняется совершенно конкретная программа миганий. А просто и наглядно в 3-м сообщении темы смотри.
А в отсутствии самого вопрошующего можно и поизголяться в кодомарательстве. ![]() А смысл? Загрузка константы в PORT - две команды. Считать PORTB, сдвинуть, проверить не вышли ли за границы, если вышли, то взять константу, загрузить обратно. Сколько там набегает? [Исправлено: VladislavS, 30.04.2012 в 10:10] |
|
|
|
|
|
15
|
|
![]() |
Цитата:
Код:
void test()
{
while (1)
{
PORTB |= (1<<PORTB0);
for (int i = 0; i < 5; i++)
{
_delay_ms(250);
PORTB = PORTB << 1;
}
PORTB = 0;
_delay_ms(250);
}
}
|
|
|
|
|
|
|
16
|
|
Завсегдатай Фонарёвки
Регистрация: 16.02.2011 Последняя активность: 22.05.2017 13:07
Сообщений: 729
Сказал(а) спасибо: 4
Поблагодарили: 177 раз(а) в 92 сообщениях
|
|
|
|
|
|
|
17
|
![]() |
Да, точно, получится бегущая тень
но это не принципиально - изменить не проблема.Почему нельзя? Кто запретил? Городить малопонятные заклинания, в которых через месяц уже не разобраться, но гордиться, что осталось 85% памяти? [Исправлено: Tamagotchi, 30.04.2012 в 23:59] |
|
|
|
|
|
18
|
|
Завсегдатай Фонарёвки
Регистрация: 16.02.2011 Последняя активность: 22.05.2017 13:07
Сообщений: 729
Сказал(а) спасибо: 4
Поблагодарили: 177 раз(а) в 92 сообщениях
|
Всё просто. Твой пример:
Код:
void test1(void)
{
while (1)
{
PORTB |= (1<<PORTB0);
for (int i = 0; i < 5; i++)
{
_delay_ms(250);
PORTB = PORTB << 1;
}
PORTB = 0;
_delay_ms(250);
}
}
Код:
5 void test1(void)
\ ??test1:
6 {
\ 00000000 938A ST -Y, R24
7 while (1)
8 {
9 PORTB |= (1<<PORTB0);
\ ??test1_1:
\ 00000002 9AC0 SBI 0x18, 0x00
10 for (int i = 0; i < 5; i++)
\ 00000004 E085 LDI R24, 5
11 {
12 _delay_ms(250);
\ ??test1_2:
\ 00000006 EF0A LDI R16, 250
\ 00000008 .... RCALL ??_delay_ms
13 PORTB = PORTB << 1;
\ 0000000A B308 IN R16, 0x18
\ 0000000C 0F00 LSL R16
\ 0000000E BB08 OUT 0x18, R16
14 }
\ 00000010 958A DEC R24
\ 00000012 F7C9 BRNE ??test1_2
15 PORTB = 0;
\ 00000014 E000 LDI R16, 0
\ 00000016 BB08 OUT 0x18, R16
16 _delay_ms(250);
\ 00000018 EF0A LDI R16, 250
\ 0000001A .... RCALL ??_delay_ms
\ 0000001C CFF2 RJMP ??test1_1
17 }
18 }
Maximum stack usage in bytes:
Function CSTACK RSTACK
-------- ------ ------
test1() 1 2
1 byte in segment ABSOLUTE
30 bytes in segment CODE
Код:
void test1(void)
{
for(;;)
{
PORTB = 1;
_delay_ms(250);
PORTB = 2;
_delay_ms(250);
PORTB = 4;
_delay_ms(250);
PORTB = 8;
_delay_ms(250);
PORTB = 0;
_delay_ms(250);
}
}
Код:
6 void test1(void)
\ ??test1:
\ ??test1_1:
7 {
8 for(;;)
9 {
10 PORTB = 1;
\ 00000000 E001 LDI R16, 1
\ 00000002 .... RCALL ?Subroutine0
11 _delay_ms(250);
12 PORTB = 2;
\ 00000004 E002 LDI R16, 2
\ 00000006 .... RCALL ?Subroutine0
13 _delay_ms(250);
14 PORTB = 4;
\ 00000008 E004 LDI R16, 4
\ 0000000A .... RCALL ?Subroutine0
15 _delay_ms(250);
16 PORTB = 8;
\ 0000000C E008 LDI R16, 8
\ 0000000E .... RCALL ?Subroutine0
17 _delay_ms(250);
18 PORTB = 0;
\ 00000010 E000 LDI R16, 0
\ 00000012 .... RCALL ?Subroutine0
19 _delay_ms(250);
20 }
\ 00000014 CFF5 RJMP ??test1_1
21 }
\ ?Subroutine0:
\ 00000000 BB08 OUT 0x18, R16
\ 00000002 EF0A LDI R16, 250
\ 00000004 .... RJMP ??_delay_ms
Maximum stack usage in bytes:
Function CSTACK RSTACK
-------- ------ ------
test1() 0 2
1 byte in segment ABSOLUTE
28 bytes in segment CODE
Вложенные циклы и сдвиги там где они не нужны? Это больше религиозные аспекты. Код должен "нравится" компилятору и микроконтроллеру, а человек потерпит. Объясни тогда через день, зачем в твоём примере PB4 зажигается на несколько тактов? Сегодня 85% осталось, а завтра 1 байта не хватило... Так бывает. :forum: [Исправлено: VladislavS, 01.05.2012 в 00:51] |
|
|
|
|
|
19
|
![]() |
VladislavS,
Ну, 2 байта экономии Но поставленная задача с большим запасом помещается, а кодКод:
void test1(void)
{ for(;;)
{
PORTB = 1;
_delay_ms(250);
PORTB = 2;
_delay_ms(250);
PORTB = 4;
_delay_ms(250);
PORTB = 8;
_delay_ms(250);
PORTB = 0;
_delay_ms(250);
}
}
В данной задаче ресурсов МК хватает с запасом. |
|
|
|
|
|
20
|
|
Завсегдатай Фонарёвки
Регистрация: 28.05.2010 Последняя активность: 22.12.2013 16:40
Сообщений: 837
Сказал(а) спасибо: 0
Поблагодарили: 80 раз(а) в 53 сообщениях
|
Почему некрасиво? Вы считаете функцию, а VladislavS задает ее в табличном виде. Это предсказуемо, и есть простор для маневра- на каждом шаге можно задать любые состояния сид (понятно, что табличку можно оформить массивом). А у Вас получается- захотелось, чтобы 2 диода загорались, и все, переписывай код. А в прерывания загоните- получите источник багов при изменении функции при чуть более сложной задаче. Ну и комментарии нужны, формально, для каждой строки.
|
|
|
|