Недавно мне понадобилось создать небольшой счётчик, который бы принимал сигналы и перекрывал их источник после принятия определённого количества, при этом выдавая процесс на семисегментый индикатор с двумя цифрами и единицой в начале (188). Для работы решил использовать pic16f84a, потому, что это оказался единственным микроконтроллером в одном из немногих радиомагазинов в моём городе. Сам аппарат спаял, а так-как занимаюсь программированием на С++, решил, что с прошивкой проблем не будет. В качестве компилятора выбрал "MPLAB IDE" с "hi-tech c comopiler'ом". Но как же я оказался неправ. В общем сижу уже неделю, изучаю pic. За это время переписал код несколько раз. Но всё без толку. Добивался, что стабильно работал индикатор, но ввод с конопок на той-же ножке, что и вывод на индикатор, никак не мог реализовать. Проверял, кстати, с помощью Proteus'а и PIC simulator IDE. На настоящем микроконтроллере пока проверять не рискую, ибо первый pic16 спалил при первой же попытке, остался только один, а сроки поджимают. Кто-нибудь из разбирающихся в этой области может помочь? В общем вот тот код, что у меня вышел на данный момент. В чём ошибки и почему он отказывается нормально работать?
В общем делаю я всё это под индикатор с общим катодом, но крайне было бы желательно мне разобраться с выводом под общий анод.
Ну и из-за недостатка ножек мне пришлось зацепить и вывод на сегменты и приём сигнала на одни и те-же выводы с динамическим переключением направления, кстати нашёл в протеусе такой-же пример, только с часами, но код там в hex-файле, так что никак не могу посмотреть эту реализацию. Ещё есть подозрения, что проблема у меня из-за незнания С, но на сколько я помню, отличия у него от С++ только в классах, за исключением некоторых комманд, которые сразу видятся компилятором.
Буду крайне признателен, если кто укажет на ошибки. Просто, как уже говорил, пишу не под ПК в первый раз и просто измучался, пытаясь исправить всё это дело.
Извиняюсь, что код не под катом, если тут есть такая функция, ибо таковой не нашёл. И ещё извиняюсь, что код жутко поплыл при вставке на форум.
Раздел: PIC
#include <pic.h>
__CONFIG(HS & WDTDIS & PWRTEN);//4 мегагерца кварц, таймеры 1 - вкл, 2 - выкл
enable_digital_io();//цифровой режим выходов
void Graphic(int);//вывод на индикатор
char Input(int);//ввод по кнопкам
bit count_mode = 0;//вода или таймер
bit clapan_mode = 0;//принудительное закрытие или начало отсчёта
char APORTB[10];//цифры 0-9
bit step = 0;//шаг индикатора
//мейн
int main()
{
//назначаем ножки
TRISA0 = 0;//открытие потока
TRISA1 = 0;//цифра 2
TRISA2 = 0;//цифра 3
TRISA3 = 0;//цифра "1"
TRISA4 = 1;//вход турбины
//назначаем элементы цифр
TRISB0 = 0;//прерывание
TRISB1 = 0;//лево верх, +-
TRISB2 = 0;//лево низ, 1
TRISB3 = 0;//центр верх, 19
TRISB4 = 0;//центр центр, смена режима
TRISB5 = 0;//центр низ, открытие клапана
TRISB6 = 0;//право верх
TRISB7 = 0;//право низ
RBPU = 1;//подтягивающие резисторы
INTEDG = 1;//срабатывание по нажатию
INTCON = 0b00000000;//нет прерываний
//присваиваем значения цифрам
APORTB[0] = 0b11101110;
APORTB[1] = 0b11000000;
APORTB[2] = 0b01111100;
APORTB[3] = 0b11111000;
APORTB[4] = 0b11010010;
APORTB[5] = 0b10111010;
APORTB[6] = 0b10111110;
APORTB[7] = 0b11001000;
APORTB[8] = 0b11111110;
APORTB[9] = 0b11111010;
//мигаем после загрузки
Graphic(188);
for(int stop=0; stop<10; stop++)
{_delay(10);}
//начинаем работу
char sygnal = 10;//оставшееся количество порций
float dynamic_sygnal = 0;//точное количество сигналов
char time_i = 0;//оставшееся время
float time_f = 0;//точное количество
while(1)//бесконечный цикл
{
if(count_mode == 0)
{
sygnal+=Input(sygnal);//регулирование количества воды
Graphic(sygnal);//вывод оставшегося количества воды
if (clapan_mode == 0)
{
if(RA4 == 0) step=0;
if(RA4 == 1 && step == 0)
{
step = 1;
dynamic_sygnal+=0.001;
if(dynamic_sygnal>=1 && sygnal>=1)
{
dynamic_sygnal--;
sygnal--;
}
}
}
}
if(count_mode == 1)
{
time_i+=Input(time_i);//регулирование времени
Graphic(time_i);
time_f+=0.0001;
if(time_f>=1 && time_i>=1)
{
time_f--;
time_i--;
}
if(time_i<=0) count_mode == 0;
}
if(sygnal <= 0 || clapan_mode == 1)
{
RA0 = 1;
}
else
{
RA0 = 0;
}
}
}
//ввод
bit A1=0;
bit A2=0;
bit i = 0;//номер цифры
int single_press = 0;
char Input(int sygnal)//блок ввода данных
{
int counting_sygnal = 0;//надбавка воды за цикл
PORTB = 0b00000001;
TRISB1 = 1;//+-
TRISB2 = 1;//1
TRISB3 = 1;//10
TRISB4 = 1;//смена режима
TRISB5 = 1;//смена режима
_delay(250);
//детект отпущеных кнопок
if(RB2 == 1 && RB3 == 1 && RB4 == 1 && RB5 == 1) single_press = 0;
//изменение количества воды
if(single_press == 0)
{
if(RB2 == 0)
{
single_press = 1;
if(RB1 == 0)
{counting_sygnal -= 1;}
else
{counting_sygnal += 1;}
}
if(RB3 == 0)
{
single_press = 1;
if(RB1 == 0)
{counting_sygnal -= 10;}
else
{counting_sygnal += 10;}
}
if(RB4 == 0)
{
single_press = 1;
count_mode ^= 1;
}
if(RB5 == 0)
{
single_press = 1;
clapan_mode ^= 1;
}
}
_delay(250);
TRISB1 = 0;//лево верх
TRISB2 = 0;//лево низ
TRISB3 = 0;//центр верх
TRISB4 = 0;//центр центр
TRISB5 = 0;//центр низ
PORTB = APORTB[i] & 0b00000001;
if(sygnal + counting_sygnal > 199) counting_sygnal == 0;
if(sygnal + counting_sygnal < 0) counting_sygnal == 0;
return counting_sygnal;
}
//графический вывод
char pass=1;
char digit=0;
void Graphic(int number)
{
char num[2];
pass++;
if(pass>=100)
{
pass=0;
if(number>=100)
{
number-=100;
RA3=1;
}
else
{
RA3=0;
}
i ^= 1;
num[1]=number%10;
num[0]=number/10;
//выбираем цифру
if(i==0)
{
A1=1;
A2=0;
digit=num[0];
}
else
{
A1=0;
A2=1;
digit=num[1];
}
RA1=A1; RA2=A2;
}
PORTB = APORTB[digit] & 0b00000001;
return;
}
В общем делаю я всё это под индикатор с общим катодом, но крайне было бы желательно мне разобраться с выводом под общий анод.
Ну и из-за недостатка ножек мне пришлось зацепить и вывод на сегменты и приём сигнала на одни и те-же выводы с динамическим переключением направления, кстати нашёл в протеусе такой-же пример, только с часами, но код там в hex-файле, так что никак не могу посмотреть эту реализацию. Ещё есть подозрения, что проблема у меня из-за незнания С, но на сколько я помню, отличия у него от С++ только в классах, за исключением некоторых комманд, которые сразу видятся компилятором.
Буду крайне признателен, если кто укажет на ошибки. Просто, как уже говорил, пишу не под ПК в первый раз и просто измучался, пытаясь исправить всё это дело.
Извиняюсь, что код не под катом, если тут есть такая функция, ибо таковой не нашёл. И ещё извиняюсь, что код жутко поплыл при вставке на форум.
Раздел: PIC