Архив рубрики: Электрические схемы

[sape]

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 проводков!

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/”

Логический элемент НЕ-И и НЕ-ИЛИ на pnp и npn транзисторах

Давайте рассмотрим логические элементы НЕ-И и НЕ-ИЛИ на pnp и npn транзисторах – данные элементы достаточно часто применяются мною для создания различных устройств. Читать далее

Заменяем микросхемы HEF4067B (CD74HC4067, 74HC154D) логикой на транзисторах

Недостаточно входных или выходных контактов на нашем микроконтроллере? Вы можете использовать HEF4067B. Он оснащен четырьмя цифровыми входами выбора (A0, A1, A2 и A3), шестнадцать независимых входов/выходов (Yn).
На транзисторной логике можно уменьшить или увеличить количество входов, чтобы получить больше или меньше выходов. Читать далее

Последовательная передача по UART с pic16f877a на C

В данной статье мы рассмотрим организацию последовательной связи (UART) между микроконтроллером PIC и персональным компьютером. Код будем писать на языке С в программе MPLAB X IDE 5.35 на российской бесплатной ОС Linux Rosa Fresh R13 Plasma – как всё быстро и бесплатно установить читайте здесь: “микроник.рус/7259/”. Читать далее

Светим и мигаем светодиодами на pic16f877a на С

Писать код буду на языке С в программе MPLAB X IDE 5.35 на российской бесплатной ОС Linux Rosa Fresh R13 Plasma – как всё быстро и бесплатно установить читайте здесь: “микроник.рус/7259/”.
Читать далее

Python tkinter: Создаём окно с кнопками

Создадим в Linux Rosa Fresh R13 (R12) окно с кнопками на Python, добавим кнопки, картинки, кнопку сброса (reset) и сдвинем окно приложения от центра и запустим одновременно редактор кода, окно приложения и другое. Читать далее

Управляем светодиодной матрицей с ПК

Будем использовать следующую цепочку: ПК, на котором напишем программу на Python – UART – Микроконтроллер Atmega (PIC или любой другой) – Самодельная светодиодная матрица. Читать далее