Jump to content

    
Sign in to follow this  
Waso

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

Recommended Posts

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

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

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

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

Share this post


Link to post
Share on other sites

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

 

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

lwIP4IAR.ZIP

Share this post


Link to post
Share on other sites

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

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

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

Share this post


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

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

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

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

Share this post


Link to post
Share on other sites
Выкладываю портированный мною под ИАР 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. Не пора ли ее переместить куда-то в более общее место?

Share this post


Link to post
Share on other sites

Мои 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-- = ' ';
}

Share this post


Link to post
Share on other sites

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;
}

Edited by umup

Share this post


Link to post
Share on other sites

Подсчет 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;

}

Share this post


Link to post
Share on other sites

Матричная клавиатура. Гашение дребезга. Ввод-вывод. Ввод символьной информации методом нескольких нажатий. Всё для 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

Share this post


Link to post
Share on other sites

Вот ссылка на классную библиотеку 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 )

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Исходник (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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this