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

Исходники программ и библиотек

пример проекта умножения с плавающей точкой.

работает быстрее, чем стандартная Си операция благодаря использованию аппаратного умножителя.

Подходит только для серии Mega

:bb-offtopic: Прошу прощения, а разве современные компиляторы не умеют использовать аппаратный умножитель? Или я Вас неверно понял?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот куча исходников для AVR от немцев.

https://141.57.27.10/svn/avr-common-source/

 

http://www.ifas.htwk-leipzig.de/easytoweb/...ontent=download

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Выкладываю портированный мною под ИАР TCP-IP стек LwIP из демо FreeRTOS для отладочной платы AT91SAM7X-EK. Он все еще выдает некоторое количество варнингов, но они связаны с выключенным дебагом. Работает web-сервер, отвечает на пинги. Перед прошивкой нужно задать айпишники в хедере sam7_emac.h. Версия lwIP - 1.1.0. Когда попытался прикрутить более новую - удивился как много оставлено для дописывания ручками в исходниках.

 

Благодарю за помощь в освоении С и IAR местных гуру и особенно Сергей Борщ.

lwIP4IAR.ZIP

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь есть библиотеки для MODBUS

http://freemodbus.berlios.de/index.php

Поскольку free, то естественно WinAVR, но и не только для AVR. Прошу прощения если повторяюсь, 9стр. перелистывать неохота.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что-то получается слишком большой размер кода. у меня RTU поместился в 500 байт Flash и 30 ОЗУ

Дело еще в том, на сколько код "откатан" в железе. Немного поизучали эту тему, но в последствии выяснилось, что в реализации всего протокола нет необходимости, а возможные коллизии обошли таймаутами. В сети попадлись вопросы в этой связИ, вот еще ветка:

http://www.fulcrum.ru/cgi-bin/bbs/mess_sel...;Sp=0&LID=0

Если Вы приаттачите свой исходик, то буду признателен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот кусок :

www.ukpyr.narod.ru/mb_clp.c

правда там только функция 3, но при желании несложно добавить и другие.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Выкладываю портированный мною под ИАР TCP-IP стек LwIP
А как все начиналось... :)
Предлагаю сюда скидывать

...

Самому мне правда пока нечего выкинуь. pardon00.gif Наоборот, нужны исходники для стандартного текстового ЖКИ-дисплея, клавиатуры 4х4, АЦП, ШИМ и пользовательского интерфейса.

 

Пополню копилку. Даже не исходником, а полезным приемом. Навеяно несколькими вопросами в последнее время, когда "все не работает" потому что программа ушла в необъявленный обработчик прерывания. Можно поставить на все неиспользуемые обработчики заглушки, но, во-первых, это не решение, а расчалка и распорка. А во-вторых не всякий флаг прерывания сбрасывается от самого факта входа в обработчик. Т.е. попали в заглушку, вышли из нее, тут же снова попали... Заглушка позволяет локализовать проблему. Но если заглушек несколько, возникает вопрос - в какую из них попадает программа? Хорошо, если есть много свободных ног - можно в каждой заглушке махать своей ногой. Но опять же есть неудобство - искать точки на плате, куда подключиться осциллографом, и перебирать их щупом. Идея в том, чтобы использовать одну ногу, а конкретное место программы, где нога шевелится, определять по скважности генерируемого сигнала:

ISR(ADC_vect)
{
    for(;;)
    {
        on(TEST);
        _nop();
        _nop();
        _nop();
        off(TEST)
    }
}
ISR(UDRE_vect)
{
    for(;;)
    {
        _nop();
        on(TEST);
        _nop();
        _nop();
        off(TEST)
    }
}
......
ISR(UDRE_vect)
{
    for(;;)
    {
        _nop();
        _nop();
        on(TEST);
        _nop();
        off(TEST)
    }
}
.......
ISR(TIMER2_COMP_vect)
{
    for(;;)
    {
        _nop();
        _nop();
        _nop();
        on(TEST);
        off(TEST)
    }
}

Отсчитать скважность можно буквально по клеткам на экране.

 

 

P.S. Тема получилась очень полезная и давно переросла подфорум AVR. Не пора ли ее переместить куда-то в более общее место?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мои 0,5 копейки:

 

Реализация форматированного преобразования int в ASCII-строку.

Использован алгоритм, предложенный =AVR='ом:

 

void ltoa_fmt(long val, s_char length, u_char *buff)
{
long ltemp;
int itemp;
s_char binc,atemp;
u_char *ptr1, *ptr2;

  ptr1 = buff;

  if (val<0)
   {
     val = -val;
     *buff++ = '-';
   }

  atemp='0';
  ltemp=1000000;
    while(val >= ltemp)
    {
      atemp++;
      val-=ltemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  ltemp=100000;
    while(val >= ltemp)
    {
      atemp++;
      val-=ltemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  itemp=10000;
    while(val >= itemp)
    {
      atemp++;
      val-=itemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  itemp=1000;
    while(val >= itemp)
    {
      atemp++;
      val-=itemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  itemp=100;
    while(val >= itemp)
    {
      atemp++;
      val-=itemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  binc=(char)val;
    while(binc >= 10)
    {
      atemp++;
      binc-=10;
    };
  if(atemp != '0')
    *buff++=atemp;
  binc += '0';
  *buff=binc;

  atemp = buff - ptr1 + 1; 
  ptr2 = ptr1 + length-1;
  while(atemp--)
    *ptr2-- = *buff--;
  atemp = ptr2 - ptr1 + 1;
  while(atemp--)           
    *ptr2-- = ' ';
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

bin2bcd AVR :

 u32 bin2bcd_u32(u32 data, u8 result_bytes) NAKED;
u32 bin2bcd_u32(u32 data, u8 result_bytes)
{asm volatile(
  "push __tmp_reg__ \n push r26 \n push r27 \n push r30 \n push r31 \n"
  "mov __tmp_reg__, %A1   \n" /*number of bytes in result*/
   "bin2bcd_u32_00:       \n" /*correct input number by left shifts*/
     "mov r31, %A0        \n"
     "mov %A0, %B0        \n"
     "mov %B0, %C0        \n"
     "mov %C0, %D0        \n"
     "mov %D0, r31        \n"
     "dec __tmp_reg__     \n"
     "brne bin2bcd_u32_00 \n"
  
   "eor r26, r26          \n" /*clear result*/
   "eor r27, r27          \n"
   "eor r30, r30          \n"
   "eor r31, r31          \n"
   "mov __tmp_reg__, %A1  \n"
   "lsl __tmp_reg__ \n lsl __tmp_reg__ \n lsl __tmp_reg__ \n" /*__tmp_reg__=size in bits*8*/
  
   "bin2bcd_u32_01:       \n" /*shift loop*/
    "subi r26,-0x33       \n" /*add 0x33*/
    "sbrs r26, 3          \n" /*if carry to bit 3,*/
    "subi r26, 3          \n" /*subtract 3*/
    "sbrs r26, 7          \n" /*if carry to bit 7,*/
    "subi r26, 0x30       \n" /*subtract 0x30*/
    "subi r27,-0x33       \n" /*add 0x33*/
    "sbrs r27, 3          \n" /*if carry to bit 3,*/
    "subi r27, 3          \n" /*subtract 3*/
    "sbrs r27, 7          \n" /*if carry to bit 7,*/
    "subi r27, 0x30       \n" /*subtract 0x30*/
    "subi r30,-0x33       \n" /*add 0x33*/
    "sbrs r30, 3          \n" /*if carry to bit 3,*/
    "subi r30, 3          \n" /*subtract 3*/
    "sbrs r30, 7          \n" /*if carry to bit 7,*/
    "subi r30, 0x30       \n" /*subtract 0x30*/
    "subi r31,-0x33       \n" /*add 0x33*/
    "sbrs r31, 3          \n" /*if carry to bit 3,*/
    "subi r31, 3          \n" /*subtract 3*/
    "sbrs r31, 7          \n" /*if carry to bit 7,*/
    "subi r31, 0x30       \n" /*subtract 0x30*/
    "lsl r26 \n rol r27 \n rol r30 \n rol r31 \n" /*shift out buffer*/
   
    "sbrc %D0, 7          \n" /*skip if msbit of input =0*/
    "ori  r26, 1          \n" /*set lsb of output*/
    "lsl %A0 \n rol %B0 \n rol %C0 \n rol %D0 \n"/*shift input*/
   
    "dec __tmp_reg__      \n"
    "brne bin2bcd_u32_01  \n" /*repeat for all bits*/
   
    "movw r22, r26        \n" /*move result*/
    "movw r24, r30        \n"
    "pop r31 \n pop r30 \n pop r27 \n pop r26 \n pop __tmp_reg__\n"
    "ret \n"
  : :"r"(data),"r"(result_bytes):"r0","r26","r27","r30","r31" /*input and output parameters*/
  );

 

bin2bcd C :

 u32 bin2bcd_u32(u32 data, u8 result_bytes)
{u32 result = 0; /*result*/
  u8 u8_1;
  for (u8_1 = (4 - result_bytes); u8_1; u8_1--) data <<= 8; /*adjust input bytes*/
  for (u8_1 = (result_bytes << 3); u8_1; u8_1--) /*bit shift loop*/
  {u8 u8_2, u8_3;
   /*result BCD nibbles correction*/
   result += 0x33333333;
   /*result correction loop*/
   for (u8_3 = 4; u8_3; u8_3--)
   {u8_2 = result >> 24;
    if (!(u8_2 & 0x08)) u8_2 -= 0x03;
    if (!(u8_2 & 0x80)) u8_2 -= 0x30;
    result <<= 8; /*shift result*/
    result |= u8_2; /*set 8 bits of result*/
   }
   /*shift next bit of input to result*/
   result <<= 1;
   if (((u8)(data >> 24)) & 0x80) result |= 1;
   data <<= 1;
  }
  return(result);
}

 

bcd2bin AVR (GCC) :

 u32 bcd2bin_u32(u32 data, u8 result_bytes) NAKED;
u32 bcd2bin_u32(u32 data, u8 result_bytes)
{asm("push __tmp_reg__ \n push r26 \n push r27 \n push r30 \n push r31 \n"
  "eor r26, r26           \n" /*clear result*/
  "eor r27, r27           \n"
  "eor r30, r30           \n"
  "eor r31, r31           \n"
  "mov __tmp_reg__, %A1   \n"
  "lsl __tmp_reg__ \n lsl __tmp_reg__ \n lsl __tmp_reg__ \n" /*__tmp_reg__=input parameter size in bits*/

   "bcd2bin_u32_00:       \n" /*bits shift loop*/
   
    "lsr r31 \n ror r30 \n ror r27 \n ror r26 \n" /*shift out buffer*/
   
    "sbrc %A0, 0          \n" /*move lowest bit*/
    "ori  r31, 0x80       \n"
   
    "lsr %D0 \n ror %C0 \n ror %B0 \n ror %A0 \n"
   
    "sbrc %D0, 7          \n" /*if carry to bit 7,*/
    "subi %D0, 0x30       \n" /*subtract 0x30*/
    "sbrc %D0, 3          \n" /*if carry to bit 3,*/
    "subi %D0, 3          \n" /*subtract 3*/
    "sbrc %C0, 7          \n" /*if carry to bit 7,*/
    "subi %C0, 0x30       \n" /*subtract 0x30*/
    "sbrc %C0, 3          \n" /*if carry to bit 3,*/
    "subi %C0, 3          \n" /*subtract 0x30*/
    "sbrc %B0, 7          \n" /*if carry to bit 7,*/
    "subi %B0, 0x30       \n" /*subtract 0x30*/
    "sbrc %B0, 3          \n" /*if carry to bit 3,*/
    "subi %B0, 3          \n" /*subtract 3*/
    "sbrc %A0, 7          \n" /*if carry to bit 7,*/
    "subi %A0, 0x30       \n" /*subtract 0x30*/
    "sbrc %A0, 3          \n" /*if carry to bit 3,*/
    "subi %A0, 3          \n" /*subtract 3*/
   
    "dec __tmp_reg__      \n" /*repeat for all bits*/
    "brne bcd2bin_u32_00  \n"
   
   "movw r22, r26         \n" /*adjust result bytes*/
   "movw r24, r30         \n"
    "bcd2bin_u32_01:      \n"
     "mov __tmp_reg__,r25 \n"
     "mov r25,r24         \n"
     "mov r24,r23         \n"
     "mov r23,r22         \n"
     "mov r22,__tmp_reg__ \n"
     "dec %A1             \n"
     "brne bcd2bin_u32_01 \n"
  
   "pop r31 \n pop r30 \n pop r27 \n pop r26 \n pop __tmp_reg__ \n"
   "ret \n"
   : :"r"(data),"r"(result_bytes):"r0","r26","r27","r30","r31" /*input and output parameters*/
  );
}

 

bcd2bin C :

 u32 bcd2bin_u32(u32 data, u8 input_bytes)
{u32 result = 0; /*result*/
  u8 cnt_bits, cnt_bytes, tmp_byte;
  for (cnt_bits = (input_bytes << 3); cnt_bits; cnt_bits--)
  {/*shift next bit*/
   result >>= 1;
   if (((u8)(data)) & 0x01) result |= 0x80000000;
   data >>= 1;
   {/*BCD correction of result*/
    for (cnt_bytes = 4; cnt_bytes; cnt_bytes--)
    {tmp_byte = (data >> 24);
     if (tmp_byte & 0x80) tmp_byte -= 0x30;
     if (tmp_byte & 0x08) tmp_byte -= 0x03;
     data <<= 8;
     data |= tmp_byte;
    }
   }
  }
  /*adjust result bytes*/
  for (cnt_bits = (4 - input_bytes); cnt_bits; cnt_bits--) result >>= 8;
  return(result);
}

 

 

num2asc C - форматированный вывод числа с фикс.запятой в ASCI-буфер (options&7 = общее количество знаков, (options>>4)&7 = положение запятой считая справа, options&8 = 8 - отображать начальные нули, options&80 = 80 - сначала преобразовать в BCD) :

void num2asc_s32(s32 data, u8 *buf, u8 options)
{u8 cnt_chars, point_pos;
cnt_chars = (options & 7); /*number of digits*/
/*convert negative to positive, set '-' flag*/
if (data < 0) {data = -data; options |= 1;} else options &= ~1;
/*if necessary, convert to BCD*/
if (options & 0x80) data = bin2bcd_u32(data, (cnt_chars >> 1) + 1);
cnt_chars++;
/*calculate point position*/
point_pos = cnt_chars - ((options >> 4) & 7);
if (point_pos) point_pos++;
while (cnt_chars) /*digits conversion loop*/
{if ((options & 8) && (data == 0) && (cnt_chars < point_pos))
  {if (options & 1) *buf = asc_minus; else *buf = asc_space;
   options &= ~1;
  } else
   {if ((cnt_chars == point_pos) && (options & 0x70)) /*store point*/
    {*buf = asc_point;
     cnt_chars--;
     buf--;
    }
    *buf = bin2asc_u8(data); /*store ASCII digit*/
   }
  cnt_chars--;
  buf--;
  data >>= 4;
}
if (options & 1) *buf = asc_minus;
}

Изменено пользователем umup

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подсчет CRC для DALLAS 1Wire устройств.Работает очень быстро.

 

unsigned char crc_ib(unsigned char __crc,unsigned char data)

{

unsigned char temp;

temp=__crc^data;

__crc=0;

if (temp&(1<<7)){__crc^=0x8C;}

if (temp&(1<<6)){__crc^=0x46;}

if (temp&(1<<5)){__crc^=0x23;}

if (temp&(1<<4)){__crc^=0x9D;}

if (temp&(1<<3)){__crc^=0xC2;}

if (temp&(1<<2)){__crc^=0x61;}

if (temp&(1<<1)){__crc^=0xBC;}

if (temp&(1<<0)){__crc^=0x5E;}

return __crc;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Матричная клавиатура. Гашение дребезга. Ввод-вывод. Ввод символьной информации методом нескольких нажатий. Всё для IAR C.

 

Для того, чтобы не вносить дополнительных ошибок выкладываю процедуры и библиотеки "как есть" из своего проекта. Всё однозначно рабочее. Клавиатура применена 3х4 с маркировкой как для АОНа. (Использовались данные толкатели). Библиотеки будут вложены, а примеры применения и некоторые подпрограммы - здесь.

 

Для реализации символьного ввода используется п/п динамического ввода на клавишу из библиотеки клавиатуры. Всё реализовано для atmega8/88

 

Инициализация

// Инициализировать таймер 0 и прерывания для опроса клавиш
#if __ATmega88__
  TCCR0A = 0x02;                                            // Режим СТС
  TCCR0B = 0x5;                                                // FCLK/1024 (14.4KHz/69.4mks)
  OCR0A = T_INT_TIM*1000000/1024/TCLK;                        // прерывание T_INT_TIM ms
  TIMSK0 = 2;                                                // Прерывания от CTC
#elif __ATmega8__
  TCCR0 = 0x05;                                                // Режим NORMAL, FCLK/1024 (14.4KHz/69.4mks)
  TIMSK |= 1;                                                // Прерывания от переполнения
#endif
// Инициализировать оборудование
  DelayInit();                                                // Инициализация таймера
  LCDInit();                                                // Инициализировать LCD дисплей
  spliter_init();                                            // Инициализировать сплитер
  KeyInit();                                                // Инициализация клавиатуры
  WakeInit();                                                // Инициализация интерфейса rs485 и протокола WakeUp
  __enable_interrupt();                                        // Разрешить прерывания

 

Символьный ввод

const uint8_t __flash strkey[10][6] =
{
  {'0',' ','-','=','+',0},
  {'1',',','.',';',':',0},
  {'2','А','Б','В','Г',0},
  {'3','Д','Е','Ж','З',0},
  {'4','И','Й','К','Л',0},
  {'5','М','Н','О',0,0},
  {'6','П','Р','С',0,0},
  {'7','Т','У','Ф','Х',0},
  {'8','Ц','Ч','Ш','Щ',0},
  {'9','Ы','Э','Ю','Я',0}
};



uint8_t    getextchar(void)                                    // Ввести расширенную клавишу
{
  uint8_t    c, index, old, tekc, d;

  
  index=0;
  while(KeyPress()==0);                        // Если установлен бит Int_Key, то клавиша была нажата
  do
  {
    while(KeyPress()!=0);                    // ждём пока клавишу отпустят
    c = getchar();                            // прочитать код клавиши
    old=c;                                    // запомнить последнюю нажатую кнопку
    if(c < '0') return(c);                    // Если клавиши управления, то выйти
    else c -= '0';
    WaitLong = PAUZA;                        // Измерить паузу после нажатия
    tekc=strkey[c][index];                    // текущий символ
    putchar(tekc);                            // вывести
    do
      if(KeyPress()!=0)                        // Если клавиша была нажата снова
      {
        d=KeyPress();                        // прочитать код клавиши
        if(d!=old)return(tekc);                // если изменили клавишу, то выйти
        index++;                            // Следующий символ из ряда
        if(strkey[c][index]==0)index=0;        // если конец ряда, то выйти
        putchar(CR_BS);                        // Забить предыдущий символ
        break;
      }
    while(WaitLong!=0);
  }
  while(WaitLong!=0);
  return(tekc);
}

 

Само прерывание опроса клавиатуры и меток времени

#ifdef __PORT88__
#pragma    vector=TIMER0_COMPA_vect                            // Метки времени 10 мс
#else
#pragma    vector=TIMER0_OVF_vect                                // Метки времени 10 мс
#endif
__interrupt    static void    MetkiTime10ms(void)
{

#if __ATmega8__
TCNT0 = -(T_INT_TIM*1000000/1024/TCLK);
#endif
  KeyScan();                                                // Опросить клавиши
  KeyStrSet();                                              // выставить строку
  if(WaitLong!=0)WaitLong--;                                // Высчитать задержку
}

Kls3x4.zip

lcd44780.zip

timerhw.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот ссылка на классную библиотеку 1-wire:

http://files.dalsemi.com/auto_id/public/owpd310.zip

( http://www.maxim-ic.com/products/ibutton/s...ire/wirekit.cfm )

 

А здесь, если порыться, можно найти много полезного по той же части:

ftp://ftp.dalsemi.com/pub/auto_id/softdev/

( ftp://ftp.dalsemi.com/pub/auto_id/softdev/softdev.html )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8бит ЦАП/АЦП, или звуко-проигрыватель PCM/ADPCM (11025Hz) с управлением по EIA-232, или тремя кнопками. писалось в целях ознакомления с AVR, надеюс будет кому то полезно. исходник на C и управляющая прожка под linux, http://www.paravozeg.narod.ru/avr_prog_md.tar.gz

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Исходник (CVAVR) для декодирования IR пульта старых телеков Goldstar.

После приема отправляет по USART. Котроллер Mega16 16МГц; выход TSOPа на INT0(PD2).

 

Communication Parameters: 8 Data, 1 Stop, No Parity

USART Mode: Asynchronous

USART Baud Rate: 38400

 

Исходник:

goldstar.c.txt

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

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