Счётчик на микроконтроллере STM32 - Часы, таймеры, счетчики - Микроконтроллеры - Каталог статей - Собери свою радиосхему! Сайт радиолюбителей.
Среда, 16.11.2016, 20:31 Приветствую Вас Гость

Чебоксары

Главная | Регистрация | Вход | RSS

Каталог статей

Главная » Статьи » Микроконтроллеры » Часы, таймеры, счетчики

Счётчик на микроконтроллере STM32



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





Каждый сегмент индикатора это один обычный светодиод. А значит для того чтоб он не сгорел, нужно ограничить ток который через него проходит. Для этого мы будем использовать семь резисторов на на 220 ом каждый. Таким образом ток через каждую ножку подключенную к сегментам не превысит 15 мА что вполне допустимо.  Для того чтоб уменьшить нагрузку на общие выводы, в схеме применяются ключевые транзисторы. Когда на базу транзистора поступает лог 1 с контроллера, он открывается и соединяет общий вывод индикатора с землёй, тем самым принимая всю нагрузку на себя.


Схема счетчика:

схему в большем разрешении.



Транзисторы можно применить вообще любые n-p-n типа. У меня нашлись BC547 вот их то я и использовал. Четыре резистора по 1К обязательны, они ограничивают ток базы. Если таких нет, то можно заюзать другие (не слишком большого сопротивления) лишь бы транзистор полностью открывался. Теперь о кнопке. у нас она будет подключена к ноге PA0, это удобно так как эта кнопка уже есть на STM32vl Discovery и припаивать её мне не придётся. На этом описание аппаратной части можно считать законченным.


Код программы:

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
// Порт к которому подключен индикатор
#define IND_PORT GPIOB
// Общие выводы индикатора
#define D0 GPIO_Pin_7
#define D1 GPIO_Pin_8
#define D2 GPIO_Pin_9
#define D3 GPIO_Pin_10
// К какой ноге какой сегмент подключен
#define SEG_A GPIO_Pin_0
#define SEG_B GPIO_Pin_1
#define SEG_C GPIO_Pin_2
#define SEG_D GPIO_Pin_3
#define SEG_E GPIO_Pin_4
#define SEG_F GPIO_Pin_5
#define SEG_G GPIO_Pin_6
//Собираем цифры из сегментов
#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 | D0 | D1 | D2 | D3 )
 
//Функция выводит в порт нужную цифру
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 Delay(void) {
  volatile uint32_t i;
  for (i=0; i != 0x1000; i++);
}
 
int main(void) {
  uint16_t counter=0; //Счётчик нажатий
  uint16_t tmp; // Содержит копию counter
                      // (из него по очереди исключаются последние цифры)
  uint8_t digit; // В эту переменную поочередно записываются цифры
                     // из которых состоит число counter
  uint8_t button_flag=0;
  //Выключаем JTAG (он занимает ноги нужные нам)
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO , ENABLE);
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  //Настраиваем на выход все ноги подключенные к индиакатору
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
  GPIO_InitTypeDef PORT; //Структура содержащая настройки порта
  PORT.GPIO_Pin = ALL_PINS; //Указываем какие ноги нужно настроить
  PORT.GPIO_Mode = GPIO_Mode_Out_PP; // Настраиваем как выход Push-pull
  PORT.GPIO_Speed = GPIO_Speed_2MHz; // Частота 2 МГц
  GPIO_Init(IND_PORT, &PORT); //Вызываем функцию настройки порта
  //Настраиваем ногу (PA0) с кнопкой на вход
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE);
  PORT.GPIO_Pin = GPIO_Pin_0;
  PORT.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &PORT);
  while(1) {
    if ((GPIOA->IDR & 0x01)==0x01) { //Кнопка нажата ?
      if (!button_flag) counter++;
      if (counter==10000) { //Досчитали до предела ?
        counter=0; //обнуляем счётчик
      }
      button_flag=1;
      } else {
      button_flag=0;
    }
    tmp=counter;
    //Вытаскиваем первую справа цифру из числа counter
    digit = tmp % 10;
    tmp = tmp / 10;
    //Выключаем все разряды
    IND_PORT->ODR &= ~(D0|D1|D2|D3);
    //Включаем нулевой разряд индикатора
    IND_PORT->ODR |= D0;
    //Выводим цифру в нулевой разряд
    digit_to_port(digit);
    //Небольшая задержка. Пусть цифра погорит некоторое время
    Delay();
    //Вытаскиваем вторую справа цифру из числа counter
    digit = tmp % 10;
    tmp = tmp / 10;
    //Выключаем все разряды
    IND_PORT->ODR &= ~(D0|D1|D2|D3);
    //Включаем первый разряд индикатора
    IND_PORT->ODR |= D1;
    //Выводим цифру в первый разряд
    digit_to_port(digit);
    //Небольшая задержка. Пусть цифра погорит некоторое время
    Delay();
    //Вытаскиваем третью справа цифру из числа counter
    digit = tmp % 10;
    tmp = tmp / 10;
    //Выключаем все разряды
    IND_PORT->ODR &= ~(D0|D1|D2|D3);
    //Включаем второй разряд индикатора
    IND_PORT->ODR |= D2;
    //Выводим цифру в второй разряд
    digit_to_port(digit);
    //Небольшая задержка. Пусть цифра погорит некоторое время
    Delay();
    //Тут мы цифр не вытаскиваем. В переменной counter уже самая старшая цифра
    //Выключаем все разряды
    IND_PORT->ODR &= ~(D0|D1|D2|D3);
    //Включаем третий разряд индикатора
    IND_PORT->ODR |= D3;
    //Выводим цифру в третий разряд
    digit_to_port(tmp);
    //Небольшая задержка. Пусть цифра погорит некоторое время
    Delay();
  }
}



При создании новго проекта в CooCox'e нужно не забыть поставить галку GPIO. С использованием этой библиотеки код становится более читаемым, не нужно помнить о том для чего нужен каждый бит. Многое в этом коде откомментировано, думаю что особых проблем с пониманием написанного не возникнет. Ну а если вопросы появятся то можно задать их чуть ниже. Компилируем, прошиваем, запускаем и получаем в результате что-то типа такого:



Работает! Жмем кнопку - значение счётчика увеличивается. Теперь можно сделать для всего этого отдельный корпус и найти счётчику достойное применение :-)



Категория: Часы, таймеры, счетчики | Добавил: (24.06.2012)
Просмотров: 3039 | Теги: счетчик, STM32 | Рейтинг: 5.0/2
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа
Логин:
Пароль:
Категории раздела
Источники питания и приборы
Охрана и контроль доступа
Измерительные устройства
Часы, таймеры, счетчики
Световые эффекты
Защита и контроль
Для начинающих
Разное
BASCOM AVR
Информация по МК, FAQ
Поиск
Наш опрос
Какие МК вы предпочитаете?
Всего ответов: 119

Статистика

Онлайн всего: 6
Гостей: 6
Пользователей: 0
Подавляющее количество часов на Atmega8 выполнены с использо...

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

да, причем у каждого канала своя нагрузка