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

Динамическая Индикация


Vitaliy129

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

Всем добрый вечер. Проблема следующая. Есть плата STM32VL Discovery. К ней цепляется з-х разрядный семисегментный индикатор. Цифры предполагается выводить динамически. Но при выводе первого разряда вместе с ним подсвечивается и второй, при выводе 2-го подсвечивается 3-й и соответственно при выводе 3-го подсвечивается 1-й. Пробовал различные частоты вывода и применять задержки между выключением предыдущего индикатора и включением последующего. В чём может быть дело??? На Си только начинаю программировать, поэтому код скорее всего не эффективный, но всё же.

Жду ваших ответов.


#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
#define IND_PORT GPIOA// This port is responsible for the display of "IND_PORT"
#define D1 GPIO_Pin_0//This conclusion is responsible for 1st indicator
#define D2 GPIO_Pin_1//This conclusion is responsible for 2nd indicator
#define D3 GPIO_Pin_2//This conclusion is responsible for 3rd indicator
// A segment of the indicator - the output of the microcontroller
#define SEG_A GPIO_Pin_0// seg "A"
#define SEG_B GPIO_Pin_1// seg "B"
#define SEG_C GPIO_Pin_2// seg "C"
#define SEG_D GPIO_Pin_3// seg "D"
#define SEG_E GPIO_Pin_4// seg "E"
#define SEG_F GPIO_Pin_5// seg "F"
#define SEG_G GPIO_Pin_6// seg "G"
#define DP GPIO_Pin_7   //Decimal point
// Create the numbers of segments
#define DIG0 ( SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F )
#define DIG1 ( SEG_B | SEG_C )
#define DIG2 ( SEG_A | SEG_B | SEG_G | SEG_E | SEG_D )
#define DIG3 ( SEG_A | SEG_B | SEG_G | SEG_C | SEG_D )
#define DIG4 ( SEG_F | SEG_G | SEG_B | SEG_C)
#define DIG5 ( SEG_A | SEG_F | SEG_G | SEG_C | SEG_D )
#define DIG6 ( SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G )
#define DIG7 ( SEG_A | SEG_B | SEG_C )
#define DIG8 ( SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define DIG9 ( SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G)
#define ALL_PINS (DIG8 | D1 | D2 | D3 )

// Delay
void Delay (void);
void Delay (void)
{
 unsigned long i;
 for (i=0; i<20000; i++);
}
//


#define TIMER_PRESCALER 720
uint8_t previousState;
uint8_t IND_State;
GPIO_InitTypeDef port;//???
TIM_TimeBaseInitTypeDef timer;
uint8_t counter1;
uint8_t counter2;
uint8_t counter3;
uint8_t rez;
uint8_t digit;

void digit_to_port (uint8_t digit){
uint8_t digitsp[]={DIG0,DIG1,DIG2,DIG3,DIG4,DIG5,DIG6,DIG7,DIG8,DIG9};
IND_PORT->ODR &= ~DIG8;
IND_PORT->ODR |= digitsp[digit];
}
//

void initAll()
{
 GPIO_InitTypeDef port;//???
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //On port "A"
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //On port "B"
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //On timer "Tim 4"

 GPIO_StructInit(&port);
//Port "A" input
   port.GPIO_Mode = GPIO_Mode_Out_PP;  
   port.GPIO_Pin = DIG8 | DP; 
   port.GPIO_Speed = GPIO_Speed_2MHz;  
   GPIO_Init(GPIOA, &port);

//Port "B" output
 port.GPIO_Mode = GPIO_Mode_Out_PP;
 port.GPIO_Pin =D1 | D2 | D3;
 port.GPIO_Speed = GPIO_Speed_2MHz; 
 GPIO_Init(GPIOB, &port); 
// Timer
 TIM_TimeBaseStructInit(&timer);
   timer.TIM_Prescaler = TIMER_PRESCALER;
   timer.TIM_Period = 5000;
   TIM_TimeBaseInit(TIM4, &timer);
}

//
int main()
{
   __enable_irq();
   initAll();
   TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
   TIM_Cmd(TIM4, ENABLE);
   NVIC_EnableIRQ(TIM4_IRQn);
 IND_State=1;
 counter1=1;
 counter2=2;
 counter3=7;
   while(1)
   {
__NOP();
   } 
}
//


void TIM4_IRQHandler()
{

   if (IND_State == 1)
   {
  GPIO_ResetBits(GPIOB, D1|D2|D3);
  GPIO_ResetBits(GPIOA,  DIG8);
  Delay();
  IND_State=2;

  GPIO_SetBits(GPIOB, D1);

  digit_to_port(counter1);
  timer.TIM_Period = 50000;
  TIM_TimeBaseInit(TIM4, &timer);
  TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
 }
 else
 {
  if (IND_State == 2)
  {
  GPIO_ResetBits(GPIOB,  D1|D2|D3);
  GPIO_ResetBits(GPIOA,  DIG8);
  Delay();
  IND_State=3;
  GPIO_SetBits(GPIOB, D2);

  digit_to_port(counter2);
  timer.TIM_Period = 50000;
  TIM_TimeBaseInit(TIM4, &timer);
  TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
  }
  else
  {
  GPIO_ResetBits(GPIOB,  D1|D2|D3);
  GPIO_ResetBits(GPIOA,  DIG8);
  Delay();
  IND_State=1;
  GPIO_SetBits(GPIOB, D3);

  digit_to_port(counter3);
  timer.TIM_Period = 50000;
  TIM_TimeBaseInit(TIM4, &timer);
  TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
  }
 }
}  

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

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

В код не вникал, но подобная проблема у меня была с СД матрицей 8х8. Попробуй так:

1. Гасим все разряды

2. Устанавливаем значение порта А (сегменты)

3. Включаем нужный пин порта В (разряд индикатора)

4. Пауза

5. Переход в п.1

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

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

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

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

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

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

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

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

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

Так попробуй:

GPIO_ResetBits(GPIOB, D1|D2|D3);
GPIO_ResetBits(GPIOA, DIG8);
GPIO_SetBits(GPIOB, D2);
Delay();
IND_State=3;

ПС Зачем куча "ифов", используй switch или что там в вашей среде типа select case?

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

Изменено пользователем КЭС
Ссылка на комментарий
Поделиться на другие сайты

"Дин.индикацию обычно организуют, используя прерывания по таймеру." Она и организована по прерыванию от таймера. Функция Delay() введена для попытки сделать небольшое "мёртвое" время между переключениями., По поводу "if" я только начинаю программировать и не сильно знаком с СИ и этим МК.

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

GPIO_ResetBits(GPIOB, D1|D2|D3); достаточно поставить один раз, в начале прерывания, до проверки такта.

GPIO_ResetBits(GPIOA, DIG8); вообще необязательно, достаточно сменить значение на новое (без предварительного обнуления)

А уже после проверки такта выставить GPIO_SetBits(GPIOB, D3);

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

  • 4 месяца спустя...

Я вот сегодня , 5 минут назад запустил 3 разрядный индикатор от СТМки : )) Счастья то сколько! А функция писалась еще для ПИКа.

Прикрепляю работающий проект под STM32F051R8

Также куски кода:

void led_out (){

clear_leds; // digit off

switch (y) // select digit
{

case 0:

IND_PORT->ODR = led_buff[0];
digit_1;
break;
case 1:

IND_PORT->ODR = led_buff[1];
digit_2;
break;

case 2:

IND_PORT->ODR = led_buff[2];
digit_3;
break;

}
if (++y>2)y=0;
}

Функция для вывода в порт данных из массива

void indication_func()
{


temp1 = temp;

temp_lcd1=temp_lcd2=temp_lcd3=0;
while (temp1>99)
{
temp1-=100;
temp_lcd3++;
}

while (temp1>9)
{
temp1-=10;
temp_lcd2++;
}

while (temp1<10 && temp1!=0)
{
temp1--;
temp_lcd1++;
}

if(temp<10)
{
led_buff[2]=led_table[temp_lcd1];
led_buff[1]=led_table[10];
led_buff[0]=led_table[10];
}
else if(temp>9 && temp<100)
{
led_buff[1]=led_table[temp_lcd1];
led_buff[2]=led_table[temp_lcd2];
led_buff[0]=led_table[10];
}
else if(temp>99)
{
led_buff[0]=led_table[temp_lcd1];
led_buff[1]=led_table[temp_lcd2];
led_buff[2]=led_table[temp_lcd3];
}

led_out();
}

Функция разложения числа на разряды

Delay(1);
indication_func();
if(timer>5){temp++; timer=0;}
timer++;

Просто крутим по кругу переменную

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

Теперь точно буду перелазить на STM32!!!

обучение STM32F051R8.rar

Что может быть лучше в радиоэлектронике, чем программирование микроконтроллеров ?

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

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

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

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

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

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

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

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

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

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

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

    • О, это очень полезные регистры! в 88 только GPIOR0 сохранил свои полезные свойства. использую их как флаги событий прерываний. для GPIOR0 адрес порта ввода-вывода 0х1Е, а значит к нему применяются команды cbi, sbi, sbic, sbis   ну и   in, out. Когда происходит прерывание, процессор переходит на адрес обработки прерывания, вот там-то мы и располагаем код: sbi   GPIOR0, 0     ;установить в 1 бит 0 в регистре GPIOR0 reti                        ;вернуться из прерывания   Без использования регистра GPIOR0, а с использованием обычного регистра код выглядел бы иначе: push   R0                          ;освобождаем регистр R0 для SREG и сохраняем его in        R0, SREG               ;сохраняем SREG в R0, все флаги операций текущей программы sbr     R23, 1<<0             ;выставляем флаг признака прерывания, например бит 0 в регистре R23 out    SREG, R0               ;восстанавливаем SREG, все флаги операций текущей программы pop   R0                          ;восстанавливаем значение R0 reti                                  ;вернуться из прерывания   Нетрудно заметить......!  
    • Сабсоник 3 порядка потом усилитель на Оу. Далее все на столе отстроить и все 
    • Вот и я думаю сделать на сдвоенном операционнике входной усилитель и сабсоник. 
    • Я всегда подозревал, что эта схема была содрана кЕтайцами с какого-то старого и хорошо известного (но не у нас) блока питания, и что в оригинале использовались именно 741 операционники. И вот тому подтверждение... Все равно те микросхемы и транзисторы что они используют в наборах, чаще всего подделки. Мне например, пришлось заменить D1047 транзистор что шел в наборе на пару таких же, но нормальных (выдраных с дохлого усилка). Транзистор из набора (маркировка явно "левая", без какого-либо намека на изготовителя) сильно грелся даже на 1,5А. Такой же транзистор D1047, но из усилка грелся раза в два меньше, да и маркировка "нормальная".  Подозреваю что и TL081 что в наборе идут тоже возможно что перемаркированные 741 (они супердешевые, сравнимо с 358). 741 операционники выпускали все кому не лень, аналогов было выпущено очень много за полвека.  Были и на плюс-минус 22в, надо смотреть конкретный даташит и производителя, даже от буквы в конце это зависит.  Например, есть такой аналог uA741 от ST ("микро-А741"). ua741-957400.pdf ua741.pdf MA741.PDF
    • Нет. Эта модель TRI для 3фаз. Да и вся разводка сделана для 3х фаз. EVOLUTION Mono ➞ 1~ 230V ± 10% 50/60Гц EVOLUTION Tri ➞ 3~ 400V ± 10% 50/60Гц В конце второй минуты есть внутренности, подключение и включение пульта. Можно заметить, что платы идентичные. 
    • У меня такой усь был, он никакой. 
    • Приветствую , вопрос по светодиодам HL5-10 .  В схеме они по 1.65в каждый , автор на вегалабе упомянул суммарное напряжение в каждом плече 4.7в и что допустимо применение стабилитронов.   Вопрос какое напряжение допустимо и за что отвечает? В наличии светики только 1.7в.  Насколько оправданно установка стабилитронов ?  Схему прилагаю
×
×
  • Создать...