Отговори на тема  [ 21 мнения ]  Отиди на страница 1, 2  Следваща
PIC16F628a 3 въпроса 
Автор Съобщение
Ранг: Популярен
Ранг: Популярен

Регистриран на: Пон Дек 15, 2014 11:05 pm
Мнения: 332
Мнение 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 | Прегледано 5990 пъти ]
Пон Дек 15, 2014 11:53 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Фев 04, 2005 9:59 pm
Мнения: 6019
Местоположение: София
Мнение Re: PIC16F628a 3 въпроса
http://www.cplusplus.com/reference/cstdlib/rand/
Проблема е, че с rand()% има bias, за разлика от зарчето.
Изображение

_________________
Warriors of the Night, ASSEMBLER!!!


Вто Дек 16, 2014 8:08 am
Профил
Ранг: Популярен
Ранг: Популярен

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


Прикачени файлове:
screen2..png
screen2..png [ 25.51 KiB | Прегледано 5919 пъти ]
Вто Дек 16, 2014 2:30 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Фев 04, 2005 9:59 pm
Мнения: 6019
Местоположение: София
Мнение 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

_________________
Warriors of the Night, ASSEMBLER!!!


Вто Дек 16, 2014 3:44 pm
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Пон Дек 15, 2014 11:05 pm
Мнения: 332
Мнение 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:24 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Съб Окт 30, 2004 11:19 pm
Мнения: 609
Мнение Re: PIC16F628a 3 въпроса
Функцията rand(), се инициализира при всеки рестарт по еднакъв начин, и ще поватаря винаги едни и същи стойности.
За да връща различни числа, преди използването й трябва да се инициализира с различна стойност.
Начина по който ще получиш различни стойности е твой.
Може да ползваш АЦП и да събиращ най младшия бит, който играе най-много, таймер който четеш според някакво събитие, някаква твоя функция която да ти дава произволни стойности, или външен рандъм генератор.


Вто Дек 16, 2014 4:35 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Вто Окт 25, 2005 10:54 am
Мнения: 896
Мнение Re: PIC16F628a 3 въпроса
За рандъм - що просто не стартираш единия таймер/брояч, при натискането на бутона му четеш стойността и делиш по модул на 6 (или там колкото ти трябва). Т.е. стойността ще зависи от момента на натискане на бутона, която ще достатъчно случайна ако таймера се тактува с мегахерци т.е. честотата е много по-голяма от евентуалната честота на натискането на бутона.


Вто Дек 16, 2014 5:01 pm
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Пон Дек 15, 2014 11:05 pm
Мнения: 332
Мнение 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 да бъде "случайното" число.


Вто Дек 16, 2014 5:40 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Фев 04, 2005 9:59 pm
Мнения: 6019
Местоположение: София
Мнение Re: PIC16F628a 3 въпроса
kalata23 написа:
Относно случайните числа, да, принципно не е редно да имам 1,2,3,4,5,6,1,2,3. На симулацията това естествено не се случва, но въпросът е, че при симулацията когато я пусна и натисна 5 пъти бутона имам примерно:

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

_________________
Warriors of the Night, ASSEMBLER!!!


Вто Дек 16, 2014 6:06 pm
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Пон Дек 15, 2014 11:05 pm
Мнения: 332
Мнение Re: PIC16F628a 3 въпроса
Явно не съм разбрал правилно, всъщност връща поредица от числа от 0 до RAND_MAX, като RAND_MAX = 32767;
това за 1 до 3265 беше пример.


Вто Дек 16, 2014 6:27 pm
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Пон Дек 15, 2014 11:05 pm
Мнения: 332
Мнение Re: PIC16F628a 3 въпроса
Много благодаря за помощта! Използвах timer0 и преди да извикам rand() взимам стойността на тимера и я задавам като параметър на srand(). Освен това, както може би се вижда от схемата и сорса, идеята е ,че като натисна един бутон, числата се джуркат, докато е натиснат бутона, което придава за по-случаен принцип. За сега пробвах програмата на симулацията и върви идеално, като изключим индикаторите, че не изобразяват всички цифри както трябва, ама това мисля, е проблем на протеуса, сега сглобявам схемата на breadboard и ще пиша дали всичко е тип-топ.


Сря Дек 17, 2014 9:42 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Фев 04, 2005 9:59 pm
Мнения: 6019
Местоположение: София
Мнение Re: PIC16F628a 3 въпроса
kalata23 написа:
Освен това, както може би се вижда от схемата и сорса, идеята е ,че като натисна един бутон, числата се джуркат, докато е натиснат бутона, което придава за по-случаен принцип.

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

_________________
Warriors of the Night, ASSEMBLER!!!


Сря Дек 17, 2014 10:15 pm
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Пон Дек 15, 2014 11:05 pm
Мнения: 332
Мнение 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 и до там


Чет Дек 18, 2014 12:40 am
Профил
Ранг: Популярен
Ранг: Популярен

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


Чет Дек 18, 2014 6:33 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Фев 04, 2005 9:59 pm
Мнения: 6019
Местоположение: София
Мнение Re: PIC16F628a 3 въпроса
Обтрни бутоните. Нека пина подразбиране е на маса, а като натиснеш бутона, да става HI така ще се въртят числата, докато не го натиснеш и ще видиш резултата.

_________________
Warriors of the Night, ASSEMBLER!!!


Пет Дек 19, 2014 12:30 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 21 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни