Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

PIC16F628a 3 въпроса
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=13429
Страница 1 от 2

Автор:  kalata23 [ Пон Дек 15, 2014 11:53 pm ]
Заглавие:  PIC16F628a 3 въпроса

Здравейте, понеже от 1 месец се занимавам с PIC микроконтролери и още нямам достатъчно опит, имам 3 въпроса и ще бъда много благодарен, ако ми помогнете да намеря отговор. Преди да ги задам обаче, искам да уточня, че пиша програми на С, като използвам компилатора CCS PIC C compiler. Понеже в момента не съм у дома и нямам физически достъп до програматори и чипове и т.н. Използвам Proteus 8.0 SP0 за симулация на код и схеми.

Та по същество:

Въпрос 1: Как мога да накарам rand() да ми върне число в интервал от 1 до 6 включително? знам, че принципно srand(int32 ) трябва да оказва от коя цифра да започне, но въпросът е, че не искам да ми даде псевдослучайно число до 3265, а до 6. Мислих си да коригирам stdlib.h до компилиране на програмата, но не е практично.

Въпрос 2: Ако някой от вас е работил с PIC C Compiler, как да накарам A5 пина да бъде вход? Проблемът е, че при PIC16F628A, този вход се използа за MCLR, но понеже не ми достигат пинове за схемата, трябва да използвам A5 и B5 като входове, а останалите пинове като изходи.

Въпрос 3: Имам схема и искам да направя програма, която с гореспоменатия ПИК управлявам двуразряден 7 сегментен индикатор с общ анод (VQE24); Целта ми е, когато на пиновете A5 и B5 постъпи логическа 1-ца (с натискане на бутон) индикаторът да изобрази 2 случайни цифри. Проблемът при мен е, че

Относно 3-тия въпрос прикачвам схемата на свързване като картинка. А ето го и кодът, който съм написал за управление на пик-а:

Код:
#include <pic16f628aproj.h>
#include <stdlib.h>
int1 state1;
int1 state2;

void main()

   int8 number1,number2,out1,out2; // нъмбър1 и 2 са променливи, които ще получат ранд() числото, а out1,out2 са
                                                // дешифрираните числа, които директно ще управляват индикатора.
   setup_oscillator(OSC_4MHZ); // избиране на осцилатор - вътрешния генератор на 4МHZ
   output_a(46);  // Дисплеят изобразява буквите F F
   output_b(46); //
   delay_ms(3000); // до закъснението включително, това е инициализация, че индикаторът работи
   output_a(255);
   output_b(255); // индикаторът загасва => чака натискане на бутон
   
   
   while(TRUE)         
   {
     if (!input(PIN_A5))       // ако на пин A5 има лог. 1
     {
       state1 = 1;             
     }
     else state1 = 0;
     
     if (input(PIN_B5)!=0)
     {
       state2 = 1;
     }
     else state2 =0;
     
     if( ( state1 == 1 ) && ( state2 == 1 ) )
     {
       
        srand(1);
        number1 = rand() % 6;
        number2 = rand() % 6;
        out1 = decoder(number1);
        out2 = decoder(number2);
        output_a(out1);
        output_b(out2);
        state1 = 0;
        state2 =0;
     }
     
     }
   }


Прикачени файлове:
Коментар на файл: Схема
pic16f628aled.png
pic16f628aled.png [ 45.14 KiB | Прегледано 5991 пъти ]

Автор:  ike [ Вто Дек 16, 2014 8:08 am ]
Заглавие:  Re: PIC16F628a 3 въпроса

http://www.cplusplus.com/reference/cstdlib/rand/
Проблема е, че с rand()% има bias, за разлика от зарчето.
Изображение

Автор:  kalata23 [ Вто Дек 16, 2014 2:30 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

Не разбрах само, какво ще рече, че има bias? Относно картинката, моите индикатори са с общ анод. Освен това, идеята е като натисна бутона да разбърква двете числата и при пускането на бутона да изобрази последните генерирани числа едновременно. Имам всичко на всичко 16 I/O, като 14 са заети от индикатора и 2 за бутона.
Относно разбъркването на числата и т.н. всичко работи шест, само, не знам от тъпата симулация ли е или е от кода, че ми се струва, че изобразяват нула. Протеуса ми изкарва неправилно числата, което е странно, защото на същият пик преди време написах един брояч с първоначална индикация FF, а после да брои от 99 до 00 и си работи чудесно. Когато седнах да пиша, тази програма, пробвах да заредя програмата от пик-а и отново правеше проблеми при симулацията......
Относно рандъм числото - number1 = rand() % 6 + 1; <- това използвам за случайно число.
Та ето скрийн за какво става дума:

Прикачени файлове:
screen2..png
screen2..png [ 25.51 KiB | Прегледано 5920 пъти ]

Автор:  ike [ Вто Дек 16, 2014 3:44 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

kalata23 написа:
Относно рандъм числото - number1 = rand() % 6 + 1; <- това използвам за случайно число.

Представи си, че rand() връща случайно число от 0 до 9. Викаш го 10 пъти и ти връща стойности 0,1,2,3,4,5,6,7,8,9 следователно функцията rand() % 6 + 1 ще ти вътне: 1,2,3,4,5,6,1,2,3,4
или ще имаш 20% шанс да ти се падне 1, 20% шанс да ти се падне 2, 20% шанс да ти се падне 3, 20% шанс да ти се падне 4, 10% шанс да ти се падне 5 и 10% шанс да ти се падне 6 - да виждаш нещо нередно тук?
От 1 пин, ако на него има ADC закачена периферия можеш да четеш 4-5 клавиша на него:
Изображение
Изображение
Май мултиплексирането не си го разбрал за това показвам още линкове разгледай ги:
http://www.8051projects.net/pic_tutoria ... xample.php
https://www.google.bg/search?num=100&es ... lexing+pic

Автор:  kalata23 [ Вто Дек 16, 2014 4:24 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

Благодаря за линковете, сега ще пробвам с мултиплексиране. Относно случайните числа, да, принципно не е редно да имам 1,2,3,4,5,6,1,2,3. На симулацията това естествено не се случва, но въпросът е, че при симулацията когато я пусна и натисна 5 пъти бутона имам примерно:
4,5
1,5
4,5
4,1
1,4

при следващото пускане на симулацията и отново 5 пъти натискане на бутона по същия начин се изобразяват отново същите числа.

Автор:  Ники [ Вто Дек 16, 2014 4:35 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

Функцията rand(), се инициализира при всеки рестарт по еднакъв начин, и ще поватаря винаги едни и същи стойности.
За да връща различни числа, преди използването й трябва да се инициализира с различна стойност.
Начина по който ще получиш различни стойности е твой.
Може да ползваш АЦП и да събиращ най младшия бит, който играе най-много, таймер който четеш според някакво събитие, някаква твоя функция която да ти дава произволни стойности, или външен рандъм генератор.

Автор:  t_i_t_o [ Вто Дек 16, 2014 5:01 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

За рандъм - що просто не стартираш единия таймер/брояч, при натискането на бутона му четеш стойността и делиш по модул на 6 (или там колкото ти трябва). Т.е. стойността ще зависи от момента на натискане на бутона, която ще достатъчно случайна ако таймера се тактува с мегахерци т.е. честотата е много по-голяма от евентуалната честота на натискането на бутона.

Автор:  kalata23 [ Вто Дек 16, 2014 5:40 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

Благодаря за разяснението и на всички за предложенията, наистина алгоритъмът ми не беше особено приятен, да си запълвам всичките пинове, когато мога да използвам мултиплексиране. Един въпрос:
Според вас добра идея ли е да използвам DATA EEPROM паметта, за предотвратяване еднаквото инициализиране на rand() при рестарт. Т.е при първо пускане на ПИКа след програмиране, да запише първите две ранд числа, които се генерират в EEPROM-a и при всеки следащ рестарт на ПИКА да върти един цикъл, с който да генерира първите две числа извикани с rand() такива, че да са различни от тези в EEPROM-a. след това да запише новите първи две числа в еепрома и така един вид да променя всички ранд() серии. За да съм сигурен, че ще ме разберете правилно, ще дам пример:

След програмиране на чипа, подавам захранване към ПИК-а:

rand() = 1;
rand() = 2;
първи адрес в data eeprom = 1;
втори адрес в data eeprom 2;
rand() = 3;
rand() = 4;
rand() = 5;
rand() = 6;
.
.
.

Рестартиране на пик-а (изключване и включване на захранването);
rand() =2 ;
rand() = 3;
първи адрес на еепрома = 2;
втори адрес на еепрома = 3;
rand = 4;
rand = 5;
rand = 6;
rand = 1;
Естествено, rand() няма да генерира 1,2,3,4,5,6 последователно, ами примерно ще генерира 5,3,5,1,6,2. Идеята е серията числа, които ще се падат да се сменя със всеки рестарт на ПИК-а. А и все пак докато бутонът е натиснат, числата ще се "джуркат",
Разбира се алгоритъмът може да се усложни до толкова, че да не генерира числа от 1 до 6 ами примерно от 1 до 3265, като числото "3265" мога да го съхраня в масив [3][2][6][5] и при първата цифра, която е в интервал 0<x<7 да бъде "случайното" число.

Автор:  ike [ Вто Дек 16, 2014 6:06 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

kalata23 написа:
Относно случайните числа, да, принципно не е редно да имам 1,2,3,4,5,6,1,2,3. На симулацията това естествено не се случва, но въпросът е, че при симулацията когато я пусна и натисна 5 пъти бутона имам примерно:

1. Не си ме разбрал. Не ти говоря за последователността на числата, а за тяхната честота. В случая 5 или 6 е много по-малко вероятно да се паднат. Прочети пак какво съм написал и го осмисли.
2. Както Ники ти каза, пускаш таймер и при първото натискане на бутон взимаш стойността на таймери и го начукваш на функцията srand() - прочети внимателно какво прави.
3. Понеже го написа 5 пъти последовалтено, да те попитам, сигурен ли си че функцията rand() връща число от 1 до 3265?

Автор:  kalata23 [ Вто Дек 16, 2014 6:27 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

Явно не съм разбрал правилно, всъщност връща поредица от числа от 0 до RAND_MAX, като RAND_MAX = 32767;
това за 1 до 3265 беше пример.

Автор:  kalata23 [ Сря Дек 17, 2014 9:42 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

Много благодаря за помощта! Използвах timer0 и преди да извикам rand() взимам стойността на тимера и я задавам като параметър на srand(). Освен това, както може би се вижда от схемата и сорса, идеята е ,че като натисна един бутон, числата се джуркат, докато е натиснат бутона, което придава за по-случаен принцип. За сега пробвах програмата на симулацията и върви идеално, като изключим индикаторите, че не изобразяват всички цифри както трябва, ама това мисля, е проблем на протеуса, сега сглобявам схемата на breadboard и ще пиша дали всичко е тип-топ.

Автор:  ike [ Сря Дек 17, 2014 10:15 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

kalata23 написа:
Освен това, както може би се вижда от схемата и сорса, идеята е ,че като натисна един бутон, числата се джуркат, докато е натиснат бутона, което придава за по-случаен принцип.

Това не е вярно.
1. При стартирането пускаш таймер
2. При първото натискане на копчето srand(таймер)
3. Изобразяване на rand()
4. При всяко натискане на копчето пак се изобразява rand()

Автор:  kalata23 [ Чет Дек 18, 2014 12:40 am ]
Заглавие:  Re: PIC16F628a 3 въпроса

Свързах елементите записах програмата на пика и нищо. Записвам на същият пик друга програма, върви идеално, на тази не иска да работи. Не е от схемата на свързване, защото при една и съща схема едната програма върви, другата - не.
Код:
void main()

   int8 number1,number2,out1,out2,value;
   setup_oscillator(OSC_4MHZ);
   output_a(46);
   output_b(46);
   delay_ms(3000);
   output_a(255);
   output_b(255);
   setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_4|RTCC_8_BIT);
   set_rtcc (255);
   start();
   
   while(TRUE)
   {
     if(input(PIN_A5)!=0)
     {
       state1 = 1;
     }
     else state1 = 0;
     
     if (input(PIN_B5)!=0)
     {
       state2 = 1;
     }
     else state2 =0;
     
     if( ( state1 == 1 ) && ( state2 == 1 ) )
     {
       
        value = get_timer0();
        srand(value);
        number1 = rand() % 6 + 1;
        while((number1 == 0) || (number1>6))
        {
          value = get_timer0();
          srand(value);
          number1 = rand() % 6 + 1;
        }
        number2 = rand() % 6 + 1;
        while(number1 == 0)
        {
          value = get_timer0();
          srand(value);
          number2 = rand() %6 + 1;
        }
        out1 = decoder(number1);
        out2 = decoder(number2);
        output_a(out1);
        output_b(out2);
        state1 = 0;
        state2 =0;
     }
     
     }
   }

Това което се случва след захранването е, че индикаторът изобразява FF и до там

Автор:  kalata23 [ Чет Дек 18, 2014 6:33 pm ]
Заглавие:  Re: PIC16F628a 3 въпроса

Съжалявам за двойният пост, общо взето пренаписах програмата наново, тръгна, като имаше проблеми с разбъркването на числата. Мъчих я струвах, накрая пак стигнах до момента с FF и нищо след това....
РЕДАКЦИЯ: Програмата работи, но нещо самите пинове А5 и B5 ми правят бела. Ако ги свържа на маса и подам захранване на пика, индикаторът изобразява FF, след това изобразява 00. При откачане на един от двата пина от масата, веднага почват да се разбъркват всички цифри.

Автор:  ike [ Пет Дек 19, 2014 12:30 am ]
Заглавие:  Re: PIC16F628a 3 въпроса

Обтрни бутоните. Нека пина подразбиране е на маса, а като натиснеш бутона, да става HI така ще се въртят числата, докато не го натиснеш и ще видиш резултата.

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/