Atmega8515 делаем кубик на языке С в MPLab X

Ниже Вы сможете скачать hex, с файлы для прошивки Atmega8515.

Программу писал в MPLab X 5.35 и компилятор MPlab XC8 версии 2.10, как установить её на Linux смотрите здесь:

Скачать MPLAB X v5.35 + MPLAB XC8 можно здесь:
“https://web.archive.org/web/20200724202813/https://www.microchip.com/development-tools/pic-and-dspic-downloads-archive”

“rutube.ru/video/eb28c94503b777a0a6ffc61dc9a5b3ed/”

1. Учимся мигать светодиодом:

Схема подключения светодиода (мне попалась квадратная 8515, которая изображена слева):

Код на Си – мигать светодиодом будем на ножке RC3 (PORTC=0x08 или PORTC=00001000) :

#include <xc.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define F_CPU 1000000UL // 1 MHz clock speed
 
int main(void)
{
PORTC=0xFF;
DDRC=0xFF; 
 
while (1)
      {
      PORTC=0x08;
      //delay_ms(1000);
      _delay_ms(1000);
      PORTC=0x00;
      _delay_ms(1000);
      }
}

Скачать hex и Cи файлы для мигания светодиодом на Atmega8535:
– скачать в zip архиве
– скачать в tar.gz архиве

Фьюзы стандартные – по умолчанию (в PonyProg2000 будут такие же):

Программатор использовал самодельный AVRasp – “gameforstreet.ru/usb-programmator-na-atmega88/”

Но можно прошить и более легким – Программатор 5 проводков (“микроник.рус/4731/”) и программа PonyProg2000 (там есть Atmega8515. Скачать PonyProg можно с моего сайта – здесь. Скачать более новую PonyProg 2.08c можно здесь – “микроник.рус/6276/” – с моего сайта.

2. Добавляем кнопку к Atmega 8515

Добавлял кнопки на основе своей записи – “микроник.рус/6390/”

Код на СИ получился следующий:

#include <xc.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define F_CPU 1000000UL // 1 MHz clock speed
 
int main(void)
{
PORTC=0xFF;
DDRC=0xFF; 

DDRA = 0b0000110;  // Конфигурируем вывод порта PA1 - как вход
PORTA |= ( 1 << 1 ); // Подключаем к PA1 подтягивающий резистор на плюс питания
PORTA |= ( 1 << 2 ); // Подключаем к PA2 подтягивающий резистор на плюс питания
char in = 1;  // Объявляем переменную in и записываем в неё число 1
char ip = 0; // Объявляем переменную in и записываем в неё число 0 - будет показывать какая кнопка включена
 
while (1)
      {
      //PORTC=0x08;
      //delay_ms(1000);
      _delay_ms(1000);
      //PORTC=0x00;
      _delay_ms(1000);
      
      if (!(PINA & (1<<PINA1)) && in == 1 )    /* если PA1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINA & (1 << PINA1) && in == 0)    /* если PA1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}
      
      if (ip == 1)
{
PORTC = 0b0000010;    // 3. Включаем светодиод на ножке PC1
}
      
      }
}

То есть кнопка находится на PA1 – если подать питание в 5В, то светодиоды будут гореть на всех выходах PortC, но если на вход PA1 подать минус, то гореть будет только выход PC1 (PORTC = 0b0000010;).

3. Давайте сделаем переменное мигание 6 ножек.

Вот код на Си:

      PORTC = 0b0000001; 
      _delay_ms(100);
      PORTC = 0b0000010; 
      _delay_ms(100);
      PORTC = 0b0000100; 
      _delay_ms(100);
      PORTC = 0b0001000; 
      _delay_ms(100);
      PORTC = 0b0010000; 
      _delay_ms(100);
      PORTC = 0b0100000; 
      _delay_ms(100);

То есть будем зажигать ножки PC0, затем небольшая задержка и следующую ножку PC1 и т.д. до PC5 – это будут наши будущие цифры на кубике.

Также не забудем следить нажата ли кнопка с помощью следующего кода на Си:

 if (!(PINA & (1<<PINA1)) && in == 1 )    /* если PB1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINA & (1 << PINA1) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}
      
      if (ip == 1)
{
_delay_ms(7000);
ip = 0;
}

Здесь если нажата кнопка, то ставим задержку – я поставил 7 сек, но можно больше, чтобы увидеть какая цифра выпала и соответственно скидываем параметр ip в значение 0.

Теперь осталось объединить два вышеуказанных кода и получим кубик – то есть после каждой смены числа – будем проверять нажата ли кнопка – если нажата, то производим задержку в 7 секунд, чтобы увидеть цифру! Можно сделать ещё одну кнопку…

Вот полный код кубика на Atmega8515 на языке Си, который на данный момент у нас получился:



#include <xc.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define F_CPU 1000000UL // 1 MHz clock speed
 
int main(void)
{
PORTC=0xFF;
DDRC=0xFF; 

DDRA = 0b0000110;  // Конфигурируем вывод порта PA1 - как вход
PORTA |= ( 1 << 1 ); // Подключаем к PA1 подтягивающий резистор на плюс питания
PORTA |= ( 1 << 2 ); // Подключаем к PA2 подтягивающий резистор на плюс питания
char in = 1;  // Объявляем переменную in и записываем в неё число 1
char ip = 0; // Объявляем переменную in и записываем в неё число 0 - будет показывать какая кнопка включена
 
while (1)
      {
      PORTC = 0b0000001; 
      _delay_ms(100);
      
            if (!(PINA & (1<<PINA1)) && in == 1 )    /* если PB1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINA & (1 << PINA1) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}
      
      if (ip == 1)
{
_delay_ms(7000);
ip = 0;
}
      
      PORTC = 0b0000010; 
      _delay_ms(100);
      
        if (!(PINA & (1<<PINA1)) && in == 1 )    /* если PB1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINA & (1 << PINA1) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}
      
      if (ip == 1)
{
_delay_ms(7000);
ip = 0;
}
      
      
      PORTC = 0b0000100; 
      _delay_ms(100);
      
        if (!(PINA & (1<<PINA1)) && in == 1 )    /* если PB1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINA & (1 << PINA1) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}
      
      if (ip == 1)
{
_delay_ms(7000);
ip = 0;
}
      
      PORTC = 0b0001000; 
      _delay_ms(100);
      
        if (!(PINA & (1<<PINA1)) && in == 1 )    /* если PB1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINA & (1 << PINA1) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}
      
      if (ip == 1)
{
_delay_ms(7000);
ip = 0;
}
      
      PORTC = 0b0010000; 
      _delay_ms(100);
      
      
        if (!(PINA & (1<<PINA1)) && in == 1 )    /* если PB1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINA & (1 << PINA1) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}
      
      if (ip == 1)
{
_delay_ms(7000);
ip = 0;
}
      
      PORTC = 0b0100000; 
      _delay_ms(100);
      
  if (!(PINA & (1<<PINA1)) && in == 1 )    /* если PB1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINA & (1 << PINA1) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}
      
      if (ip == 1)
{
_delay_ms(7000);
ip = 0;
}
      
      
      }
}

Скачать hex файл и файл с можно ниже:
– скачать в tar.gz архиве
– скачать в zip архиве

В итоге у Вас должно получиться следующее:

“rutube.ru/video/47609322a60c2e620c5c974ec09ea484/”

4.

5. Выводим несколько цифр на семисегментном индикаторе.

Воспользуемся ШИМ – то есть будем мигать несколькими цифрами по переменно, но так как частота мигания будет высокой, то глаза не будут видеть мигания.

Для этого воспользуемся моей записью “микроник.рус/5154/”

Добавить комментарий