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

Azerhud

Members
  • Постов

    20
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные Azerhud

  1. Ничего секретного. Перед выходом на пенсию начал изучать AVR. А самый лучший способ это начать изучать на конкретном примере. Благодаря Вам понял как простым способом выдёргивать импульс из определенного количества. Теперь ломаю голову как их суммировать. Судя по литературе мне нужно копать в сторону таймеров и прерывания. Но мне проще изучать по рабочему коду. То есть смотреть как это сделано и как работает а потом собрать свой вариант. Надеюсь и впредь на Вашу помощь. )))

  2. 5 часов назад, dosikus сказал:

    Очевидно же - инкрементировать  указатель на буфер в каждой итерации, контролируя выходы за предел .

     При достижении необходимой длины посылки - проверять на содержимое.

    Как вариант маркер конца передачи.

    Одно но , на авр это пошло и уныло ...

    Спасибо за помощь. Пойду читать про строки, разбираться что такое статический буфер, и учить сначала работать с интерфейсом.

  3. 1 час назад, ruhi сказал:

    вы читаете и сохраняете один символ здесь, а вам надо дождаться и сохранить 6-символов что бы так сравнить строки:

    if (strncmp (str1, str2,6)==0)

    а глядя сюда:

    char str2[6] = "ABC";

    и это не будет работать, потому что здесь заданы только 3-символа или 4-ре элемента массива с чем будут сравниваться остальные непонятно!

    Вот и не могу понять как правильно сделать что б мне прочитать и сравнить то что пришло с образцом :(

  4. Здравствуйте уважаемые. Помогите пожалуйста. Необходимо считать символы из регистра SPDR передаваемые с одного МК в другой через интерфейс SPI и сравнить с имевшейся строкой на соответствие.  Делаю так,

     ISR(SPI_STC_vect)
       {  
          
           char str1[6]; 
          *str1 = SPDR; 
           char str2[6] = "ABC"; //Образец строки для сравнения
      
        if (strncmp (str1, str2,6)==0) //Если strncmp выдаст ноль
          { 
    	PORTC=0xFF; // то включаем светодиоды
          }
    	 else
    	{
    	   PORTC=0x00; //иначе светодиоды  выключены
             }
         
         return;
       }

    но не получается.

  5. Проверьте, всё ли так как надо.

    :) Спасибо большое. Если честно, это почти то к чему я стремлюсь. Но проблема в том что я сам хочу дойти до этого.

    1. Научится отображать динамическую индикацию...

    2, Научиться как выводить значения из клавиатуры формате 1, 11, 111, 1111

    3, Заставить из введенного значения отнимать 0,5, 1 или 2 по внешнему прерыванию

    и тд и тп. А у Вас уже готовый код. ...

    Но всё равно большое спасибо за пример.

  6. Код счётчика на семисегментном индикаторе от 0000 до 9999. В переменную volatile unsigned int test =0; можно задать любое начальное значение отсчёта. test+=1; прямой отсчёт. test-=1; обратный. Если смогу найти сайт где я этот код взял обязательно выложу ссылку. Может кому пригодится...

    //#define F_CPU 7372800UL // Частота кварца
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <string.h>
    volatile unsigned int test =0;
    ISR(INT0_vect) // Обработчик прерывания по совпадению таймера 1
    {
    test++;
    // Увеличить выводимое число
    if(test > 9999) test = 0; // Если вышел за пределы четырех разрядов, обнулить
    TCNT1H=0x00; // Сброс регистра
    TCNT1L=0x00; // счета
    }
    void dig_out(int num); // Объявление функции вывода на индикатор
    int main(void)
    {
    // Настройка портов
    DDRB=0xFF; //Порт В сигменты индикатора
    DDRC = 0x0F; //Порт С разряды
    DDRD = 0x04; // Порт D PD2 вход
    PORTD=0x04; // // Порт D PD2 подключаем подтягивающий резистор
    //инициализация прерывания
    GICR |= 0x40;//0x40 = 0b01000000 разрешить прерывания на int0
    MCUCR |= 0x3;//0x3 = 0b00000011 прерывания по фронту int0
    sei();//разрешить все прерывания, cli()- запретить
    
    
    while(1)
    {
    dig_out(test); //Постоянно вызываем функцию вывода текущего числа
    }
    }
    void dig_out(int num) // Функция для вывода на индикатор 4-х разрядов
    {
    unsigned char i = 0; // Переменная счетчика
    unsigned char raz = 1; // Номер разряда
    unsigned char dig_num[] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02,
    0x78, 0x00, 0x10}; // Коды цифр для индикатора с общим анодом
    unsigned char dig[] = {0, 0, 0, 0}; // Массив для значения разряда
    
    if(num < 10) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    dig[1] =0;
    dig[2] =0;
    }
    
    if(num < 100) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    dig[1] =0;
    }
    
    if(num < 1000) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    }
    
    while(num > 999) // Получение количества тысяч
    {
    dig[0]++;
    num -= 1000;
    }
    
    while(num > 99) // Получение количества сотен
    {
    dig[1]++;
    num -= 100;
    }
    
    while(num > 9) // Получение числа десятков
    {
    dig[2]++;
    num -= 10;
    }
    
    dig[3] = num; // Получения количества единиц
    
    while(raz <= 0x10) // Крутимся пока не заполним все 4 разряда
    {
    PORTC = raz; // Выбираем разряд
    PORTB = dig_num[dig[i]]; // Выводим цифру
    raz = raz<<1; // Сдвигаемся на следующий разряд
    i++; // Увеличиваем индекс следующей цифры
    _delay_ms(1); // Задержка 1 мс
    }
    }
    

    PS: Нашёл http://www.avrki.ru/articles/content/led_display/index.php.. Я просто немного переделал его, что б считал импульсы.

  7. Форматирования как не было, так и нет. Для определения нажатой кнопки все также сотню раз вызывается процедура опроса. Весь "код" перемешан, нет разделения на блоки.

    Попробуйте все-таки начать с начала.......

    Большое спасибо что откликнулись. Похоже мне не стоило начинать изучение программирование микроконтроллеров. У меня такое ощущение что я учусь в первом классе и вместо арифметики пытаюсь решить задачи тригонометрия.... К примеру форматирование- что я с ним должен сделать, если программа AVR Studio 5 сама его так форматирует? А для определение нажатой кнопки использую то что вычитал и нашёл в интернете. На счёт перемешивания кода, согласен. Но почему то некоторые переменные вывожу за пределы main или while и они перестают работать.. :( Наверно не за своё дело взялся. Спасибо Всем что помогли...

  8. И снова здравствуйте. Что то больно трудно мне даётся этот Си :)

    Суть такова. Исходя из того что вычерпал из интернета изменил код. На конец более менее понял как подключить клавиатуру к моему коду, но опять грабли :(

    Проблема в том что при нажатии на кнопки у меня вводятся значения только с 0 по 9 а выше не идут. Хотя если я указываю в массиве вместо 0х07 - 0х16 то на дисплее выводится цифра 22. то есть у меня всё ещё проблема с переменными, посоветуйте пожалуйста..... :umnik2:

    //#define F_CPU 7372800UL // Частота кварца
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <string.h>
    
    // Массив значений для порта вывода
    unsigned char key_tab[4] = {0b11111110,
    				 0b11111101,
    				 0b11111011,
    				 0b11110111};
    // Функция опроса клавиатуры
    unsigned char scan_key(void)
    {
    unsigned char key_value = 0;
    unsigned char i;
    for(i = 0;i < 4;i++)
    {
    PORTD = key_tab[i]; // выводим лог. 0 в порт вывода
    _delay_us(10);
    switch (PIND & 0xF0)
    {
    case 0xE0:key_value = 1 + i * 3;
    return (key_value);
    case 0xD0:key_value = 2 + i * 3;
    return (key_value);
    case 0xB0:key_value = 3 + i * 3;
    return (key_value);
    default:
    break;
    }
    }
    return (key_value);
    }
    volatile unsigned int test =0;
    void dig_out(int num); // Объявление функции вывода на индикатор
    int main(void)
    {
    // Настройка портов
    DDRB=0xFF; //Порт В сигменты индикатора
    DDRC = 0x0F; //Порт С разряды
    // массив цифр для индикатора
    unsigned char num[10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x16, 0x08, 0x09};
    DDRD |= (1 << PD3)|(1 << PD2)|(1 << PD1)|(1 << PD0); // Порт вывода
    DDRD &= ~(1 << PD7)|(1 << PD6)|(1 << PD5)|(1 << PD4); // Порт ввода
    PORTD = 0xF0; // Устанавливаем лог. 1 в порт ввода
    _delay_ms(10);
    
    
    while(1)
    {
    if(scan_key()==1) // Выводим значение нажатой кнопки на индикатор
    test = num[1];
    if(scan_key()==2)
    test = num[2];
    if(scan_key()==3)
    test = num[3];
    if(scan_key()==4)
    test = num[4];
    if(scan_key()==5)
    test = num[5];
    if(scan_key()==6)
    test = num[6];
    if(scan_key()==7)
    test = num[7];
    if(scan_key()==8)
    test = num[8];
    if(scan_key()==9)
    test = num[9];
    if(scan_key()==11)
    test = num[0];
    
    /Здесь пробую увеличить значение с клавиатуры
    if(scan_key()>10){
    test=10+num[];}
    if(scan_key()>100){
    test=100+num[];}
    if(scan_key()>1000){
    test=1000+num[];}
    
    //****************************************************
    dig_out(test); //Постоянно вызываем функцию вывода текущего числа
    }
    }
    void dig_out(int num) // Функция для вывода на индикатор 4-х разрядов
    {
    unsigned char i = 0; // Переменная счетчика
    unsigned char raz = 1; // Номер разряда
    unsigned char dig_num[] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02,
    0x78, 0x00, 0x10}; // Коды цифр для индикатора с общим анодом
    unsigned char dig[] = {0, 0, 0, 0}; // Массив для значения разряда
    
    if(num < 10) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    dig[1] =0;
    dig[2] =0;
    }
    
    if(num < 100) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    dig[1] =0;
    }
    
    if(num < 1000) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    }
    
    while(num > 999) // Получение количества тысяч
    {
    dig[0]++;
    num -= 1000;
    }
    
    while(num > 99) // Получение количества сотен
    {
    dig[1]++;
    num -= 100;
    }
    
    while(num > 9) // Получение числа десятков
    {
    dig[2]++;
    num -= 10;
    }
    
    dig[3] = num; // Получения количества единиц
    
    while(raz <= 0x10) // Крутимся пока не заполним все 4 разряда
    {
    PORTC = raz; // Выбираем разряд
    PORTB = dig_num[dig[i]]; // Выводим цифру
    raz = raz<<1; // Сдвигаемся на следующий разряд
    i++; // Увеличиваем индекс следующей цифры
    _delay_ms(1); // Задержка 1 мс
    }
    }
    

    post-95730-0-14292300-1461932661.jpg

  9. Цель задачи такова: Собрать счётчик витков с предустановкой количества витков. Дисплей должен быть семисегментный четырёхразрядный. Клавиатура матричная 4х3. Работает таким образом. Через клавиатуру задаём количество витков, к примеру 7852. Как я понимаю, Этот параметр должен записаться в ОЗУ МК. И отобразится на индекаторе. После чего нажимаем кнопку старт и команда идёт на пуск двигателя. Через герконовый датчик (или датчик холла) Получаем импульсы. -1. То есть счёт идёт на уменьшение, после достижения 0000 идёт команда на стоп. Как я понял, вводимые с клавиатуры цифры должны занестись в некий массив с которого попадут в ОЗУ а от туда будут считаны на дисплей, вот по этому мне и нужна переменная $temp. Уже второй день копаюсь в интернете ноне могу найти примеров как в массив передать значение клавиатуры. И ещё, допустим я создал массив key[4] и как то передал в неё значения key[0]=7, key[1]=8. key[2]=5. key[3]=2 то смогу ли создать переменную temp = key. И передать её дальше в виде temp=7852?

    PS: Грубо говоря это всем известный счётчик витков на калькуляторе :)

  10. Эту статью я первым делом увидел, вот как раз его и пытаюсь в более упрощённом виде повторить....

    ЗЫ: Кстати она для LCD дисплея, а я хочу под семисегментный.....

    И он отображает только один знак, 1,2,3, А,В и тд..

  11. "...А мне нужно 22,333,5555 и тд. и тп. А так же передать эти числа в переменную $temp. например $temp=7512; Помогите пожалуйста... ..." - тут все просто - судя по вопросу - НУЖНО - в раздел работа, не нужно - УЧИСЬ ... у меня ребенок сидит и сам "си с плючами" грызет ... без "пАмАхИте" ... и это потому, что он хочет научиться ... а готовое - в разделе РАБОТА ...

    Я не прошу что то сделать вместо меня! А хочу увидеть рабочие примеры... Мой ребёнок просто с друзьями в футбол играет..

  12. Здравствуйте. В просторах интернета нашёл схемку с прошивкой для матричной клавиатуры с отображением на семисегментный индикатор. (рисунок)

    А это код к нему:

    #include <avr/io.h>
    #include <util/delay.h>
    // Массив значений для порта вывода
    unsigned char key_tab[4] = {0xFE,0xFD,0xFB,0xF7};
    
    // Функция опроса клавиатуры
    unsigned char scan_key(void)
    {
    unsigned char key_value = 0;
    unsigned char i;
    for(i = 0;i < 4;i++)
    {
    PORTB = key_tab[i]; // выводим лог. 0 в порт вывода
    _delay_us(10);
     switch (PINB & 0xF0)
     {
     case 0b11100000:key_value = 1 + i * 3; return (key_value);
     case 0b11010000:key_value = 2 + i * 3; return (key_value);
     case 0b10110000:key_value = 3 + i * 3; return (key_value);
     default:
     break;
     }
    }
    return (key_value);
    }
    
    
    
    int main(void)
    {
    // массив цифр для индикатора
    unsigned char num[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
    
    DDRB = 0x0F;
    PORTB = 0xF0; // Устанавливаем лог. 1 в порт ввода
    DDRD = 0xFF; // Выход на индикатор
    PORTD = 0x00;
    
    _delay_ms(10);
    
    while(1)
    {
    if(scan_key()==1) // Выводим значение нажатой кнопки на индикатор
    PORTD = num[1];
    if(scan_key()==2)
    PORTD = num[2];
    if(scan_key()==3)
    PORTD = num[3];
    if(scan_key()==4)
    PORTD = num[4];
    if(scan_key()==5)
    PORTD = num[5];
    if(scan_key()==6)
    PORTD = num[6];
    if(scan_key()==7)
    PORTD = num[7];
    if(scan_key()==8)
    PORTD = num[8];
    if(scan_key()==9)
    PORTD = num[9];
    if(scan_key()==11)
    PORTD = num[0];
    }
    }
    

    Так вот, перерыл весь интернет но никак не могу найти такой код, что б можно было выводить на семисегментный четырёх разрядный индикатор. То есть в данном случаи код выводит только 1,2,3 и тд. А мне нужно 22,333,5555 и тд. и тп. А так же передать эти числа в переменную $temp. например $temp=7512; Помогите пожалуйста...

    post-95730-0-33084200-1460196778_thumb.png

  13. C портами вроде немного разобрался. Нашёл в интернете код для семисегментного индикатора который просто считал. Немного изменил и получился счётчик. Добавил светодиод и теперь при достижении 0000 срабатывает светодиод. Но! есть переменная

    volatile unsigned int test = 111; // Переменная для вывода на индикатор
    

    которая задаёт начальное значения с которого начинается отчёт. Так вот, нашёл много исходных кодов опроса матричной клавиатуры, но никак не пойму как её прикрутить к коду счётчика. Как я понимаю если я набираю 99 или 123, то эти значении должны вписаться в какую то переменную откуда будут переданы в test? Что то типа test=(значения введённые с клавиатуры). Подскажите пожалуйста в какую сторону копать??

    //#define F_CPU 7372800UL // Частота кварца
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    volatile unsigned int test = 111; // Переменная для вывода на индикатор
    ISR(INT0_vect) // Обработчик прерывания по совпадению таймера 1
    {
    test--;
    // Увеличить выводимое число
    if(test > 9999) test = 0; // Если вышел за пределы четырех разрядов, обнулить
    TCNT1H=0x00; // Сброс регистра
    TCNT1L=0x00; // счета
    }
    void dig_out(int num); // Объявление функции вывода на индикатор
    int main(void)
    {
    DDRB=0x01;
    PORTB=0x01;
    DDRA=0xFF;
    DDRC = 0x0F; // Настройка портов
    //PORTA = 0x00;
    DDRD = 0x00; // для работы с индикатором Порт С для разрядов, Порт D для цифр
    PORTD=0x04;
    //TCCR1A=0x00; // Настройка таймера
    //TCCR1B=0x04;
    //инициализация прерывания
    GICR |= 0x40;//0x40 = 0b01000000 разрешить прерывания на int0
    MCUCR |= 0x3;//0x3 = 0b00000011 прерывания по фронту int0
    sei();//разрешить все прерывания, cli()- запретить
    
    //TCNT1H=0x00;
    //TCNT1L=0x00;
    //OCR1AH=0x70;
    //OCR1AL=0x80;
    //TIMSK=0x10;
    
    sei(); // Разрешение прерываний
    
    while(1)
    {
    dig_out(test); //Постоянно вызываем функцию вывода текущего числа
    }
    }
    void dig_out(int num) // Функция для вывода на индикатор 4-х разрядов
    {
    unsigned char i = 0; // Переменная счетчика
    unsigned char raz = 1; // Номер разряда
    unsigned char dig_num[] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; // Коды цифр для индикатора с общим анодом
    unsigned char dig[] = {0, 0, 0, 0}; // Массив для значения разряда
    
    if(num < 10) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    dig[1] =0;
    dig[2] =0;
    }
    
    if(num < 100) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    dig[1] =0;
    }
    
    if(num < 1000) // Для заполнения нулями левых разрядов
    {
    dig[0] =0;
    }
    
    while(num > 999) // Получение количества тысяч
    {
    dig[0]++;
    num -= 1000;
    }
    
    while(num > 99) // Получение количества сотен
    {
    dig[1]++;
    num -= 100;
    }
    
    while(num > 9) // Получение числа десятков
    {
    dig[2]++;
    num -= 10;
    }
    
    dig[3] = num; // Получения количества единиц
    
    while(raz <= 0x10) // Крутимся пока не заполним все 4 разряда
    {
    PORTC = raz; // Выбираем разряд
    PORTA = dig_num[dig[i]]; // Выводим цифру
    raz = raz<<1; // Сдвигаемся на следующий разряд
    i++; // Увеличиваем индекс следующей цифры
    if(dig[0]==0&&dig[1]==0&&dig[2]==0&&dig[3]==0){PORTB=0x00;}
    _delay_ms(1); // Задержка 1 мс
    }
    }
    

    post-95730-0-08476300-1459095747_thumb.jpg

  14. Xt

    if(PINB1==0 ){
    if(1 == 0){
    Чего вы хотели этим добиться?

    Ну и схему бы поглядеть.

    Схему прикрепил, но что то её не видно А хотел я через PIN считать состояние порта PB1 и в зависимости от этого включать или выключать светодиода..

    post-95730-0-17747800-1458822264.jpg

  15. Здравствуйте. столкнулся с такой проблемой. На вид всё очень просто, но не работает. Хочу просто включить светодиод с помощью кнопки. пишу код:

    #include <avr/io.h>
    #include <util/delay.h>
    int main()
    {
    DDRB = 0b00000001;
    
    while(1)
    {
    if(PINB1==0 ){
    PORTB= 0b00000011;
    } else
    {
    PORTB= 0b00000010;
    }
    }
    }
    

    Но почему то он не работает, помогите пожалуйста новичку.

×
×
  • Создать...