реклама на сайте
подробности

 
 
> Светодиодиодна индикация на PIC18F6722, Как правильно написать программу?
Andbiz
сообщение Aug 16 2012, 16:40
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 447
Регистрация: 16-11-08
Из: Украина, Донецк
Пользователь №: 41 684



Здравствуйте, уважаемые форумчане!
Пробую освоить микроконтроллер PIC18F6722. Программа для работы – MPLAB IDE v8.86 + компилятор С18. Программатор – MPLAB ICD3. Есть плата, на которой уже установлен данный микроконтроллер и есть светодиоды, которые можно «позажигать», чтобы немного разобраться в работе данного МК.

Вот схемы платы:
Прикрепленное изображение

Прикрепленное изображение

Прикрепленное изображение


Микроконтроллер показан на третьей схеме.
Кварц стоит внешний – на 6 Мгц. Также используется внешний сторожевой ждущий таймер ADM706, который подключен к выводу 2 (RE0), которым нужно периодически давать импульсы, чтобы сбрасывать данный таймер и он не подал сигнал на перезапуск МК (я так понимаю).

На плате есть 8 семисегментных индикаторов HL1-HL8 (KingsBright SA56-11EWA).
Я решил написать программу, при которой на них будет написаны числа 12345678.
Сигналы на выбора сегмента (D0-D7) подключены от МК к индикатору через буферный регистр хранения информации ЭКФ1533ИР22. Сигналы на разрешение включения индикатора LE4 – LE11 подаются на индикатор с того же буферного регистра ЭКФ1533ИР22, на который данные сигналы подаются с МК через дешифратор ЭКФ1533ИД7 и инвертор сигналов ЭКФ1533ЛН1. С данными микросхемами я разобрался и написал для себя таблицу значений выходов МК, при которой будет зажигаться необходимая мне комбинация цифр.

Текст программы написал следующий:

Код
#include <p18f6722.h>

#pragma config OSC = XT // Применяю внешний кварцевый резонатор
#pragma config WDT = OFF // Внутренний сторожевой таймер отключаю - применяется внешний, который нужно периодически обнулять

void main (void)
{
    TRISD = 0;
    TRISE = 0;

    PORTD = 0; // Сбрасываю значения на порте D
    PORTE = 0; // Сбрасываю значения на порте E
    
    PORTD = 0xF9; // Принимаю соответствующие значения сегментов для индикатора HL1
    PORTE = 0x3; // Разрешаю индикацию индикатора HL1

    PORTD = 0xA4; // Принимаю соответствующие значения сегментов для индикатора HL2
    PORTE = 0x4; // Разрешаю индикацию индикатора HL2

    PORTD = 0xB0; // Принимаю соответствующие значения сегментов для индикатора HL3
    PORTE = 0x5; // Разрешаю индикацию индикатора HL3

    PORTD = 0x99; // Принимаю соответствующие значения сегментов для индикатора HL4
    PORTE = 0x6; // Разрешаю индикацию индикатора HL4

    PORTD = 0x92; // Принимаю соответствующие значения сегментов для индикатора HL5
    PORTE = 0x7; // Разрешаю индикацию индикатора HL5

    PORTD = 0x82; // Принимаю соответствующие значения сегментов для индикатора HL6
    PORTE = 0x8; // Разрешаю индикацию индикатора HL6

    PORTD = 0xF8; // Принимаю соответствующие значения сегментов для индикатора HL7
    PORTE = 0x9; // Разрешаю индикацию индикатора HL7

    PORTD = 0x80; // Принимаю соответствующие значения сегментов для индикатора HL8
    PORTE = 0xA; // Разрешаю индикацию индикатора HL8
    
    while (1); // Организую бесконечный цикл, для того, чтобы индикация светодиодов была постоянной
}


Программу скомпилировал, все прошло нормально, но прошивать МК еще не стал – решил спросить совета. Как я понимаю, при данной программе на мгновение должна появиться комбинация 12345678, т.к. с вывод микроконтроллера RE0 сигнал подается на ждущий таймер и индикаторы. Данный вывод у меня будет задействован в индикации и будет периодически менять свое значение, т.е. будет сбрасываться. Правильно ли я думаю? Правильно ли я написал программу? Правильно ли я указал конфигурационные биты в начале программы?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Andbiz
сообщение Aug 20 2012, 15:28
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 447
Регистрация: 16-11-08
Из: Украина, Донецк
Пользователь №: 41 684



Большое спасибо за помощь!

Цитата
на ИР22 (SN74LS373) остаются (хранятся) те данные, которые были во время перехода H->L.
то есть те данные, которые были в момент отключения канала дешифратора (Дешифратор активный 0, но у Вас еще инвертор после него есть)


Я обратил внимание на это. Но потом подумал, что это будет влиять в тот, момент, когда индикация будет меняться. А у меня она пока не изменяется.

По поводу комментариев – поправил.
По поводу констант понял.
По поводу склонения слова «Порт» - буду иметь ввиду.

Цитата
Основной штамп на первом листе Вы благоразумно затерли, иначе я бы оперировал конкретным именем разработчика


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

Текст программы после исправления получился вот таким:

Код
#include <p18f6722.h>

#pragma config OSC = XT        // Применяю внешний кварцевый резонатор
#pragma config WDT = OFF    // Внутренний сторожевой таймер отключаю - применяется внешний, который нужно периодически обнулять сигналом ADR0

#define ADDR_HL1 0x3    // определяю адрес первого индикатора HL1 0x03, как переменную ADDR_HL1
#define ADDR_HL2 0x4    // определяю адрес второго индикатора HL2 0x04, как переменную ADDR_HL2
#define ADDR_HL3 0x5    // определяю адрес третьего индикатора HL3 0x05, как переменную ADDR_HL3
#define ADDR_HL4 0x6    // определяю адрес четвертого индикатора HL4 0x06, как переменную ADDR_HL4
#define ADDR_HL5 0x7    // определяю адрес пятого индикатора HL5 0x07, как переменную ADDR_HL5
#define ADDR_HL6 0x8    // определяю адрес шестого индикатора HL6 0x08, как переменную ADDR_HL6
#define ADDR_HL7 0x9    // определяю адрес седьмого индикатора HL7 0x09, как переменную ADDR_HL7
#define ADDR_HL8 0xA    // определяю адрес восьмого индикатора HL8 0x0A, как переменную ADDR_HL8
#define ADDR_HL_NO_SELECT 0x00       //определяю переменную, при которой не будет не задействован ни один индикатор HL1-HL8

#define LEDCODE_0 0xC0    //определяю переменную, при которой на индикаторе будет отображаться "0"
#define LEDCODE_1 0xF9    //определяю переменную, при которой на индикаторе будет отображаться "1"
#define LEDCODE_2 0xA4    //определяю переменную, при которой на индикаторе будет отображаться "2"
#define LEDCODE_3 0xB0    //определяю переменную, при которой на индикаторе будет отображаться "3"
#define LEDCODE_4 0x99    //определяю переменную, при которой на индикаторе будет отображаться "4"
#define LEDCODE_5 0x92    //определяю переменную, при которой на индикаторе будет отображаться "5"
#define LEDCODE_6 0x82    //определяю переменную, при которой на индикаторе будет отображаться "6"
#define LEDCODE_7 0xF8    //определяю переменную, при которой на индикаторе будет отображаться "7"
#define LEDCODE_8 0x80    //определяю переменную, при которой на индикаторе будет отображаться "8"
#define LEDCODE_9 0x90    //определяю переменную, при которой на индикаторе будет отображаться "9"

#define PORT_DATA PORTD    //определяю PORTD, как переменную PORT_DATA
#define PORT_ADDR PORTE    //определяю PORTE, как переменную PORT_ADDR

void Indicator(char addrCode, char dataCode);    //определяю функцию с именем Indicator, char - символьный тип данных

void Indicator(char addrCode, char dataCode)    //ввожу параметры функции, т.е. значения, которые будут находиться под именам addrCode и dataCode.
{
    PORT_ADDR = addrCode;    //под параметром addrCode будет значение переменной PORT_ADDR
    PORT_DATA = dataCode;    //под параметром dataCode будет значение переменной PORT_DATA
}

void main (void)    // точка входа в саму программу
{
    TRISD = 0;    // выводы порта D микроконтроллера определяю, как выходы
    TRISE = 0;    // выводы порта Е микроконтроллера определяю, как выходы

    Indicator(ADDR_HL1,LEDCODE_1);    //на индикатор HL1 вывожу число "1"
    Indicator(ADDR_HL2,LEDCODE_2);    //на индикатор HL2 вывожу число "2"
    Indicator(ADDR_HL3,LEDCODE_3);    //на индикатор HL3 вывожу число "3"
    Indicator(ADDR_HL4,LEDCODE_4);    //на индикатор HL4 вывожу число "4"
    Indicator(ADDR_HL5,LEDCODE_5);    //на индикатор HL5 вывожу число "5"
    Indicator(ADDR_HL6,LEDCODE_6);    //на индикатор HL6 вывожу число "6"
    Indicator(ADDR_HL7,LEDCODE_7);    //на индикатор HL7 вывожу число "7"
    Indicator(ADDR_HL8,LEDCODE_8);    //на индикатор HL8 вывожу число "8"
      
        while(1);  // Организую бесконечный цикл, для того, чтобы индикация светодиодов была постоянной. Цикл прерывается перезапуском или выключением платы.
}


Переменным ADDR, LEDCODE, PORT_DATA и PORT_ADDR приравнены константы вне функции main, поэтому они глобальные.

void Indicator(char addrCode, char dataCode); - тут, как я понимаю, производиться объявление функции до ее использования. Void – ставиться, т.к. в моем понимании значение функции «возвращается», используется в дальнейшем участке схемы, т.е. сюда «возвращаются».

Код
//сами функции
void Indicator(char addrCode, char dataCode)
{
    PORT_ADDR = addrCode;
    PORT_DATA = dataCode;
    
}


Тут, как я понимаю, производиться заполнение фунции, объявленной ранее, т.е. приравниваются значения PORT_ADDR и PORT_DATA некоторым значениям, которые будут указаны позже в тексте программы. Void – ставиться, т.к. сюда также возвращаются в дальнейшем при работе самой программы.
Текст самой программы обозначается void main (void) – когда работа доходит до этого участка, то все работает на этом участке и по мере необходимости (в процессе выполнения программы) происходит возврат в участки, обозначенные, как . Void, в которых происходит «переопределение» каких-либо переменных.

Вопросы:
1) Ваша программа полностью работает, если убрать строчку:
Код
    PORT_ADDR = ADDR_HL_NO_SELECT;     // в этот момент защелкиваются данные на HL1

Если она есть, код 12345678 на индикаторах высвечивается, но периодически появляются одно временно восьмерки на HL3 и HL7 или HL5 и HL7.
Без этой строчки все хорошо. А зачем она?
2) В моей программе не использовалось предопределение констант перемеными при помощи #define и не использовалась функция. В остальном она как будто-бы подобна Вашей. Но Ваша все же работает. Почему не работала моя программа? Почему происходила неправильная индикация?
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Andbiz   Светодиодиодна индикация на PIC18F6722   Aug 16 2012, 16:40
- - Andbiz   Программу записал в МК. В результате получилась сл...   Aug 17 2012, 17:29
|- - Ruslan1   на ИР22 (SN74LS373) остаются (хранятся) те данные,...   Aug 17 2012, 19:53
- - ILYAUL   Цитата1. Коментарии должны быть полезны, а не прос...   Aug 17 2012, 20:14
|- - Ruslan1   Цитата(Andbiz @ Aug 20 2012, 18:28) Я обр...   Aug 20 2012, 17:20
- - Andbiz   Сигнал LE1 идет на микросхему D7 ЭКФ1533ИР22 (перв...   Aug 20 2012, 17:52
- - Andbiz   Написал другую программу. Предприятие, на котором ...   Aug 21 2012, 15:40
|- - _Артём_   Цитата(Andbiz @ Aug 21 2012, 18:40) Прогр...   Aug 21 2012, 15:55
- - esaulenka   Маленький совет: при написании комментариев забыть...   Aug 21 2012, 16:28
|- - _Артём_   Цитата(esaulenka @ Aug 21 2012, 19:28) Ма...   Aug 21 2012, 16:36
- - _Ivana   Да, читая комментарии я только ещё больше путаюсь ...   Aug 21 2012, 16:43
- - esaulenka   и о ЦАПах, которые на самом деле очень даже АЦП Ц...   Aug 21 2012, 17:23
- - Andbiz   _Артём_ Спасибо, понял – более компактный код можн...   Aug 22 2012, 17:01
|- - Ruslan1   Про индикацию: самое простое для разборок- это 1. ...   Aug 23 2012, 08:54
- - esaulenka   Цитата1) За return должно следовать выражение в ск...   Aug 23 2012, 11:46
- - Andbiz   Спасибо! Программу сделал. Код получился следу...   Aug 31 2012, 18:51
- - Andbiz   Программу для ввода текста сделал – вводит в...   Sep 5 2012, 14:15
- - Andbiz   Вопрос еще по поводу функции sprintf . Могу ли я и...   Sep 5 2012, 19:01
- - esaulenka   Вот зачем, интересно, мы тут кучу советов надавали...   Sep 6 2012, 11:26
|- - Andbiz   Цитата(esaulenka @ Sep 6 2012, 14:26) Вот...   Sep 6 2012, 14:50
- - esaulenka   ЦитатаПри нажатии клавиши может отобразиться много...   Sep 7 2012, 09:31


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st August 2025 - 08:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.01487 секунд с 7
ELECTRONIX ©2004-2016