Написал другую программу. Предприятие, на котором я работаю, связано с обслуживание электроприводов. При этом на приводах часто применяют индикацию, при которой семисегментные индикаторы зажигают свои сегменты в соответствии с вращением двигателя – т.е. по часовой, либо против часовой. Частота изменения сегментов соответствует скорости вращения двигателя.
Предложили попробовать написать такую программу, чтобы она просто изменяла свои сегменты по часовой стрелке. Попробовал – получилась вот такая:
Код
#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_X 0xFF //определяю переменную, при которой на индикаторе не будет отображаться ни один сегмент
#define LEDCODE_a 0xFE //определяю переменную, при которой на индикаторе будет отображаться сегмент "a"
#define LEDCODE_b 0xFD //определяю переменную, при которой на индикаторе будет отображаться сегмент "b"
#define LEDCODE_c 0xFB //определяю переменную, при которой на индикаторе будет отображаться сегмент "c"
#define LEDCODE_d 0xF7 //определяю переменную, при которой на индикаторе будет отображаться сегмент "d"
#define LEDCODE_e 0xEF //определяю переменную, при которой на индикаторе будет отображаться сегмент "e"
#define LEDCODE_f 0xDF //определяю переменную, при которой на индикаторе будет отображаться сегмент "f"
#define LEDCODE_g 0xBF //определяю переменную, при которой на индикаторе будет отображаться сегмент "g"
#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 delay (void) //организую подпрограмму задержки
{
unsigned int i;
for (i==0; i<6000; i++); //длительность задержки опрделяется величиной i
}
void main (void) // точка входа в саму программу
{
TRISD = 0; // выводы порта D микроконтроллера определяю, как выходы
TRISE = 0; // выводы порта Е микроконтроллера определяю, как выходы
Indicator(ADDR_HL1,LEDCODE_X); //сбрасываю индикатор HL1
Indicator(ADDR_HL2,LEDCODE_X); //сбрасываю индикатор HL2
Indicator(ADDR_HL3,LEDCODE_X); //сбрасываю индикатор HL3
Indicator(ADDR_HL4,LEDCODE_X); //сбрасываю индикатор HL4
Indicator(ADDR_HL5,LEDCODE_X); //сбрасываю индикатор HL5
Indicator(ADDR_HL6,LEDCODE_X); //сбрасываю индикатор HL6
Indicator(ADDR_HL7,LEDCODE_X); //сбрасываю индикатор HL7
Indicator(ADDR_HL8,LEDCODE_X); //сбрасываю индикатор HL8
while(1) // Организую бесконечный цикл
{
char j, n; // объявляю локальную переменную n - число счета и j - счетчик
n=6;
for (j=0;j<n;j++) //начинаю цикл перебора сегментов
{
if (j==0)
{
Indicator(ADDR_HL1,LEDCODE_a); //зажигаю сегмент "a"
Indicator(ADDR_HL2,LEDCODE_a); //зажигаю сегмент "a"
Indicator(ADDR_HL3,LEDCODE_a); //зажигаю сегмент "a"
Indicator(ADDR_HL4,LEDCODE_a); //зажигаю сегмент "a"
Indicator(ADDR_HL5,LEDCODE_a); //зажигаю сегмент "a"
Indicator(ADDR_HL6,LEDCODE_a); //зажигаю сегмент "a"
Indicator(ADDR_HL7,LEDCODE_a); //зажигаю сегмент "a"
Indicator(ADDR_HL8,LEDCODE_a); //зажигаю сегмент "a"
delay (); //пауза
}
else if (j==1)
{
Indicator(ADDR_HL1,LEDCODE_b); //зажигаю сегмент "b"
Indicator(ADDR_HL2,LEDCODE_b); //зажигаю сегмент "b"
Indicator(ADDR_HL3,LEDCODE_b); //зажигаю сегмент "b"
Indicator(ADDR_HL4,LEDCODE_b); //зажигаю сегмент "b"
Indicator(ADDR_HL5,LEDCODE_b); //зажигаю сегмент "b"
Indicator(ADDR_HL6,LEDCODE_b); //зажигаю сегмент "b"
Indicator(ADDR_HL7,LEDCODE_b); //зажигаю сегмент "b"
Indicator(ADDR_HL8,LEDCODE_b); //зажигаю сегмент "b"
delay (); //пауза
}
else if (j==2)
{
Indicator(ADDR_HL1,LEDCODE_c); //зажигаю сегмент "c"
Indicator(ADDR_HL2,LEDCODE_c); //зажигаю сегмент "c"
Indicator(ADDR_HL3,LEDCODE_c); //зажигаю сегмент "c"
Indicator(ADDR_HL4,LEDCODE_c); //зажигаю сегмент "c"
Indicator(ADDR_HL5,LEDCODE_c); //зажигаю сегмент "c"
Indicator(ADDR_HL6,LEDCODE_c); //зажигаю сегмент "c"
Indicator(ADDR_HL7,LEDCODE_c); //зажигаю сегмент "c"
Indicator(ADDR_HL8,LEDCODE_c); //зажигаю сегмент "c"
delay (); //пауза
}
else if (j==3)
{
Indicator(ADDR_HL1,LEDCODE_d); //зажигаю сегмент "d"
Indicator(ADDR_HL2,LEDCODE_d); //зажигаю сегмент "d"
Indicator(ADDR_HL3,LEDCODE_d); //зажигаю сегмент "d"
Indicator(ADDR_HL4,LEDCODE_d); //зажигаю сегмент "d"
Indicator(ADDR_HL5,LEDCODE_d); //зажигаю сегмент "d"
Indicator(ADDR_HL6,LEDCODE_d); //зажигаю сегмент "d"
Indicator(ADDR_HL7,LEDCODE_d); //зажигаю сегмент "d"
Indicator(ADDR_HL8,LEDCODE_d); //зажигаю сегмент "d"
delay (); //пауза
}
else if (j==4)
{
Indicator(ADDR_HL1,LEDCODE_e); //зажигаю сегмент "e"
Indicator(ADDR_HL2,LEDCODE_e); //зажигаю сегмент "e"
Indicator(ADDR_HL3,LEDCODE_e); //зажигаю сегмент "e"
Indicator(ADDR_HL4,LEDCODE_e); //зажигаю сегмент "e"
Indicator(ADDR_HL5,LEDCODE_e); //зажигаю сегмент "e"
Indicator(ADDR_HL6,LEDCODE_e); //зажигаю сегмент "e"
Indicator(ADDR_HL7,LEDCODE_e); //зажигаю сегмент "e"
Indicator(ADDR_HL8,LEDCODE_e); //зажигаю сегмент "e"
delay (); //пауза
}
else if (j==5)
{
Indicator(ADDR_HL1,LEDCODE_f); //зажигаю сегмент "f"
Indicator(ADDR_HL2,LEDCODE_f); //зажигаю сегмент "f"
Indicator(ADDR_HL3,LEDCODE_f); //зажигаю сегмент "f"
Indicator(ADDR_HL4,LEDCODE_f); //зажигаю сегмент "f"
Indicator(ADDR_HL5,LEDCODE_f); //зажигаю сегмент "f"
Indicator(ADDR_HL6,LEDCODE_f); //зажигаю сегмент "f"
Indicator(ADDR_HL7,LEDCODE_f); //зажигаю сегмент "f"
Indicator(ADDR_HL8,LEDCODE_f); //зажигаю сегмент "f"
delay (); //пауза
}
}
}
}
Программа работает, сегменты изменяются.
Вопросы:
1) Правильно ли я организовал программу?
2) Есть ли методы, при которых программа была бы более компактной?
Теперь на работе предложили написать программу, при которой был бы задействован какой-то вход под АЦП. На данный вход подается напряжение до 5 В и это напряжение должно индикатироваться на индикаторе. Точность – до сотой (0,01) вольта.
PIC18F6722 – содержит 12 аналоговых входов (5 входов на PORTF – AN0-AN4 и 7 входов на PORTF – AN5-AN11). Выводы МК AN0-AN4 задействованы для подключения клавиатуры через дешифратор D4, поэтому их использовать не получиться. Выводы – AN5-AN10 (ножки 13-18) используются на плате для вывода изображения на ЖКИ. Они выводятся напрямую на разъем Х10.
В качестве аналоговых входов выбрал AN5 и AN6.
Как я понимаю, при работе ЦАП необходимо опорное напряжение, относительно которого будет производиться измерение напряжения.
VREF+ (21 ножка МК) - не задействована и не подключена. Микросхема в корпусе 64-Pin TQFP. Шаг ножек очень мелкий, припаять провод проблематично.
VREF- (22 ножка МК) задействована в качестве выхода под дешифратор D4. Вывода AVDD и AVSS (ножки 19 и 20) не подключены - подпаяться тоже проблематично.
Как я понимаю, организовать ЦАП без использования этих входов невозможно, т.е. создание на этой плате устройства с применением ЦАП (измерение напряжения).
Верно?