Перейти к содержанию

crazz

Рекомендуемые сообщения

Но для начала, попробуйте метод тыка и поиск мелочи по даташиту или хелпу к программе. Так глядишь, ничего и спрашивать не прийдется.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Не сбивайте человека с системного обучения. Метод тыка годится только для имеющего профильное высшее образование.Это Корабельников изучал контроллеры методом тыка. Результат известен...

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Я Вам еще раз говорю. Открывайте даташит (на русском языке) на PIC12F629/675 на указанном мной ресурсе и начинайте читать. Даташит на МК - это не справочник по транзисторам, там подробнейшее описание по всем узлам. А то Вы больше ноете о трудностях, хотя еще ничего не начали читать...

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Это если применять метод тыка абсолютно ко всему, но ведь большая часть информации можно почерпнуть из даташита и хелпа. Например, метод тыка вполне помогает освоить среду программирования, и само собой этот метод основывается на знании предмета изучения. Если не знаешь как работает транзистор - долго будешь тыкать пока не разберешься, но ведь можно просто почитать курс электроники, после которого метод вполне сработает.

Неужели совсем ничего нет?

Я по крайней мере ничего такого не видел и не использовал.

В принципе ведь все сводится к тому чтобы написать простую программу - мигание светодиодом, и 90% такой книжки заключается в иллюстрациях на какую кнопку программы нажимать чтобы скомпилировать пример...

А остальные 10% это выдержки с даташита.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

У человека нет фундамента образования по цифровой технике и вычислительным машинам. Когда представляешь себе архитектуру, хотя бы приблизительно, то можно методом проб и ошибок (это и есть тык) чего то там освоить, да и то очень примитивно.

А быстро и эффективно изучать можно только с первоисточником и ручкой в руке. Задавая вопросы по ходу изучения и получая на них внятные ответы.

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Да, кстати ... вопросы и ответы записывать надо, кому-то может тоже пригодится.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Я прочитав Корабельникова на асме хоть первые программы простецкие мог сам написать, пусть с алгоритмическими ошибками, но в конечном итоге она хоть как -то работала. Но мои комп сразил страшный недуг ( незнаю что это было) и все программы на асме удалены и резервных копий не осталось, я даже в интернет целиком программу не выкладывал. И я решил начать на СИ, три дня штудировал литературу, в итоге я ничего не понимаю и сеичас даже без подсказки не вспомню как диод на ноге зажечь, а ведь впереди еще usart в конечное устроиство надо придумать.Но это совсем другая тема:(

Не цитируите полностью предыдущее сообщение!!!

Ссылка на комментарий
Поделиться на другие сайты

Просто методом тыка очень долго.Я так электронику изучал.Неужели совсем ничего нет?

Есть прекрасный материал для начинающих по микроконтроллерам PIC - http://mcc18.narod.ru/ - Пошаговая инструкция с картинками - где скачать, как настроить проект, скомпилировать первую простейшую программу с симуляцией. Попробуйте поработать над материалом.
Ссылка на комментарий
Поделиться на другие сайты

У кого есть библиотека преобразования 8 битного значения температуры в вормат вывода на семисегментный дисплеи на си?

Вот что я наваял

/*
*Сигнализация с функцией измерения температуры на DS1821
и отправкои тревожного сообщения и голосового вызова.
компилятор MicroC
*/
int tmp;
void main() {
ADCON1  = 0x03;            // Порт А цифровои, 00000111
TRISA   = 0xFF;            // на вход (кнопки)
TRISB   = 0   ;            // на выход (датчик темп)
TRISC   = 0   ;            // На выход, подключен индикатор
TRISD   = 0   ;            // На выход  катод индикатора и зумер
Ow_Reset(&PORTB, RB0);       // Посылаем сигнал сброса
Ow_Write(&PORTB, RB0, 0x0C);  // Инициализируем  конфиг регистр
Ow_Write(&PORTB, RB0, 0b01000001); //Запишем конфиг(одноразовое преобразование)
Ow_Reset(&PORTB, RB0);
Delay_us(30);              //Задержка
Ow_Write(PORTB, RB0, 0xEE);  // Начало преобразования
 TRISB  = 1   ;               //На вход
 Delay_us(15)  ;
tmp = Ow_Read(PORTB,RB0);    // Прочитаем Температуру
}

Если допустить что это все заработает, то дальше надо вывести tmp на два разряда семисегментных индикаторов.

Не цитируите полностью предыдущее сообщение!!!

Ссылка на комментарий
Поделиться на другие сайты

ind_1 = tmp/10;   // Первый индикатор это десятки
ind_2 = tmp%10;   // Второй - еденицы (остаток от деления на 10)

:)

Ваш код не заработает. Во первых, у программы не должно быть конца. Поставьте в конце ф-ии main такой код

while(1){

}

Во вторых, между командой преобразования и командой чтения температуры должно пройти время ( >750 mS ). А у Вас всего 15 uS.

Ссылка на комментарий
Поделиться на другие сайты

Предыдущий бред удалил.

Вот так то у меня получше получилось

 компилятор MicroC
*/
int tmp;
void main() {
ADCON1  = 0x03;            // Порт А цифровои, 00000111
TRISA   = 0xFF;            // на вход (кнопки)
TRISB   = 0   ;            // на выход (датчик темп)
TRISC   = 0   ;            // На выход, подключен индикатор
TRISD   = 0   ;            // На выход  катод индикатора и зумер
}
Temp_DS(int ind_1, int ind_2)
{
Ow_Reset(&PORTB, RB0);     // Посылаем сигнал сброса
Delay_us(30);
Ow_Write(&PORTB, RB0, 0x0C);  // Инициализируем  конфиг регистр
Ow_Write(&PORTB, RB0, 0b01000001); //Запишем конфиг(одноразовое преобразование)
Ow_Reset(&PORTB, RB0);
Delay_us(30);              //Задержка
Ow_Write(PORTB, RB0, 0xEE);  // Начало преобразования
 TRISB  = 1   ;               //На вход
 Delay_us(800)  ;
tmp = Ow_Read(PORTB,RB0);     // Прочитаем Температуру
ind_1 = tmp/10,ind_2 = tmp%10 ; // Два регистра с десятками и единицами.
}

Изменено пользователем Andrey_Ch8

Не цитируите полностью предыдущее сообщение!!!

Ссылка на комментарий
Поделиться на другие сайты

И компилятор потянет за собой библиотеки умножения и деления...

И потом, 8 бит это 3 разряда... да и почему получается 8 бит? с термометра снимается значение 12 бит, которое надо преобразовать поскольку единица этого значения означает 0.125 градусов. Значение надо сдвинуть на 3 разряда(поделить на 8 с учетом знака) и получим значение в градусах.

Затем можно простым пересчетом - цикл от значения температуры в градусах до 0 а внутри цикла прибавлять 1 к двоично-десятичному счетчику. Либо воспользоваться одним из алгоритмов преобразования Bin2BCD с приглянувшимися ВАМ параметрами(разрядность, быстродействие, потребление памяти) которые можно найти в интернете. Получим в результате двоичное число, каждые 4 бита которого будут представлять отдельную цифру - каждую половину байта выделить, по таблице найти соответствие сегментам индикатора и выводить их.

Для начала просто попробуй выводить в 16-ричном виде.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Ничего нового, все эти книги гугл выдает при запросе "програмирование микроконтролер", вот хорошая статейка по си, но опять же самые азы.

http://eugenemcu.ru/publ/2-1-0-51

Нет мои датчик 8ми битный , это написано в даташите

The core functionality of the DS1821 is its proprietary direct-to-digital temperature sensor, which

provides 8-bit (1°C increment) centigrade temperature readings over the range of -55°C to +125°C.

Причем значения мастеру скидывает со знаком, то есть

+125°C* 0111 1101 7Dh
+85°C 0101 0101 55h
+25°C 0001 1001 19h
0°C 0000 0000 00h
-1°C 1111 1111 FFh
-25°C 1110 0111 E7h
-55°C 1100 1001 C9h

Изменено пользователем Andrey_Ch8

Не цитируите полностью предыдущее сообщение!!!

Ссылка на комментарий
Поделиться на другие сайты

Лучше с ассемблера.

Когда вообще ничего не знаешь про МК, писать сразу на Си и трудно и бестолково - как будто слепой улицу переходишь.

Потом возникают глупые вопросы, ответы на которые в асме очевидны...

Но вопросы можно задавать любые... Даже и глупые. :rolleyes::)

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Функции типа void

Следует использовать ключевое слово void как тип значения, возвращаемого функцией, если функция ничего не возвращает.

Что это значит, если функция ничего не возвращает, тип возвращаемого значения это void?

Не цитируите полностью предыдущее сообщение!!!

Ссылка на комментарий
Поделиться на другие сайты

А ну с этим все понятно, просто переводим воид на руский, Функции типа "Пустота"

Следует использовать ключевое слово "пустота" как тип значения, возвращаемого функцией, если функция ничего не возвращает.

А как мгне быть с таблицеи перевода двоично-десятичного в код семисегментных индикаторов???

где мне взять много много исходных кодов на си , желательно под пик. чтобы хоть такие вопросы не спрашивать, я даже не представляю себе как может выглядеть эта таблица

Изменено пользователем Andrey_Ch8

Не цитируите полностью предыдущее сообщение!!!

Ссылка на комментарий
Поделиться на другие сайты

в си есть функции, и есть процедуры.

и те, и другие являются самостоятельными кусками программы, выполняющими заданный набор действий.

но у функции есть результат, как например у синуса, а процедура лишь выполняет действие, например сбрасывает биты порта, ничего не возвращая в программу.

по-простому говоря, функция может стоять справа знака равенства, процедура нет.

чтобы функция результат вернула в программу, она должна в конце положить его в регистр или на стек, или как-то еще, что задается архитектурой процессора.

на это требуются дополнительные команды, расходуется место в памяти - а для типа void никаких специфических действий в коде компилятор не предпринимает, прошивка становится компактнее и быстрее работает.

в то же время, процедура может даже имея тип void возвращать значение, и не одно, используя указатели или глобальные переменные.

таблицу кодировки для индикатора можно составить самому

зная, какие сегменты к каким линиям порта присоединены, можно для каждого символа составить слово (8 бит, один байт), которое при выводе в порт включит нужные сегменты индикатора.

как раз семь бит и семь сегментов

Ссылка на комментарий
Поделиться на другие сайты

спасибо, я знаю какие сегменты подсоеденины к пинам, на ассемблере я бы использовал команду addwf pc и из таблицы вывел в порт, а на си какие деиствия надо сделать, начиная с того что у меня есть двоично дес ятичное значение для каждого разряда индикатора?

Изменено пользователем Andrey_Ch8

Не цитируите полностью предыдущее сообщение!!!

Ссылка на комментарий
Поделиться на другие сайты

Немного дополню пост mil_alex'а. Таблица это есть массив констант(как правило) с предопределёнными значениями.

Т.е. например

const char arr_seg[10]={
63,
6,
91,
79,
102,
109,
125,
7,
127,
111
}

Выбор значения из таблицы.

PORTB = arr_seg[5]; // Вывести в порт В значение 5-ого элемента таблицы.

Ссылка на комментарий
Поделиться на другие сайты

Пожалуйста, изучай. Только компилятор другой (HI-TECH), но принцип думаю будет понятен.

Схема:

post-48853-0-35867300-1289861330_thumb.jpg

При нажатии на кнопку индикаторы сдвигаются влево, а в 4-ый индикатор записвается число соответствующее нажатой кнопки. Кнопки * и # выводят пробел.

Архив с исходником и файлом протеуса

7-seg&keyboard.rar

Для тех, кому лень качать архив:

#include	"pic18.h"
#include	"delay.h"

__CONFIG(1, 0x02FF);	
__CONFIG(2, 0x0EFF);		
__CONFIG(4, 0xFF80);



void keyboard(void);
void key_press(char key_num);



unsigned char const digit[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x00};// Сегменты (цифры) 0 1 2 3 4 5 6 7 8 9 
unsigned char buf_ind[4]; // Буфер индикаторов
const char key_val[12] = {1,2,3,4,5,6,7,8,9,10,0,10};	// Коды кнопок
char buf_key[10];	// Буфер номеров нажатых кнопок
char key_flag=0;	// Флаг/счётчик нажатых кнопок. Показатель того, нажата ли кнопка и сколько их нажато до обработки




//******************************************************//
void main()
{
char tmp,i;	// Временные переменные

TRISC=0b10000000;
PORTC=0xFF;
TRISD=0b11110000;
PORTD=0xF0;
TRISB=0b11100001;
PORTB=0b00011110;

key_flag=0;


TMR1ON=1;	// Вкл. таймер 1
TMR1IF=0;	// Сбросили флаг
TMR1IE=1;	// Разрешили прерывание от TMR1
TMR1 = 65536-2500;	// Установили значение таймера на 2500 циклов


PEIE=1;
GIE=1;

//--Очищаем индикаторы--//
buf_ind[0] = ~digit[10];
buf_ind[1] = ~digit[10];
buf_ind[2] = ~digit[10];
buf_ind[3] = ~digit[10];  
//---------------------//


while(1)	// Основной цикл
{

//----- Задержка 1 сек. -------//
DelayMs(250);DelayMs(250);	
DelayMs(250);DelayMs(250);
//-----------------------------//

//---- Обрабатываем нажатые кнопки (если нажатия были) ---------//
while(key_flag){	// Пока счётчик >0
	tmp=buf_key[0]; 	// Сохраняем номер первой необработанной нажатой кнопки
	GIE=0;				// Запрещаем прерывания. ОБЯЗАТЕЛЬНО !!!!
		for(i=0;i<9;i++){	// Двигаем буфер номеров влево
			buf_key[i] = buf_key[i+1];
		}
	key_flag--;		// Счётчик нажатых кнопок -1
	GIE=1;			// Разрешаем прерывания

	key_press(tmp);	// Вызываем процедуру обработки нажатой кнопки
}	// и так все нажатия до последнего
//---------------------------------------------------------------//

}
}
//******************************************************//

//******************************************************//
void key_press(char key_num)	// Обработчик нажатой кнопки. key_num - номер нажатой кнопки
{
char i,cod;

for(i=0;i<3;i++){	// Двигаем буфер индикаторов влево
	buf_ind[i] = buf_ind[i+1];
}
cod = key_val[key_num];		// Выдираем код нажатой кнопки из таблицы
buf_ind[3] = ~digit[cod];	// В 4-ый индикатор пихаем код

}
//******************************************************//

//***** обработчик прерываний ***********************//
void interrupt _isr(void)
{
static unsigned char ind_num=0;	// Номер индикатора
static char cnt_ms=10;			// Счётчик mS для опроса кнопок


if(TMR1IF)	// Проверяем флаг
{
	TMR1IF=0;	// Сбрасываем флаг
	TMR1 = 65537-2500 + TMR1;	// Переустанавливаем таймер на 1 mS

	ind_num++;	// Следующий индикатор
	if(ind_num>3)	ind_num=0;	// Если зашкалило, выбираем первый

	PORTD &=0b11110000;	// Гасим индикаторы
	NOP();NOP();NOP();NOP();NOP();	// Небольшая задержка
	PORTC=buf_ind[ind_num];			// Выводим в порт значение текущего индикатора из буфера
	PORTD |=(1<<ind_num);			// Зажигаем текущий индикатор


	if(!--cnt_ms){	// Отсчитываем 10 mS
		cnt_ms=10;
		keyboard();	// Вызываем процедуру опроса кнопок
	}
}
}
//***************************************************//

//***************************************************//
void keyboard()
{
char i;
static char H_num=0;		// Номер опрашиваемой строки
char key_num;				// Порядковый номер опрашиваемой кнопки
char key_par[12];			// Текущие состояния кнопок
static char key_tmp[12];	// Предыдущие состояния кнопок


H_num++;		// Следующая строка
if(H_num>3){	// Если зашкалило - выбираем первую строку
H_num=0;
}
key_num =H_num*3;	// Смещаем номер опрашиваемой кнопки относительно номера строки


RB1=1;RB2=1;RB3=1;RB4=1;	// На всех строках 1-чки

if(H_num==0)	RB4=0;		// 0 на 1-й строке
if(H_num==1)	RB3=0;		// 0 на 2-й строке
if(H_num==2)	RB2=0;		// 0 на 3-й строке
if(H_num==3)	RB1=0;		// 0 на 4-й строке


if(!RB5)				// Если в 1-ом стобце лог.0
key_par[key_num]=1; // текущее состояние кнопки - нажато
else					// иначе
key_par[key_num]=0;	// cостояние - отжато

key_num++;	// Номер кнопки +1
if(!RB6)
key_par[key_num]=1;
else
key_par[key_num]=0;

key_num++;	// Номер кнопки +1
if(!RB7)
key_par[key_num]=1;
else
key_par[key_num]=0;


//---- Сохраняем текущие состояния кнопок ----//
//---- и смотрим изменения состояний ---------//
for(i=0;i<12;i++){		
if(key_tmp[i] && !key_par[i]) {	// Если предыдущее состояние было нажато и текущее отжато
	buf_key[key_flag] = i;		// Сохраняем в буфер номер нажатой кнопки
	key_flag++;					// Увеличиваем флаг/счётчик на 1
}
key_tmp[i] = key_par[i];	// Сохраняем текущие состояния
}
//-------------------------------------------//


}

Прошу обратить внимание на задержку 1 сек. в основном цикле, после которой обрабатываются нажатые кнопки.

Сделал её я не зря. Пример показывает как можно реализовать буфер нажатых кнопок для последующей обработки. Т.е. нажатия на кнопки укладываюся в некий буфер, точнее укладываются номера нажатых кнопок. Если во время этой задержки нажать несколько кнопок подряд, то по истечению задержки, нажатия все обработаются без потерь.

Вобщем юзай, изучай, спрашивай...

PS: Это мой первый опыт в опросе дин. клавы, так что критика приветствуется :)

Помогите.....

Почему мой не работает??


#include<p18f452.h>
#include <delays.h>


void keyboard(void);
void key_press(char key_num);
void InterruptHandlerHigh (void);
void InterruptHandlerLow (void);

unsigned char const digit[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x00};// Сегменти (цифри) 0 1 2 3 4 5 6 7 8 9 
unsigned char buf_ind[4]; // Буфер індикаторів
const char key_val[12] = {1,2,3,4,5,6,7,8,9,10,0,10};   // Коди кнопок (назви)
char buf_key[10];       // Буфер номерів натиснутих кнопок
char key_flag=0;        // Прапорець/лічильник натиснутих кнопок. Показник того, чи було натиснуто кнопку 
                       // і скільки їх було натиснуто для опрацювання

//******************************************************//
void main()
 {
  char tmp,i;     // Тимчасові змінні

    //Конфігурування портів PORTC i PORTD
    //ДЛЯ РОБОТИ ІНДИКАТОРА
    // 0-виходи, 1-входи
TRISC=0b10000000;
PORTC=0xFF;
TRISD=0b11110000;
PORTD=0xF0;
    //Конфігурування порту PORTВ
    //ДЛЯ РОБОТИ КЛАВІАТУРИ
TRISB=0b11100001;
PORTB=0b00011110;

 key_flag=0;
    // Налаштування таймера TMR0
T0CONbits.TMR0ON = 1;     // Вкл. таймер TMR0
INTCONbits.TMR0IF = 0;    // скинути прапорець переривань TMR0
INTCONbits.TMR0IE = 0;    // дозволити переривання при переповненні TMR0
//TMR0L = 65536-2500;       // Установили значение таймера на 2500 циклів

INTCONbits.PEIE = 1;      // дозволено всі незамасковані переферійні переривання
INTCONbits.GIE = 1;       // глобальний дозвіл переривань
RCONbits.IPEN=1;     //включити пріоритети переривань
INTCON2bits.TMR0IP=0;	//встановити пріоритет переривань від TMR0 низьким

//--Чистимо індикатори--//
buf_ind[0] = ~digit[10];       //інвертуємо значення бітів (0 на 1 або 1 на 0)
buf_ind[1] = ~digit[10];
buf_ind[2] = ~digit[10];
buf_ind[3] = ~digit[10];  
//---------------------//

    while(1)             //безмежний цикл
      {
//----- Затримка 1 сек. -------//
Delay1KTCYx(1); //Затримка
//-----------------------------//

//---- Опрацювання натиснутої кнопки (якщо такі є) ---------//
       while(key_flag)
         {                        // Поки лічильник >0
          tmp=buf_key[0];         // Зберігаємо номер першої неопрацьованої натиснутої кнопки
          INTCONbits.GIE = 0;     // Забороняємо переривання. Обов*язково!
          for(i=0;i<9;i++)
             {                    // Зсуваємо буфер номерів вліво
              buf_key[i] = buf_key[i+1];
             }
          key_flag=key_flag-1;    // Лічильник натиснутих кнопок -1
          INTCONbits.GIE = 1;     // Дозволяємо переривання

          key_press(tmp);         // Викликаємо процедуру опрацювання натиснутої кнопки
         }                        // і так всі натиснуті кнопки до останньої
//---------------------------------------------------------------//
      }
 }

void key_press(char key_num)    // Опрацювання натиснутої кнопки. key_num - номер нажатой кнопки
 {
  char i,cod;
  for(i=0;i<3;i++)
    {       // Двигаем буфер индикаторов влево
     buf_ind[i] = buf_ind[i+1];
    }
  cod = key_val[key_num];         // Выдираем код нажатой кнопки из таблицы
  buf_ind[3] = ~digit[cod];       // В 4-ый индикатор пихаем код

 }

//******************************************************//

// Вектор високопріоритетного переривань

#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{
 _asm
   goto InterruptHandlerHigh //перехід на програму опрацювання високопріоритетних переривань
 _endasm
}

// Вектор низькопріоритетного переривань
#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow (void)
{
 _asm
   goto InterruptHandlerLow //перехід на програму опрацювання низькопріоритетних переривань
 _endasm
}
//***** обработчик прерываний ***********************//

// Програма опрацювання низькопріоритетних переривань
 #pragma code
 #pragma interrupt InterruptHandlerLow
 void InterruptHandlerLow ()
 {
  static unsigned char ind_num=0; // Номер индикатора
  static char cnt_ms=10;                  // Счётчик mS для опроса кнопок
  if(INTCONbits.TMR0IF==1)      // Проверяем флаг
   {
   INTCONbits.TMR0IF=0;       // Сбрасываем флаг
 //  TMR1L = 65537-2500 + TMR1L;       // Переустанавливаем таймер на 1 mS
   ind_num++;      // Следующий индикатор
   if(ind_num>3)   
     ind_num=0;      // Если зашкалило, выбираем первый
   PORTD &=0b11110000;     // Гасим индикаторы
   Delay10TCYx(50);  // Небольшая задержка
   PORTC=buf_ind[ind_num];                 // Выводим в порт значение текущего индикатора из буфера
   PORTD |=(1<<ind_num);                   // Зажигаем текущий индикатор

   if(!--cnt_ms)
      {  // Отсчитываем 10 mS
       cnt_ms=10;
       keyboard();     // Вызываем процедуру опроса кнопок
      }
   }
 }
void keyboard()
{
char i;
static char H_num=0;            // Номер опрашиваемой строки
char key_num;                           // Порядковый номер опрашиваемой кнопки
char key_par[12];                       // Текущие состояния кнопок
static char key_tmp[12];        // Предыдущие состояния кнопок

H_num++;                // Следующая строка
if(H_num>3)
  {    // Если зашкалило - выбираем первую строку
   H_num=0;
  }
key_num =H_num*3;       // Смещаем номер опрашиваемой кнопки относительно номера строки

       // На всех строках 1-чки
PORTBbits.RB1=1;
PORTBbits.RB2=1;
PORTBbits.RB3=1;
PORTBbits.RB4=1;
//---------------------
if(H_num==0)    PORTBbits.RB4=0;          // 0 на 1-й строке
if(H_num==1)    PORTBbits.RB3=0;          // 0 на 2-й строке
if(H_num==2)    PORTBbits.RB2=0;          // 0 на 3-й строке
if(H_num==3)    PORTBbits.RB1=0;          // 0 на 4-й строке
//=========================
if(!PORTBbits.RB5)               // Если в 1-ом стобце лог.0
  key_par[key_num]=1; // текущее состояние кнопки - нажато
else                         // иначе
  key_par[key_num]=0;     // cостояние - отжато

key_num++;      // Номер кнопки +1

if(!PORTBbits.RB6)
  key_par[key_num]=1;
else
  key_par[key_num]=0;

key_num++;      // Номер кнопки +1

if(!PORTBbits.RB7)
  key_par[key_num]=1;
else
  key_par[key_num]=0;
//=========================
//---- Сохраняем текущие состояния кнопок ----//
//---- и смотрим изменения состояний ---------//
for(i=0;i<12;i++)
  {              
   if(key_tmp[i] && !key_par[i]) 
      { // Если предыдущее состояние было нажато и текущее отжато
       buf_key[key_flag] = i;          // Сохраняем в буфер номер нажатой кнопки
       key_flag++;                                     // Увеличиваем флаг/счётчик на 1
      }
   key_tmp[i] = key_par[i];        // Сохраняем текущие состояния
  }
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Програма опрацювання високопріоритетних переривань
#pragma code
#pragma interrupt InterruptHandlerHigh

void InterruptHandlerHigh ()
 {
 }





Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...