Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATmega16 + PT2322 + PT2323
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Страницы: 1, 2
Дмитрий(846)
Здравствуйте я ученик, и ничего не понимаю в написание программы для ATmega16. Надеюсь здесь я найду людей которые мне смогут помочь.
Суть такова у меня есть печатка приложил ниже. (уже сделана, распаяна)

Помогите начать с нуля, написать прошивку.

Сперва надо сказать то, что будет делать программа и собственно ATmega:
-Управлять аудио процессорами по интерфейсу I2C. (Аудио процессоры PT-2322 + PT2323)
-Выводить состояние параметров и управления на LCD Winstar 16x2.
-Сигнализировать свечением диодов о выбранных параметрах.
-Управляться пультом по протоколу RC-5
-Управляться 5 кнопками (Sesect, 2.1, 5.1, AC-3, StandBy).

C чего начать я даже и не знаю.

Ниже приложил материалы которые у меня есть.(включая исходник готовой прошивки но с пультом в котором работают только три кнопки, нет регулировки тембром, и физических кнопок.
kovigor
Цитата(Дмитрий(846) @ Mar 5 2013, 01:59) *
C чего начать я даже и не знаю.

Это учебная задача ? Тогда начните с того, что в CodeVision есть готовая библиотека для работы с I2C - устройствами (ваш МК - мастер шины). Есть также готовая библиотека для работы с LCD. затем начните с малого - напишите простую программку, которая выводит на LCD "Hello, world !". Будут вопросы - пишите. Разбираться в чижих исходниках, часто весьма неудачных - нет, увольте ...
P.S. Бегло просмотрел исходник. Нет, разбираться в нем я не вижу смысла - слишком все сложно и объемно. Проще написать прошивку самому ...
Дмитрий(846)
Спасибо что отозвался помочь!!!
Это не учебная задача, а проявление интереса и к тому же у меня акустика 5.1, это для нее!
С выводом, текста и подключением библиотек понял, подключу и отпишусь.
kovigor
Цитата(Дмитрий(846) @ Mar 5 2013, 10:42) *
С выводом, текста и подключением библиотек понял, подключу и отпишусь.

ОК, ждем-с sm.gif. См. мануал на CodeVision, там все достаточно подробно расписано ...
Дмитрий(846)
Цитата(kovigor @ Mar 5 2013, 11:23) *
ОК, ждем-с sm.gif. См. мануал на CodeVision, там все достаточно подробно расписано ...


Все получилось вот исходник, что дальше? опишем контакты на атмега?? как?
Код
/********************************************************************************
***************
Project : System Sound
Version : 0.1beta
Start Date    : 5.03.2013
Complite Date : 5.03.2013
Author  : Oberemok D.M. and kovigor
Company : Home
Comments: Пpoeкт шecтикaнaльнoгo peгyлятopa гpoмкocти и ceлeктopa вxoдoв нa      
          микpocxeмax PT2322 и PT2323
            
Chip type               : ATmega16
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
********************************************************************************
*****************/
#include <mega16.h> //библиотека для работы с ATmega16

#asm
   .equ __i2c_port=0x15;PORTC //указываем порт i2c
   .equ __sda_bit=1            //ножка SDA на 23 PIN PDIP
   .equ __scl_bit=0            //ножка SCL на 23 PIN PDIP
   .equ __lcd_port=0x1B;PORTA     // Указываем расположение LCD  
  
#endasm

#include <i2c.h>               //Подключение библиотеки i2c
#include <lcd.h>               //Подключение библиотеки LCD
#include <stdio.h>
#include <delay.h>             //Подключение библиотеки задержки

void main(void)
{
    lcd_init(16);                 //Обнаружение LCD
    lcd_clear();                  //Очистить LCD
    lcd_gotoxy(1,2);              //указываю место последующего вывода текста
    lcd_putsf("Syetem Sound");    //выводим
    lcd_gotoxy(2,2);              //указываю место последующего вывода текста
    lcd_putsf("Ver: 0.1Beta");    //выводим
    delay_ms(3000);               //задержка 3сек
}

Кстати прикрепил датащиты процессоров
kovigor
Цитата(Дмитрий(846) @ Mar 5 2013, 20:19) *
Все получилось вот исходник, что дальше? опишем контакты на атмега?? как?

Молодец, поздравляю !
Вы сгенерили проект, CV сгенерил вам шаблон Си - кода, из которого вы выкинули почти все и остаток привели здесь. Естественно, в том, что вы выкинули, эти самые контакты и описаны. Описания корректируются вами же, когда вы инструктируете CV, рассказывая ему, как генерить .c - шаблон. Я уже сегодня давал ссылку:
http://atmel.moy.su/publ/1-1-0-3
Разберитесь и действуйте.

В аудиопроцессоры я вникать не буду. План работы примерно такой. Берете самую простую функцию оного аудиопроцессора, которую вам нужно реализовать у себя в системе, и реализуете. Например, попробуйте посредством программирования/настройки (или как там это называется) аудиопроцессора сгенерить на его выходе простую синусоиду ...
P.S. попытайтесь разбить вашу задачу на маленькие кусочки, и реализуйте их, от самых простых к более сложным.

Статья про RC5 вот (а вообще, их довольно много):
http://www.platan.ru/shem/pdf/prim.pdf

Можете пойти другим путем - для начала сделайте декодер RC5, а декодированные значения отображайте на индикаторе. Например, нажали "пятерку" на пульте, приняли ее в МК, декодировали и написали на индикаторе: "RC5 code received: '5' !". А потом займетесь аудиопроцессорами ...
Дмитрий(846)
Ну а как реализовать пять кнопок??? на ноге 37??
кнопки последовательно соединены резисторами 4.7К Ом
kovigor
Цитата(Дмитрий(846) @ Mar 5 2013, 23:55) *
Ну а как реализовать пять кнопок??? на ноге 37??
кнопки последовательно соединены резисторами 4.7К Ом

Да кто ж его знает ? Вы бы хоть схемку от руки набросали, а то вообще непонятно, как подключены кнопки ...
Дмитрий(846)
Вот, а вообще я ж печатку выложил
kovigor
Цитата(Дмитрий(846) @ Mar 6 2013, 01:27) *
Вот, а вообще я ж печатку выложил

На схеме ошибка - не Ом, а КОм. а так все просто. Это делитель напряжения. Верхнее плечо - горизонтально расположенный резистор (подключите его правую ножку к источнику питания), а нижнее образовано оставшимися сопротивлениями и может меняться в зависимости от того, какие кнопки нажаты. Вам нужно подать сигнал с делителя на вход любого из имеющихся в МК АЦП (например, на PA3 (конечно, можно подать на любой из входов PA0 ... PA7)) ...
Дмитрий(846)
да это понятно, да там 4.7 кОм как в моем коде это отобразить
kovigor
Цитата(Дмитрий(846) @ Mar 6 2013, 17:20) *
да это понятно, да там 4.7 кОм как в моем коде это отобразить

Я же говорю, оцифровывайте сигнал с делителя посредством АЦП. Как задействовать АЦП ? Читайте даташит, там нет ничего сложного ...
Дмитрий(846)
Вообще ничего не понял.
kovigor
Цитата(Дмитрий(846) @ Mar 6 2013, 18:46) *
Вообще ничего не понял.

Я говорю, внутри МК есть такой узел, как АЦП. Вот на его вход (pin 37) вам и нужно подать сигнал с делителя, образованного резисторами и кнопками, с целью измерения напряжения, приходящего от делителя. Понятно ?

Вот книжки на русском:
http://lord-n.narod.ru/download/books/wall.../atmelbook.djvu
Дальше вот сюда зайдите:
http://lord-n.narod.ru/walla.html
Евстифеев "Микроконтроллеры AVR семейств Tiny и Mega фирмы Atmel"
Трамперт "Измерение, управление и регулирование с помощью AVR микроконтроллеров"

Думаю, пока хватит ...
artkam
Вот здесь про обработку нажатия клавиш при помощи АЦП очень подробно расписано, даже приведены примеры кода: http://chipenable.ru/index.php/programming...du-chast-1.html
Mik174
Озвученная задача - не для того, кто "я ученик, и ничего не понимаю в написание программы для ATmega16".
Вероятность что ничего не получится весьма высока.

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

В качестве совета - возьмите для начала задачу попроще и разберитесь с основами программирования МК.

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

Например:
1) Научиться вывести текст и значение переменной на ЖКИ, например, типа такого, "U=456", где 456 - не строка, а значение целочисленной переменной.
2) Научиться использовать АЦП и сделать простейший вольтметр, который может померить напряжение пальчиковой батарейки и вывести напряжение в кодах, полученных от АЦП на первой строке и пересчитанное в милливольты - во второй строке.
3) У Вас кнопки сделаны на основе резисторного делителя.
Подключите их к входу, на котором измеряли напряжение в предыдущем варианте.
Включите схему и понажимайте на кнопки - увидите, что каждой из них соответствует напряжение.
4) Сделайте программу распознавания какая кнопка нажата. Принцип простой - если напряжение меньше, чем U2, но больше чем U1, значит, нажата кнопка SB1. Для каждой из кнопок эти два напряжения будут своими.

Чтобы осмысленно понимать, что происходит при такой схеме подключения кнопок, надо разобраться что такое делитель напряжения.

А вообще, я посоветовал бы по началу не экономить на спичках и сделать обычное подключение кнопок - по одной на каждый вывод порта МК, для новичка это легче будет.

Если это проделаете, можно двигаться дальше.
Дмитрий(846)
Код
/********************************************************************************
***************
Project : System Sound
Version : 0.1beta
Start Date    : 5.03.2013
Complite Date : 8.03.2013
Author  : Oberemok D.M. and kovigor
Company : Home
Comments: Пpoeкт шecтикaнaльнoгo peгyлятopa гpoмкocти и ceлeктopa вxoдoв нa      
          микpocxeмax PT2322 и PT2323
            
Chip type               : ATmega16
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
********************************************************************************
*****************/
#include <mega16.h> //библиотека для работы с ATmega16
#include <i2c.h>               //Подключение библиотеки i2c
#include <lcd.h>               //Подключение библиотеки LCD
#include <stdio.h>
#include <delay.h>             //Подключение библиотеки задержки
//программирование микроконтроллеров AVR на Си - осваиваем АЦП
#include <ioavr.h>             //для кнопок
#include <intrinsics.h>        //для кнопок

#asm
   .equ __lcd_port=0x1B;PORTA  // Указываем расположение LCD
   .equ __i2c_port=0x15;PORTC   //указываем порт i2c
   .equ __sda_bit=1            //ножка SDA на 23 PIN PDIP
   .equ __scl_bit=0            //ножка SCL на 23 PIN PDIP    
#endasm  

//Физические кнопки
#define KEY___Standby   1
#define KEY___SELECT    2
#define KEY___2_1       3
#define KEY___5_1       4
#define KEY___AC-3      5
// Для удобства пины ввода-вывода сопоставляем с символическими именами - куда что подключено по схеме

#asm("sei")     // бесконечный цикл
//макрос для запуска преобразования
#define StartConvAdc()  ADCSRA |= (1<<ADSC)

void skane_key(void)
{
//ион - напряжение питания, выравнивание влево, нулевой канал
ADMUX = (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
//вкл. ацп, режим одиночного преобр., разрешение прерывания,частота преобр. = FCPU/128
ADCSRA = (1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);

__enable_interrupt();
StartConvAdc();
  while(1)
  {
    //какой-нибудь код
  }
  return 0;
}


//обработчик прерывания АЦП
#pragma vector=ADC_vect
__interrupt void adc_my(void)
{
   unsigned char AdcBuf = ADCH;

  //какой-нибудь код
  StartConvAdc();
}  

void main(void)
{
lcd_init(16);
PORTA=0x00; //Выставляем все выходы PORTA на ноль
DDRA=0x00;  //Выставляем все выходы PORTA как входы
{
    lcd_init(16);                 //Обнаружение LCD
    lcd_clear();                  //Очистить LCD
    lcd_gotoxy(0,0);              //указываю место последующего вывода текста
    lcd_putsf("System Sound");    //выводим
    lcd_gotoxy(0,1);              //указываю место последующего вывода текста
    lcd_putsf("Downloaded");       //выводим
    delay_ms(1500);                //задержка
    lcd_clear();                   //Очистить LCD

for (;;)
{
if(!PINA.3 > 0)  //если кнопка нажата
    {              
    lcd_clear();                  //Очистить LCD
    lcd_gotoxy(0,0);              //указываю место последующего вывода текста
    lcd_putsf("On");    //выводим
    }
else
    {
    lcd_clear();                  //Очистить LCD
    lcd_gotoxy(0,0);              //указываю место последующего вывода текста
    lcd_putsf("Off");    //выводим    
    }  
}
}
}//Main


в чем проблема не компилирует
ошибка
Error: System Sound.c(103): no matching #endif
_Артём_
Этот код вызывает сомнения, так как не находится внутри какой-либо функции(особенно #asm("sei")):
Код
/********************************************************************************

#include <mega16.h> //библиотека для работы с ATmega16
#include <i2c.h>               //Подключение библиотеки i2c
#include <lcd.h>               //Подключение библиотеки LCD
#include <stdio.h>
#include <delay.h>             //Подключение библиотеки задержки
//программирование микроконтроллеров AVR на Си - осваиваем АЦП
#include <ioavr.h>             //для кнопок
#include <intrinsics.h>        //для кнопок

#asm
   .equ __lcd_port=0x1B;PORTA  // Указываем расположение LCD
   .equ __i2c_port=0x15;PORTC   //указываем порт i2c
   .equ __sda_bit=1            //ножка SDA на 23 PIN PDIP
   .equ __scl_bit=0            //ножка SCL на 23 PIN PDIP    
#endasm  

//Физические кнопки
#define KEY___Standby   1
#define KEY___SELECT    2
#define KEY___2_1       3
#define KEY___5_1       4
#define KEY___AC-3      5
// Для удобства пины ввода-вывода сопоставляем с символическими именами - куда что подключено по схеме

#asm("sei")     // бесконечный цикл


А этот обработчик не похож на Codevision-ский:

Код
#pragma vector=ADC_vect
__interrupt void adc_my(void)

Так в ИАР АВР пишут, но может что поменялось в CV?
Дмитрий(846)
Код
/********************************************************************************
***************
Project : System Sound
Version : 0.1beta
Start Date    : 5.03.2013
Complite Date : 8.03.2013
Author  : Oberemok D.M. and kovigor
Company : Home
Comments: Пpoeкт шecтикaнaльнoгo peгyлятopa гpoмкocти и ceлeктopa вxoдoв нa      
          микpocxeмax PT2322 и PT2323
            
Chip type               : ATmega16
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
********************************************************************************
*****************/
#include <mega16.h> //библиотека для работы с ATmega16
#include <i2c.h>               //Подключение библиотеки i2c
#include <lcd.h>               //Подключение библиотеки LCD
#include <stdio.h>
#include <delay.h>             //Подключение библиотеки задержки
//программирование микроконтроллеров AVR на Си - осваиваем АЦП
#include <ioavr.h>             //для кнопок
#include <intrinsics.h>        //для кнопок

#asm
   .equ __lcd_port=0x1B;PORTA  // Указываем расположение LCD
   .equ __i2c_port=0x15;PORTC   //указываем порт i2c
   .equ __sda_bit=1            //ножка SDA на 23 PIN PDIP
   .equ __scl_bit=0            //ножка SCL на 23 PIN PDIP    
#endasm  
// Для удобства пины ввода-вывода сопоставляем с символическими именами - куда что подключено по схеме
//макрос для запуска преобразования
#define StartConvAdc() ADCSRA |= (1<<ADSC)
//Физические кнопки
#define KEY___Standby   0
#define KEY___SELECT    1
#define KEY___2_1       2
#define KEY___5_1       3
#define KEY___AC_3      4

//кнопочный буфер
volatile unsigned char KeyBuf = 0;

void skane_key(void)
{
  unsigned char tmp;
  
  //настраиваем порты
  DDRC = 0xff;
  PORTC = 0xff;

  //инициализируем АЦП
  //ион - напряжение питания, выравнивание влево, нулевой канал
  ADMUX = (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
  //вкл. ацп, режим одиночного преобразования, разрешение прерывания, частота преобр. = FCPU/128
  ADCSRA = (1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);

  //разрешаем прерывания и запускаем преобразование
  __enable_interrupt();
    StartConvAdc();

  //основной цикл программы - опрос кнопочного буфера
  while(1)
  {
    tmp = KeyBuf;
    if (tmp)
    {
      tmp--;
      PORTC = ~(1<<tmp);
    }
    else
      PORTC = 0xff;
  }
  return 0;
}


#pragma vector=ADC_vect
__interrupt void adc_my(void)
{
  //считываем старший регистр АЦП
  unsigned char AdcBuf = ADCH;
  
  //опеределяем в какой диапазон он попал
  if (AdcBuf > 240)
    KeyBuf = KEY___AC_3;
  else if (AdcBuf > 180)
    KeyBuf = KEY___SELECT;
  else if (AdcBuf > 120)
    KeyBuf = KEY___2_1;
  else if (AdcBuf > 50)
    KeyBuf = KEY___5_1;
  else
    KeyBuf = KEY___Standby;  
    
  //защита от дребезга и не только. если нажата какая-нибудь кнопка
  //сравниваем совпадают ли текущее состояние и предыдущее
  //если совпадают - проверяем счетчик comp, если нет обнуляем его
  //кнопка считается нажатой если она удерживается в течении 100
  //преобразований АЦП
  if (Key)
  {
    if (Key == LastState)
    {
      if (comp > 100)
        KeyBuf = Key;      
      else
        comp++;
    }
    else
    {
      LastState = Key;
      comp = 0;
    }
  }
  else
  {
    comp = 0;
    KeyBuf = KEY___Standby;
    LastState = KEY___Standby;
  }  
  //запускаем преобразование и выходим
  StartConvAdc();
}





























  

void main(void)
{
lcd_init(16);
PORTA=0x00; //Выставляем все выходы PORTA на ноль
DDRA=0x00;  //Выставляем все выходы PORTA как входы
{
    lcd_init(16);                 //Обнаружение LCD
    lcd_clear();                  //Очистить LCD
    lcd_gotoxy(0,0);              //указываю место последующего вывода текста
    lcd_putsf("System Sound");    //выводим
    lcd_gotoxy(0,1);              //указываю место последующего вывода текста
    lcd_putsf("Downloaded");       //выводим
    delay_ms(1500);                //задержка
    lcd_clear();                   //Очистить LCD

for (;;)
{
if(!PINA.3 > 0)  //если кнопка нажата
    {              
    lcd_clear();                  //Очистить LCD
    lcd_gotoxy(0,0);              //указываю место последующего вывода текста
    lcd_putsf("On");    //выводим
    }
else
    {
    lcd_clear();                  //Очистить LCD
    lcd_gotoxy(0,0);              //указываю место последующего вывода текста
    lcd_putsf("Off");    //выводим    
    }  
}
}
}//Main

тоже самое
_Артём_
Цитата(Дмитрий(846) @ Mar 8 2013, 18:24) *
тоже самое


Возможно.
Наверное потому, что всё это:

Код
#include <intrinsics.h>        //для кнопок


Код
  __enable_interrupt();


Код
#pragma vector=ADC_vect
__interrupt void adc_my(void)

CodeVision-у не известно. Выкиньте эти строки из программы и тогда компилируйте.

P.S.
Посмотрел приложенный архив (файл intrinsics.h):
Код

  This file declares the ARM intrinsic inline functions.

  Copyright 1999-2006 IAR Systems. All rights reserved.

  $Revision 34635 $



#ifndef __INTRINSICS_INCLUDED
#define __INTRINSICS_INCLUDED

#include ycheck.h

#ifndef _SYSTEM_BUILD
  #pragma system_include
#endif


  Check that the correct C compiler is used.


#if ((__TID__  8) & 0x007F) != 79
#error File intrinsics.h can only be used together with iccarm.
#endif

#ifdef __cplusplus
extern C {
#endif

#pragma language=save
#pragma language=extended

__intrinsic void    __no_operation(void);

Он у вас не только не той системы, но ещё и из другой оперы. И почему-то комментарии раскомментированы...
Дмитрий(846)
Помогите поправить синтаксис.
При выводе Volume на Максимум и Минимум, устройство ребутиться !
kovigor
Цитата(Дмитрий(846) @ Mar 12 2013, 20:20) *
Помогите поправить синтаксис.
При выводе Volume на Максимум и Минимум, устройство ребутиться !

Мне сейчас некогда. А самому - никак ? Ребутится - значит, почти наверняка рушится стек. Или вы, например, где-то в программе создали массив на 10 элементов, а пишете в него не десять элементов, а больше, и этим разрушаете соседние переменные.
P.S. Вообще, не обижайтесь, но я вам по-дружески очень советую с первых же шагов учиться работать самостоятельно, особенно при решении элементарных вопросов ...
P.P.S. Лучшим отладчиком часто бывает обычный светодиод, ибо он позволяет довольно точно проследить ход выполнения программы ...

Дополню. Еще вариант - вы что-то напутали с типами данных (по ошибке используете знаковый тип как беззнаковый, или наоборот, или же путаете восьмиразрядные данные с 16-разрядными)
Дальше, по вашему исходнику. В блоке "switch" непременно должен быть "default", а не только "case 1,2,3 и проч.".
Дальше. У вас из обработчиков прерываний вызывается функция " Set_Key", которая вызывает задержку на 300 мС !!!!! Это абсолютно недопустимо. Обработчики прерывания должны выполняться почти мгновенно. Разбираться с результатами работы обработчиков нужно в фоновом процессе, но никак не прямо в самих обработчиках. Конечно, из этого правила бывают исключения, но они только подтверждают правило ...
Ладно, пока хватит. Устраните эти вопиющие недоработки, тогда посмотрим ...
Дмитрий(846)
За распознавание энкодера не понял зачем там default (все работает норм)


Вот смотри.

И вопросик правильно ли написал код выбора режима

Код
//Выбор режима роботы        
if(key == COMMAND_KEY_ok)
{
switch(mode)
  {
  case 1:                      // 2.1 mode
     i2c_start();
     i2c_write(ADDR_2323);
     i2c_write(ACK);
     i2c_write(0xf5);  // CE Выключен, включено Mute на канал // 0xf4 Включен
     i2c_write(0xf9);  // RL Выключен, включено Mute на канал // 0xf8 Включен
     i2c_write(0xfb);  // RR Выключен, включено Mute на канал // 0xfa Включен
     i2c_stop();                    
    break;
  case 2:                      // 3.1 mode
     i2c_start();
     i2c_write(ADDR_2323);
     i2c_write(ACK);
     i2c_write(0xf4);  // CE Включен, выключено Mute на канал // 0xf5 Выключен
     i2c_write(0xf9);  // RL Выключен, включено Mute на канал // 0xf8 Включен
     i2c_write(0xfb);  // RR Выключен, включено Mute на канал // 0xfa Включен
     i2c_stop();
    break;
  case 3:                      // 4.1 mode
     i2c_start();
     i2c_write(ADDR_2323);
     i2c_write(ACK);
     i2c_write(0xf5);  // CE Выключен, включено Mute на канал // 0xf4 Включен
     i2c_write(0xf8);  // RL Включен, выключено Mute на канал // 0xf9 Выключен
     i2c_write(0xfa);  // RR Включен, выключено Mute на канал // 0xfb Выключен
     i2c_stop();
    break;
  default:                     // 5.1 mode
     i2c_start();
     i2c_write(ADDR_2323);
     i2c_write(ACK);
     i2c_write(0xfe);          // Включить все каналы
     i2c_stop();
    break;
  }
}
kovigor
Цитата(Дмитрий(846) @ Mar 12 2013, 23:03) *
За распознавание энкодера не понял зачем там default (все работает норм)

Вот смотри.

И вопросик правильно ли написал код выбора режима


Мало ли что еще работает из того, что сделано неправильно ?

Простите, но я не привык обращаться к незнакомым людям на "ты".

Правильно ли, не знаю. Чтобы ответить, нужно вникать в код и алгоритм. А мне сейчас не до этого. Могу почти точно (99.9%) уже сейчас сказать, что у вас неправильно построен сам проект, ибо в правильно построенных проектах функции задержек на 300мС из обработчиков прерываний не вызываются, но такие задержки всегда делаются в фоновом процессе. Функции обмена по I2C также очень желательно никогда не вызывать из обработчиков прерываний, ибо продолжительность их выполнения труднопредсказуема ...
Дмитрий(846)
Цитата(kovigor @ Mar 12 2013, 21:34) *
Мало ли что еще работает из того, что сделано неправильно ?

Простите, но я не привык обращаться к незнакомым людям на "ты".

Правильно ли, не знаю. Чтобы ответить, нужно вникать в код и алгоритм. А мне сейчас не до этого. Могу почти точно (99.9%) уже сейчас сказать, что у вас неправильно построен сам проект, ибо в правильно построенных проектах функции задержек на 300мС из обработчиков прерываний не вызываются, но такие задержки всегда делаются в фоновом процессе. Функции обмена по I2C также очень желательно никогда не вызывать из обработчиков прерываний, ибо продолжительность их выполнения труднопредсказуема ...


Все понял, покажите как организовать выбор default в той части кода?
kovigor
Цитата(Дмитрий(846) @ Mar 12 2013, 22:58) *
Все понял, покажите как организовать выбор default в той части кода?

Смотря что вы хотите получить. Можно просто проигнорировать недопустимый "mode" и выйти из "switch", просто написав "break", а можно как-то обработать ошибочную ситуацию (что вы и делаете), например, выключив звук или включив лампочку - индикатор ошибки. Тут решить можете только вы, задача-то творческая ...
Дмитрий(846)
Спасибо реализовал break, а там посмотрим.
Посмотрите внимательно код, есть еще пожелания.

Подскажите расчетные данные для реализации кнопок через ацп на резитротах 4,7кОм !!!

Код
unsigned char read_key(void)
{
        unsigned char key_adc;        
        key_adc=read_adc(3);
                
          if                      (key_adc <=   3)  return KEY_STANDBY;
          if ((key_adc >= 124) && (key_adc <= 130)) return KEY_STANDBY; //KEY_VOLUME_PLUS;
          if ((key_adc >= 167) && (key_adc <= 173)) return KEY_STANDBY; //KEY_VOLUME_MINUS; //167-173 = 1630 Om
          if ((key_adc >= 188) && (key_adc <= 194)) return KEY_STANDBY; //KEY_INPUT5_1;     //167-173 = 3000 Om
          if ((key_adc >= 201) && (key_adc <= 207)) return KEY_STANDBY; //KEY_MUTE;        
}
kovigor
Цитата(Дмитрий(846) @ Mar 13 2013, 00:14) *
Спасибо реализовал break, а там посмотрим.
Посмотрите внимательно код, есть еще пожелания.

Подскажите расчетные данные для реализации кнопок через ацп на резитротах 4,7кОм !!!

Код гляну завтра, сегодня уже поздно. А значения вы и сами легко вычислите, исходя из того, что это простейший делитель напряжения, а также из закона Ома и того факта, что сопротивления резисторов задаются с допуском, например, в 10%. Да, если вы используете 8-разрядный АЦП, то макс. значение на его выходе будет равно 255, имейте это в виду. Задача, действительно, простейшая. Нарисуйте на листике делитель и сразу все поймете ...
Дмитрий(846)
Цитата(kovigor @ Mar 12 2013, 22:27) *
Код гляну завтра, сегодня уже поздно. А значения вы и сами легко вычислите, исходя из того, что это простейший делитель напряжения, а также из закона Ома и того факта, что сопротивления резисторов задаются с допуском, например, в 10%. Да, если вы используете 8-разрядный АЦП, то макс. значение на его выходе будет равно 255, имейте это в виду. Задача, действительно, простейшая. Нарисуйте на листике делитель и сразу все поймете ...


Огромное спасибо, за помощь.
kovigor
Цитата(Дмитрий(846) @ Mar 13 2013, 00:31) *
Огромное спасибо, за помощь.

Не за что ...

Смотрю, но он не компилируется:
if(enc >= TACT && standby_1 == 1)
Здесь после функции идет какой-то неприкаянный обрывок кода. Разбирайтесь ...

Еще раз: Старайтесь не вызывать из обработчиков прерываний функции обмена по I2C.
Проект, похоже, сделан неправильно. Советую переделать его как можно скорее, реализовав его в виде машины состояний ("state machine") - одной или нескольких:

http://www.chipenable.ru/index.php/program...te-machine.html
http://nongreedy.ru/embedded/2012/10/09/fi...-state-machine/
Вот еще, может, вам понравится:
http://easyelectronics.ru/avr-uchebnyj-kur...yj-avtomat.html
Дмитрий(846)
("state machine") - вообще не понимаю!

Поправил, все компилируется.
kovigor
Цитата(Дмитрий(846) @ Mar 13 2013, 20:10) *
("state machine") - вообще не понимаю!

Так я же вам ссылки дал. Синонимы - "машина состояний", иногда говорят "цифровой автомат". ("state machine") - один из подходов к разработке ПО, в частности, для МК. Допустим, вы разрабатываете кодовый замок, у него есть 10 кнопок от 0 до 9 , и он должен открываться числом 729.
(Возьмите бумажку, карандашик и рисуйте):
В состояние С1 замок попадает после включения питания. В этом состоянии он ждет нажатия любой из кнопок. Если нажата только одна кнопка, и это "7", то замок переходит в состояние С2, во всех прочих случаях он остается в состоянии С1.
В состоянии С2 замок опять ждет нажатия любой из кнопок. Если нажата только одна кнопка, и это "2", то замок переходит в состояние С3, во всех прочих случаях он переходит в состояние С1.
В состоянии С3 замок опять ждет нажатия любой из кнопок. Если нажата только одна кнопка, и это "9", то замок переходит в состояние С4, во всех прочих случаях он переходит в состояние С1.
В состоянии C4 замок открывается (втягивает защелку) и ждет три секунды, а затем отпускает защелку и переходит в состояние C5.
В состоянии С5 замок ждет отпускания всех кнопок (остается в нем, если не все кнопки отпущены). Если же все кнопки отпущены, то замок переходит в состояние С1, после чего все повторяется сначала. Понятно ?
Попробуйте сделать такой замок сами, только предусмотрите подавление дребезга от кнопок ...

А, вот еще есть книжка Лобанова. Там не совсем про МК, но суть та же:
http://lord-n.narod.ru/walla.html

Ладно, пока Лобанова не читайте, а то запутаетесь ...
Дмитрий(846)
Честно говоря я уже запутанный.

Я понял что ничего не получиться самостоятельно.
kovigor
Цитата(Дмитрий(846) @ Mar 13 2013, 22:33) *
Честно говоря я уже запутанный.

Я понял что ничего не получиться самостоятельно.

Нет, наоборот, тут все просто, как песня. Вы просто сходу за слишком сложную задачу взялись. Начните с двух простых задач. Реализуйте в виде цифровых автоматов:
-Светофор. Пусть он переключается в каждое следующее состояние по нажатию кнопки. Предусмотрите (обязательно) в том же автомате в виде доп. состояний механизм подавления дребезга
-Кодовый замок. Блок-схему алгоритма я набросал выше, но это только набросок. Подойдите к нему творчески.

В обоих случаях для отсчета временных интервалов пользуйтесь прерыванием от таймера

P.S. А вообще, я вам указал на книги по программированию для МК. Читали ? Смотрели ? Ничего непостижимого там нет, программирование МК доступно даже старшеклассникам
Дмитрий(846)
Но зачем?
Ведь есть уже готовое, осталось только подкорректировать, не без вашего участия.

Может давайте поможете мне разобрать код, дополнить его, оптимизировать его работу
kovigor
Цитата(Дмитрий(846) @ Mar 13 2013, 23:17) *
Но зачем?

Да нет у меня времени разбираться в чужом коде, тем более, что этот проект - не самый простой проект на свете. В него нужно вникать, и вникать глубоко. Да и разбирательство это мне ни к чему, ничему новому я там не научусь.
Ладно. Не хотите учиться - не нужно. Я умываю руки. Проект-то ваш. Вы сами не дотите ничего сделать cамостоятельно, чтобы он заработал, так я должен хотеть ? Вам говоришь, как надо, а вы "но зачем ? ...". Ну, тогда, если вы знаете лучше меня, сами и разбирайтесь ...
Дмитрий(846)
Цитата(kovigor @ Mar 14 2013, 00:52) *
Да нет у меня времени разбираться в чужом коде, тем более, что этот проект - не самый простой проект на свете. В него нужно вникать, и вникать глубоко. Да и разбирательство это мне ни к чему, ничему новому я там не научусь.
Ладно. Не хотите учиться - не нужно. Я умываю руки. Проект-то ваш. Вы сами не дотите ничего сделать cамостоятельно, чтобы он заработал, так я должен хотеть ? Вам говоришь, как надо, а вы "но зачем ? ...". Ну, тогда, если вы знаете лучше меня, сами и разбирайтесь ...


Помоги разобраться почему ребутиться!
XVR
Во первых маловат массив text (и пишут в него из прерывания и основной программы)
Во вторых - у вас общение с LCD идет из прерываний и из основного цикла программы - на LCD будет каша
С I2C то же самое

А ребутится может из за использования в прерываниях и основной программе всего, чего только можно. А так же из за использования функции sprintf - ей нужен довольно большой стек (насколько я помню)
Дмитрий(846)
Цитата(XVR @ Mar 15 2013, 09:18) *
Во первых маловат массив text (и пишут в него из прерывания и основной программы)
Во вторых - у вас общение с LCD идет из прерываний и из основного цикла программы - на LCD будет каша
С I2C то же самое

А ребутится может из за использования в прерываниях и основной программе всего, чего только можно. А так же из за использования функции sprintf - ей нужен довольно большой стек (насколько я помню)


Ох? реально не учел текста + %Vol
глюков стало меньше!
Дмитрий(846)
Подскажите после нажатия кнопки на пульте Power, атмега перезагружается
Дмитрий(846)
Подскажите значения, не могу рассчитать значения делителей.

if (key_adc <= 3) return KEY_
if ((key_adc >= 50) && (key_adc <= 108)) return KEY_
if ((key_adc >= 130) && (key_adc <= 178)) return KEY_
if ((key_adc >= 180) && (key_adc <= 198)) return KEY_
if ((key_adc >= 200) && (key_adc <= 248)) return KEY_
if ((key_adc >= 248) && (key_adc <= 255)) return KEY_

НА ноге атмеги с плюсом кинул 4,7 кОм а на кнопках последовательно кинул по 1кОм
artkam
Приведите, пожалуйста, схему...
Дмитрий(846)
Спасибо за помощь
muravei
Цитата(Дмитрий(846) @ Mar 18 2013, 17:19) *
Подскажите значения, не могу рассчитать значения делителей.

Подсказываю: Был такой мужик ,Ом .Так вот , закон его имени.
Далее читаете доку на Мегу16 ,раздел АЦП. Там есть формула перевода напряжения в цифру.
artkam
Как-то уж слишком мудрено у Вас... Предлагаю привести схему к виду, как в приложенном файле, тогда о уровнях напряжения на входе АЦП можно будет просто догадаться, не прибегая даже к закону имени Ома ))))
Дмитрий(846)
Цитата(artkam @ Mar 19 2013, 16:21) *
Как-то уж слишком мудрено у Вас... Предлагаю привести схему к виду, как в приложенном файле, тогда о уровнях напряжения на входе АЦП можно будет просто догадаться, не прибегая даже к закону имени Ома ))))


НУ я замерял напряжение на своей схеме: 0,9 \ 1,52 \ 2,00 \ 2,35 \ 2,64
как в адц перевести???

Еще подскажите как организовать сдвиг бита для регулировки тона.
Исходник привел ниже.
Биты регулировки
в коде
Код
0b1001 G3 G2 G1 G0     Bass tone control
0b1010 K3 K2 K1 K0      Middle tone control
0b1011 H3 H2 H1 H0      Treble tone control

TONE CONTROL BITS
G3/K3/H3 G2/K2/H2 G1/K1/H1 G0/K0/H0      Attenuation (dB)
      0             0              0             0            -14
      0             0              0             1               -12
      0             0              1             0               -10
      0             0              1             1               -8
      0             1              0             0               -6
      0             1              0             1               -4
      0             1              1             0               -2
      0             1              1             1               0
      1             0              0             0               +14
      1             0              0             1               +12
      1             0              1             0               +10
      1             0              1             1               +8
      1             1              0             0               +6
      1             1              0             1               +4
      1             1              1             0               +2
      1             1              1             1               0
Note: G=Bass, K=Middle, H=Treble
kovigor
Цитата(Дмитрий(846) @ Mar 19 2013, 18:12) *
НУ я замерял напряжение на своей схеме: 0,9 \ 1,52 \ 2,00 \ 2,35 \ 2,64
как в адц перевести???

Для этого придется-таки хоть чуть-чуть подумать и вспомнить пропорции, их учат примерно классе в четвертом. Если АЦП 10-разрядный, и на его вход подано его полное опорное напряжение, например, AVCC=5В (я не знаю, какое опорное напряжение вы выбрали для АЦП), то из его регистра будет считано число 1023. Числа для остальных напряжений рассчитайте сами.
Дмитрий(846)
Цитата(kovigor @ Mar 19 2013, 17:46) *
Для этого придется-таки хоть чуть-чуть подумать и вспомнить пропорции, их учат примерно классе в четвертом. Если АЦП 10-разрядный, и на его вход подано его полное опорное напряжение, например, AVCC=5В (я не знаю, какое опорное напряжение вы выбрали для АЦП), то из его регистра будет считано число 1023. Числа для остальных напряжений рассчитайте сами.



Спасибо с кнопками разобрался, перепаял резистор на +5 на 10кОм, а не 4,7кОм.
Все работает вот результат.
Код
unsigned char read_key(void)
{
        unsigned char key_adc;        
        key_adc=read_adc(3);             //3
                
          if                      (key_adc <=   3)  return KEY_STANDBY;
          if ((key_adc >= 20)  && (key_adc <= 60)) return KEY_MUTE;     //45//100-148 = 1000 Om
          if ((key_adc >= 70) &&  (key_adc <= 85)) return KEY_INPUTAC3;     //77//130-178 = 2000 Om
          if ((key_adc >= 90) &&  (key_adc <= 118)) return KEY_INPUT1;    //102//180-198 = 3000 Om
          if ((key_adc >= 120) && (key_adc <= 144)) return KEY_MODE;    //119//200-248 = 4000 Om
          if ((key_adc >= 150) && (key_adc <= 190)) return KEY_INDICATE_PLUS;    //134//200-248 = 5000 Om
}


Теперь нужна помощь с регулировкой тона
kovigor
Цитата(Дмитрий(846) @ Mar 19 2013, 21:41) *
Теперь нужна помощь с регулировкой тона
...
Еще подскажите как организовать сдвиг бита для регулировки тона.

Поздравляю, так бы и раньше. Вещи-то простейшие.

Сдвиг бита ? Любую книжку по Си гляньте, того же Шилдта, справочник, или Крупника

Пример:

Код
unsigned char x, y;

...

x = 0x80;
y = (x >> 1); //Теперь Y = 0x40
y = (y << 1); //Теперь Y равно = 0x80

http://www.cyberguru.ru/cpp/cpp-programmin...ide-page27.html
Дмитрий(846)
Очень благодарен за помощь. Но это я понимаю.
Но мне надо начиная с 0 при шаге в право надо +2 ДБ в лево 0 еще в лево -2ДБ на сначениях +14 или -14 остановить выполнение

Значение бита перевел, помогите хоть с bass с остальными я уже сделаю
Код
/*1 0 0 1 G3 G2 G1 G0 Bass tone control
1 0 1 0 K3 K2 K1 K0 Middle tone control
1 0 1 1 H3 H2 H1 H0 Treble tone control
                Bass    Middle   Treble
0 0 0 0 -14     0x90     0xA0     0xB5
0 0 0 1 -12     0x91     0xA1     0xB5
0 0 1 0 -10     0x92     0xA2     0xB5
0 0 1 1 -8      0x93     0xA3     0xB5
0 1 0 0 -6      0x94     0xA4     0xB5
0 1 0 1 -4      0x95     0xA5     0xB5
0 1 1 0 -2      0x96     0xA6     0xB6
0 1 1 1 0       0x97     0xA7     0xB7
1 1 1 1 0       0x9F     0xAF     0xBF
1 1 1 0 +2      0x9E     0xAE     0xBE
1 1 0 1 +4      0x9D     0xAD     0xBD
1 1 0 0 +6      0x9C     0xAC     0xBC
1 0 1 1 +8      0x9B     0xAB     0xBB
1 0 1 0 +10     0x9A     0xAA     0xBA
1 0 0 1 +12     0x99     0xA9     0xB9
1 0 0 0 +14     0x98     0xA8     0xB8
*/
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.