subroutine.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. *
  3. * Подпрограмки, которые я успел наваять на C
  4. *
  5. */
  6. //============================================================================
  7. // программный SPI. Выводит байт начиная со старшего бита
  8. // выходные пины -- SCK, MOSI, порт -- SPI_PORT. строб -- из 0 в 1
  9. void spi_SendByte (uint8_t DataByte) {
  10. uint8_t i; // счетчик бит
  11. for (i=8; i>0; i--) {
  12. SPI_PORT &= (~(1<<PIN_SCK)); // выдали строб
  13. if (bit_is_set(DataByte,7)) { // если бит 7 == 1
  14. SPI_PORT |= (1<<PIN_MOSI); // MOSI = 1
  15. } else { // если бит 7 == 0
  16. SPI_PORT &= (~(1<<PIN_MOSI)); // MOSI = 0
  17. }
  18. SPI_PORT |= (1<<PIN_SCK); // защёлкнули строб
  19. DataByte <<= 1; // сдвиг влево на 1 бит
  20. }
  21. }
  22. //============================================================================
  23. // bcd2ascii
  24. // придумал сам, ещё не проверял
  25. typdef struct {uint8_t msb, uint8_t lsb} x2_ascii;
  26. x2_ascii BCD_to_ASCII(unit8_t bcd) {
  27. x2_ascii ascii;
  28. ascii.msb = bcd;
  29. ascii.lsb = bcd;
  30. ascii.msb >>= 4;
  31. ascii.msb |= 0x0F;
  32. ascii.lsb |= 0x0F;
  33. ascii.msb += 0x30;
  34. ascii.lsb += 0x30;
  35. return ascii;
  36. }
  37. // как-то так...
  38. //============================================================================
  39. /*
  40. http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=66337
  41. Post subject: RE: 16bit Binary to BCD conversion
  42. The cheap way, leveraging on the C libraries ascii conversion routines.
  43. Code:
  44. */
  45. char (*a)[10]; // Указатель на массив из десяти символов
  46. // returns number of digits converted
  47. // result array must be large enough to hold
  48. // the number of digits converted.
  49. int itobcd(unsigned int val, char *result)
  50. {
  51. char BCD_text[6]; // max 5 digits in a 16 bit uint
  52. int i;
  53. itoa(val, BCD_text, 10);
  54. i=0;
  55. while(BCD_text[i])
  56. {
  57. result[i] = BCD_text[i]-'0';
  58. i++;
  59. }
  60. return i;
  61. }
  62. //============================================================================
  63. // http://www.strudel.org.uk/itoa/
  64. // char* version 0.1
  65. char* itoa(int val, int base){
  66. static char buf[32] = {0};
  67. int i = 30;
  68. for(; val && i ; --i, val /= base){
  69. buf[i] = "0123456789abcdef"[val % base];
  70. }
  71. return &buf[i+1];
  72. }
  73. // char* version 0.4
  74. /*
  75. * C++ version 0.4 char* style "itoa":
  76. * Written by Lukas Chmela
  77. * Released under GPLv3.
  78. */
  79. char* itoa(int value, char* result, int base) {
  80. // check that the base if valid
  81. if (base < 2 || base > 36) { *result = '\0'; return result; }
  82. char* ptr = result, *ptr1 = result, tmp_char;
  83. int tmp_value;
  84. do {
  85. tmp_value = value;
  86. value /= base;
  87. *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
  88. } while ( value );
  89. // Apply negative sign
  90. if (tmp_value < 0) *ptr++ = '-';
  91. *ptr-- = '\0';
  92. while(ptr1 < ptr) {
  93. tmp_char = *ptr;
  94. *ptr--= *ptr1;
  95. *ptr1++ = tmp_char;
  96. }
  97. return result;
  98. }
  99. //============================================================================
  100. /*
  101. Реализация от Кернигана и Ритчи
  102. Функция itoa появилась в первом издании книги Брайана Кернигана и Дениса
  103. Ритчи Язык программирования Си, на странице 60. Второе издание Язык
  104. программирования Си («K&R2») на стр. 64 содержало нижеследующую реализацию
  105. itoa. В книге отмечено несколько вопросов, связанных с этой реализацией,
  106. включая тот факт, что она не в состоянии корректно обработать самое
  107. маленькое отрицательное число -2длина машинного слова в битах-1.[1]
  108. */
  109. /* itoa: конвертируем n в символы в s */
  110. void itoa(int n, char s[])
  111. {
  112. int i, sign;
  113. if ((sign = n) < 0) /* записываем знак */
  114. n = -n; /* делаем n положительным числом */
  115. i = 0;
  116. do { /* генерируем цифры в обратном порядке */
  117. s[i++] = n % 10 + '0'; /* берем следующую цифру */
  118. } while ((n /= 10) > 0); /* удаляем */
  119. if (sign < 0)
  120. s[i++] = '-';
  121. s[i] = '\0';
  122. reverse(s);
  123. }
  124. /*
  125. Функция reverse реализована двумя страницами ранее:
  126. */
  127. #include <string.h>
  128. /* reverse: переворачиваем строку s на месте */
  129. void reverse(char s[])
  130. {
  131. int i, j;
  132. char c;
  133. for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
  134. c = s[i];
  135. s[i] = s[j];
  136. s[j] = c;
  137. }
  138. }
  139. //============================================================================
  140. // задержка на прерываниях
  141. void delay_ms (word ms) {
  142. ADCSRA &= (~(1<<ADEN)); // выключим АЦП
  143. do { // два байта экономии
  144. set_sleep_mode(SLEEP_MODE_IDLE);
  145. sleep_mode();
  146. } while (ms > 0);
  147. ADCSRA |= (1<<ADEN); // включим АЦП
  148. }