Advertisement
Guest User

Untitled

a guest
Dec 9th, 2019
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.92 KB | None | 0 0
  1. #include <mega128a.h>
  2. #include <delay.h>
  3. #define _BV(b) (1 << (b))
  4. #define MUX (_BV(REFS0))
  5. #define BIT_IS_CLEAR(Reg, b) ((Reg & _BV(b)) == 0)
  6.  
  7.  
  8. unsigned char Digit (unsigned int d, unsigned char m)
  9. {
  10. //[]-----------------------------------------------------[]
  11. //| Назначение: выделение цифр из разрядов пятиразрядного |
  12. //| десятичного положительного числа |
  13. //| Входные параметры: |
  14. //| d - целое десятичное положительное число |
  15. //| m - номер разряда (от 1 до 5, слева направо) |
  16. //| Функция возвращает значение цифры в разряде m числа d |
  17. //[]-----------------------------------------------------[]
  18.     unsigned char i = 5, a;
  19.     while(i)
  20.     { // цикл по разрядам числа 21
  21.         a = d%10; // выделяем очередной разряд
  22.         if(i-- == m) break; // выделен заданный разряд - уходим
  23.         d /= 10; // уменьшаем число в 10 раз
  24.     }
  25.     return(a);
  26. }
  27.  
  28. void sgmnt_init()
  29. {
  30.     DDRC = 0xFF;
  31.     DDRA |= (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
  32. }
  33.  
  34. void sgmnt_write(unsigned int number)
  35. {
  36.     unsigned char i;
  37.     unsigned char num;
  38.     for (i = 1; i < 6; i++)
  39.     {
  40.         num = Digit (number, i);
  41.         switch (num)
  42.         {
  43.         case 0:
  44.         PORTC = 0x3F;  
  45.         break;
  46.                  
  47.         case 1:
  48.         PORTC = 0x06;
  49.         break;
  50.                
  51.         case 2:
  52.         PORTC = 0x5B;
  53.         break;
  54.                
  55.         case 3:
  56.         PORTC = 0x4F;
  57.         break;
  58.                
  59.         case 4:
  60.         PORTC = 0x66;
  61.         break;
  62.                
  63.         case 5:
  64.         PORTC = 0x6D;
  65.         break;
  66.                
  67.         case 6:
  68.         PORTC = 0x7D;
  69.         break;
  70.                
  71.         case 7:
  72.         PORTC = 0x7;
  73.         break;
  74.                
  75.         case 8:
  76.         PORTC = 0x7F;
  77.         break;
  78.                
  79.         case 9:
  80.         PORTC = 0x6F;
  81.         break;
  82.                
  83.         }
  84.                
  85.         PORTA |= (1 << i);
  86.         delay_us(10);
  87.         PORTA &= ~(1 << i);
  88.     }  
  89. }
  90.  
  91.  
  92. unsigned int readAdc(unsigned char channel)
  93. {
  94.     ADMUX = MUX | channel;
  95.     delay_us(10);
  96.     ADCSRA |= _BV(ADSC);
  97.     while(BIT_IS_CLEAR(ADCSRA, ADIF));
  98.     ADCSRA |= _BV(ADIF);
  99.     return ADCW;
  100. }
  101.  
  102.  
  103.  
  104. void main(void)
  105. {
  106.     int field; // Значение с датчика Холла
  107.     int ref; // Задание
  108.     int error0 = 0;
  109.     int error1 = 0; // Ошибка управления
  110.     int control; // Сигнал управления
  111.     int kp = 2;
  112.     int kd = 0.1;
  113.        
  114.  
  115.     // Инициализация портов ввода/вывода
  116.     DDRB = _BV(5);
  117.     DDRG = _BV(3);
  118.     // Инициализация АЦП
  119.     ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
  120.     // Инициализация таймера 1
  121.     // Быстрая ШИМ 8 бит
  122.     TCCR1A = _BV(COM1A1) | _BV(WGM10);
  123.     TCCR1B = _BV(WGM12) | _BV(CS10);  
  124.    
  125.     sgmnt_init();
  126.    
  127.     while(1)
  128.     {
  129.        
  130.         // Получение и фильтрация сигнала с датчика
  131.         // магнитного поля
  132.         field = (readAdc(1) + readAdc(1) +
  133.         readAdc(1) + readAdc(1) + readAdc(1)) / 5;
  134.         ref = readAdc(3); // Получение задания с ручки
  135.         //потенциомера
  136.         // Расчёт ошибки управления
  137.         error1 = ref - field;
  138.         // Расчёт сигнала управления
  139.         control = error1*1.1 + (error1 - error0)*50;
  140.         // Ограничение сигнала управления
  141. //        if (error1 > 0)
  142. //            sgmnt_write(error1);
  143. //        else
  144. //            sgmnt_write(-1*error1);
  145. //        delay_ms(300);
  146.         error0 = error1; //предыдущее значение
  147.            
  148.        
  149.         if(control > 255)
  150.         {
  151.             control = 255;
  152.         }
  153.         if(control < -255)
  154.         {
  155.             control = -255;
  156.         }
  157.         // Установка сигнала управления
  158.         if(control >= 0)
  159.         {
  160.             PORTG &= ~_BV(3);
  161.             OCR1AL = (unsigned char)control;
  162.         }
  163.         else
  164.         {
  165.             PORTG |= _BV(3);
  166.             OCR1AL = (unsigned char)(-control);
  167.         }
  168.        
  169.         /*
  170.         int field; // Значение с датчика Холла
  171.         int ref; // Задание
  172.         int error = 0; // Ошибка управления
  173.         int control; // Сигнал управления
  174.         //управления
  175.         // Получение и фильтрация сигнала с датчика
  176.         // магнитного поля
  177.         field = (readAdc(1) + readAdc(1) +
  178.         readAdc(1) + readAdc(1) + readAdc(1)) / 5;
  179.         field -= 512;
  180.         ref = readAdc(3); // Получение задания с ручки
  181.         //потенциомера
  182.         // Расчёт ошибки управления
  183.         error = ref - field;
  184.         // Расчёт сигнала управления
  185.         control = error / 1.3 + (error1-error0)*400;
  186.         // Ограничение сигнала управления
  187.         error0 = error1; //предыдущее значение
  188.        
  189.         if(control > 255)
  190.         {
  191.         control = 255;
  192.         }
  193.         if(control < -255)
  194.         {
  195.         control = -255;
  196.         }
  197.         // Установка сигнала управления
  198.         if(control >= 0)
  199.         {
  200.         PORTG &= ~_BV(3);
  201.         OCR1AL = (unsigned char)control;
  202.         }
  203.         else
  204.         {
  205.         PORTG |= _BV(3);
  206.         OCR1AL = (unsigned char)(-control);
  207.         }*/
  208.     }
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement