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

Перевод БК с дисплея от Siemens на 1602


Inmixxx Channel

Рекомендуемые сообщения

Ребят, кому не сложно, гляньте пожалуйста на код. Работаю обычно на Bascom AVR, c языком С столкнулся впервые. Захотел перевести Бортовой компьютер пользователя @mr_smit (ссылка на страницу http://cxem.net/avto/electronics/4-116.php) на символьный дисплей winstar. Танцами с бубном пытаюсь переделать код. Вроде и ошибок нет, прошил контроллер, но ничего не выводит. И еще у меня схема без кварцевого резонатора (работает на 8Мгц). Таймеры перевел вроде

#include <mega32.h>

// Alphanumeric LCD functions
//#include <alcd.h>
#include <alcd.h>

// Standard Input/Output functions
#include <stdio.h>
#include <delay.h>
#include <string.h>
#include <stdio.h>
// SPI functions
#include <spi.h>


#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

#define Connect      1
#define ReadData     2
#define ReadError    3
#define SpeedSample  4

int mode;


char convert[32];

#define BUFFER_SIZE 200
unsigned char buffer[BUFFER_SIZE];                       // приемный буффер

flash unsigned char startCommunication[]                 = {0x81,0x10,0xf1,0x81,0x03};
flash unsigned char readDataByLocalIdentifier_RLI_ASS[]  = {0x82,0x10,0xF1,0x21,0x01,0xA5};
flash unsigned char readDTCByStatus[]                    = {0x84,0x10,0xF1,0x18,0x00,0x00,0x00,0x9D};
flash unsigned char clearDiagnosticInformation[]         = {0x83,0x10,0xf1,0x14,0x00,0x00,0x98};  

// для истории
// flash unsigned char startDiagnosticSession[]            = {0x83,0x10,0xF1,0x10,0x81,0x0A,0x1F};
// flash unsigned char stopCommunication[]                 = {0x81,0x10,0xf1,0x82,0x04};
// flash unsigned char stopDiagnosticSession[]             = {0x81,0x10,0xf1,0x20,0xA2};
// flash unsigned char testerPresent[]                     = {0x82,0x10,0xf1,0x3E,0x01,0xC2};
// flash unsigned char readDataByLocalIdentifier_RLI_FT[]  = {0x82,0x10,0xF1,0x21,0x03,0xA7};

volatile bit             StartSend, first_draw, go, zamer_finish;
volatile unsigned char   counter;
volatile unsigned int    ms;
volatile unsigned int    dsec;
//unsigned char            Connect_Delay;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   buffer[counter] = data;
   if (++counter == BUFFER_SIZE) {
     counter = 0;
     }
   }
}

void SendCommand (flash unsigned char *command, unsigned char length) {
  counter = 0; 
  while (length--) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
  // Reinitialize Timer 0 value
  TCNT0=0x06;
  if (++ms > 250) {
    ms = 0;
    StartSend = 1;       // разрешаем отправку запроса через каждые 250 мс
  }
}

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer1 value
TCNT1H=0xE796 >> 8;           // таймер срабатывает каждые 0,1 сек
TCNT1L=0xE796 & 0xff;

if (++dsec > 300) {           // даем на разгон 30 сек
  TCCR1B=0x00;
  go = 0;
  zamer_finish = 1;
  }
}



void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=Out Bit6=In Bit5=Out Bit4=Out Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(1<<DDB7) | (0<<DDB6) | (1<<DDB5) | (1<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=0 Bit6=T Bit5=0 Bit4=0 Bit3=T Bit2=T Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 1 ms
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0x83;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 31,250 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1 s
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x85;
TCNT1L=0xEE;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (1<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
MCUCSR=(0<<ISC2);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 10400
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x2F;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
SFIOR=(0<<ACME);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 2*2000,000 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
SPSR=(1<<SPI2X);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 7
// RD - PORTC Bit 1
// EN - PORTC Bit 6
// D4 - PORTC Bit 2
// D5 - PORTC Bit 3
// D6 - PORTB Bit 4
// D7 - PORTC Bit 5
// Characters/line: 16
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
      { if (PIND.3 == 0) {                              // если нажали кнопку выбора режима
          delay_ms(15);
          if (PIND.3 == 0) {
            mode++;                                     // меняем режим
            if(mode>4){                                 
              mode=2;
            }
            TCCR1B=0x00;
            dsec = 0;                                   // сбрасываем замер времени 
            go = 0;
            zamer_finish = 0;
            first_draw = 1;                             // перерисовываем экран при первом заходе в режим
          }
        } 
      }
      
      if (PIND.4 == 0) {                              // если нажали кнопку сброса
          delay_ms(15);
          if (PIND.4 == 0) {
            if (mode == ReadError) {
              SendCommand(clearDiagnosticInformation,7);   // стираем ошибки
              delay_ms(500);                               // даём ЭБУ время на стирание ошибок
			  first_draw = 1;                              // перерисовываем экран
            }
            else if (mode == SpeedSample) {
              TCCR1B=0x00;
              dsec = 0;                                    // сбрасываем замер времени 
              go = 0;
              zamer_finish = 0;
			  first_draw = 1;                              // перерисовываем экран
            }
          }
        }
        
        
        switch (mode) {                                  // смотрим какой режим
          case Connect:                                  // если только что включились => подключаемся к ЭБУ
            if (StartSend == 1) { 
              lcd_clear();                               // очистка дисплея
              lcd_gotoxy(0,0);                           // 0 позиция, верхняя строка
              lcd_putsf("Conn");
              delay_ms(100);
              SendCommand(startCommunication,5);
              StartSend = 0;
              /*if (++Connect_Delay > 8) {                       // делаем 8 попыток подключиться                       
                put_string(28,60,"НЕТ СВЯЗИ С ЭБУ",0xAFE0,1);  // если нет ответа, то выводим соответствующее сообщение
                delay_ms(2000);                                // и через секунду пробуем подключиться вновь
                Connect_Delay = 0;
              } */
            }
            else {
              if (counter > 11) {                        // парсим  запрос + ответ 
                unsigned char i = 0;
                unsigned int crc = 0;
                for (i=5;i<11;i++) {                     // запрос + ответ = 12 байт
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
                if ( buffer[11] == i ) {                 // проверяем контрольную сумму
                  if ( buffer[8] == 0xC1 ) {             // положительный ответ startCommunication
                    //SendCommand(startDiagnosticSession,7);  // запрашиваем диагностику, ответ не проверяем (хотя надо бы...)
                    mode = ReadData;                     // переходим в режим чтения данных 
                    first_draw = 1;  
                  }                                         
                }
              counter = 0;                               // сбрасываем counter иначе опять попадем под условие if (counter > 11)    
              }
            }
            break;
            
          case ReadData:                                 // если режим чтения данных 
            if (first_draw == 1) {                       // если перешли в этот режим, то первый раз рисуем             
              lcd_clear();
             /* put_string(-3,0,"ТЕМПЕРАТУРА",text_tablo,1); 
              put_string(98,0,"ДРОССЕЛЬ",text_tablo,1);  
              put_string(12,33,"ОБОРОТЫ",text_tablo,1);
              put_string(102,33,"РЕГ. ХХ",text_tablo,1); 
              put_string(1,66,"НАПРЯЖЕНИЕ",text_tablo,1);
              put_string(106,66,"ВПРЫСК",text_tablo,1);
              put_string(2,99,"МАСС.РАСХ.",text_tablo,1);
              put_string(93,99,"ДАТЧИК О2",text_tablo,1); */
              
              first_draw = 0;
            };                                           
            if (StartSend == 1) {                      
              SendCommand(readDataByLocalIdentifier_RLI_ASS,6);
              StartSend = 0;
            }
            else  { 
              if (counter>48) {                          //  6 байт запрос + 43 байта ответ (4-й байт в ответе - число байтов в посылке)
               unsigned char i = 0;
                unsigned int crc = 0;
                //unsigned char drossel = 0;
                for (i=6;i<48;i++) {                    
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
                if ( buffer[48] == i ) {                 // проверяем контрольную сумму      
                  i = buffer[20] - 0x28;                 // вычисляем температуру двигателя
                  if (i & 0x80) {                        // если она ниже нуля
                    i = 256 - i;
                    sprintf(convert,"-%d°",i); 
                    if (strlen(convert) <= 3)  {         // стираем лишнее справа от параметра в случае если он стал одинарным или двойным          
                     
                      lcd_gotoxy(0,1);                   
                      lcd_puts(strcat(convert, " "));            // выводим надпись в указанных координатах 
                    }
                    else {
                      
                      lcd_gotoxy(0,1);                   
                      lcd_puts(convert);  
                    }                   
                  }
                  else {                                 // если выше нуля
                    sprintf(convert,"%d°",i);
                    if (strlen(convert) <= 3)  {
                      
                    lcd_gotoxy(0,1);                   
                      lcd_puts(strcat(convert, " "));  
                     // put_string(25,11,strcat(convert, " "),text_parametr,2);
                      //put_string(25,11,strcat(" ", convert),text_parametr,2);
                    }
                    else {
                     // put_string(25,11,convert,text_parametr,2);
                     lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
                    }
                  }
                          
          case ReadError:                                // если режим чтения ошибок 
            if (first_draw == 1) {
              //fill_screen(bgcolor);
			  
             // put_string(5,5,"КОЛИЧЕСТВО ОШИБОК:",text_tablo,1);
              //first_draw = 0; 
              lcd_gotoxy(0,0);                   
                      lcd_putsf("Errs");
              lcd_clear();
              
            }
            if (StartSend == 1) {                      
              SendCommand(readDTCByStatus,8);
              StartSend = 0;
            }
            else  {                                      // !!!!!!!!!!! ответ может быть произвольной длины !!!!!!!!!!!!!!
              if (counter>12) {                          // парсим  запрос + ответ 
			    unsigned char cislo_oshibok = 0; 
			    unsigned char otvet_length = 0; 
                cislo_oshibok = buffer[12];              // смотрим число ошибок   
			    otvet_length = 13+(3*cislo_oshibok);     // длинна ответа
                if (counter > otvet_length) {            // ждем пока примутся все ошибки
                  unsigned char i = 0;
			      unsigned int crc = 0;
			      for (i=8;i<otvet_length;i++) {               
                    crc = crc + buffer[i];
                  }
                  i =  crc & 0xFF;                       // берем 2 младших разряда 
			      if ( buffer[otvet_length] == i ) {     // проверяем контрольную сумму
			        sprintf(convert,"%d",cislo_oshibok);
				    //put_string(150,5,convert,text_parametr,1);
                    lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
                    if (cislo_oshibok != 0) {
				      for (i=0;i < cislo_oshibok;i++) {
				        sprintf(convert,"Р%02x%02x",buffer[(13+(i*3))],buffer[(14+(i*3))]);
                        if (i < 6) {
                         
                        //  put_string(5,25+(i*15),convert,0xAFE0,1);
                          lcd_gotoxy(0,1);                   
                         lcd_puts(convert);
                         
                        }
                        else if (i>=6 && i<12) {
                        //  put_string(65,25+((i-6)*15),convert,0xAFE0,1);
                        lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
                        } 
                        else if (i>=12 && i<18) {
                        //  put_string(125,25+((i-12)*15),convert,0xAFE0,1);
                        lcd_gotoxy(0,1);                   
                      lcd_puts(convert);  
                        }
				      }
                    }
                  }
                counter = 0;                             // сбрасываем counter иначе опять попадем под условие if (counter>12)				
                }		  
			  }
            }
            }
            }
            }
            }
            }
		//	break;
			
		  /*case SpeedSample:                              // если режим замера скорости 0-100 км/ч
            if (first_draw == 1) {
              fill_screen(bgcolor);
              put_string(15,5,"РАЗГОН 0-100 КМ/Ч",text_tablo,1);
              put_string(65,25,"0.0",0xAFE0,2);
              put_string(52,70,"СКОРОСТЬ",text_tablo,1); 
              first_draw = 0;
            }
            if (StartSend == 1) {                      
              SendCommand(readDataByLocalIdentifier_RLI_ASS,6);
              StartSend = 0;
            }
            else  {
              if (counter>48) {                          //  6 байт запрос + 43 байта ответ (4-й байт в ответе - число байтов в посылке)
			    unsigned char i = 0;
			    unsigned int crc = 0;
                unsigned char speed = 0;
			    for (i=6;i<48;i++) {                    
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
			    if ( buffer[48] == i ) {                 // проверяем контрольную сумму 
                  speed = buffer[29];
                  if (speed == 0)  {                     // если машина остановлена
                    go = 1;                              // разрешаем замер скорости
                  }
                  if (speed > 0 && go == 1) {             // начали разгоняться    
                    if (zamer_finish) {
                      TCCR1B=0x00;
                    }
                    else {
                      TCCR1B=0x04;                       // запустили отсчет времени  
                      if (speed >= 100) {                 // замер разгона до 40 км/ч
                        zamer_finish = 1;
                        TCCR1B=0x00;                          
                      }
                    }                    
                  }
				  sprintf(convert,"%.1f",((float) (dsec * 0.1)));  // выводим время
				  put_string(65,25,convert,0xAFE0,2);
                  sprintf(convert,"%d",speed);                     // показываем текущую скорость
				  if (strlen(convert) < 3)  {                
                      put_string(65,90,strcat(convert, " "),0xAFE0,2);
				  }
				  else {
				      put_string(65,90,convert,0xAFE0,2);
				  }  
                }
              }
            }
			break;
			
          default : break;			
		}     
      }
}
*/

 

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

у вас индикатор по описанию сидит на PORTC, однако все разряды порта настроены на вход. И почему-то D6 индикатора подключен к PORTB.
Где вы задаёте порты ввода/вывода к которым подключен индикатор?

Изменено пользователем dm37
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

2 часа назад, dm37 сказал:

у вас индикатор по описанию сидит на PORTC, однако все разряды порта настроены на вход. И почему-то D6 индикатора подключен к PORTB.
Где вы задаёте порты ввода/вывода к которым подключен индикатор?

Порты задавал в Project - Configure и в CodeWizardAVR

project_configure.jpg

Изменено пользователем Inmixxx Channel
Ссылка на комментарий
Поделиться на другие сайты

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Сделал для проверки дисплея отдельный проект - работает. Походу программка зависает в каком-то месте

Изменено пользователем Inmixxx Channel
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Немного поправил, но все равно на дисплее ничего( и com порт молчит

/*******************************************************
This program was created by the
CodeWizardAVR V3.12 Advanced
Automatic Program Generator
© Copyright 1998-2014 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : Lada ECU Monitor
Version : 1.02
Date    : 09.03.2017
Author  : mr_smit , inmixxx
Company : 
Comments: 


Chip type               : ATmega32
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*******************************************************/

#include <mega32.h>
#include <alcd.h>                 // Alphanumeric LCD functions
#include <delay.h>
#include <string.h>
#include <stdio.h>                // Standard Input/Output functions

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

#define Connect      1
#define ReadData     2
#define ReadError    3
#define SpeedSample  4

int mode;

//#define HI(x) ((x)>>8)
//#define LO(x) ((x)& 0xFF)

//unsigned int svetlii_color = 0x1A12;   // цвет заднего фона (светлый)
//unsigned int temnii_color  = 0x218E;   // цвет заднего фона (темный)
//unsigned int text_parametr = 0xFFE0;   // цвет параметров
//unsigned int text_tablo    = 0xFFFF;   // цвет надписей

char convert[32];

#define BUFFER_SIZE 200
unsigned char buffer[BUFFER_SIZE];                       // приемный буффер

flash unsigned char startCommunication[]                 = {0x81,0x10,0xf1,0x81,0x03};
flash unsigned char readDataByLocalIdentifier_RLI_ASS[]  = {0x82,0x10,0xF1,0x21,0x01,0xA5};
flash unsigned char readDTCByStatus[]                    = {0x84,0x10,0xF1,0x18,0x00,0x00,0x00,0x9D};
flash unsigned char clearDiagnosticInformation[]         = {0x83,0x10,0xf1,0x14,0x00,0x00,0x98};  

// для истории
// flash unsigned char startDiagnosticSession[]            = {0x83,0x10,0xF1,0x10,0x81,0x0A,0x1F};
// flash unsigned char stopCommunication[]                 = {0x81,0x10,0xf1,0x82,0x04};
// flash unsigned char stopDiagnosticSession[]             = {0x81,0x10,0xf1,0x20,0xA2};
// flash unsigned char testerPresent[]                     = {0x82,0x10,0xf1,0x3E,0x01,0xC2};
// flash unsigned char readDataByLocalIdentifier_RLI_FT[]  = {0x82,0x10,0xF1,0x21,0x03,0xA7};

volatile bit             StartSend, first_draw, go, zamer_finish;
volatile unsigned char   counter;
volatile unsigned int    ms;
volatile unsigned int    dsec;
//unsigned char            Connect_Delay;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   buffer[counter] = data;
   if (++counter == BUFFER_SIZE) {
     counter = 0;
     }
   }
}

void SendCommand (flash unsigned char *command, unsigned char length) {
  counter = 0; 
  while (length--) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
  // Reinitialize Timer 0 value
  TCNT0=0x06;
  if (++ms > 250) {
    ms = 0;
    StartSend = 1;       // разрешаем отправку запроса через каждые 250 мс
  }
}

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer1 value
TCNT1H=0xE796 >> 8;           // таймер срабатывает каждые 0,1 сек
TCNT1L=0xE796 & 0xff;

if (++dsec > 300) {           // даем на разгон 30 сек
  TCCR1B=0x00;
  go = 0;
  zamer_finish = 1;
  }
}




void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// F:  Bit7=In      Bit6=In   Bit5=In      Bit4=In     Bit3=In     Bit2=In     Bit1=In    Bit0=In 
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T       Bit6=T        Bit5=T        Bit4=T       Bit3=T         Bit2=T        Bit1=T       Bit0=T 
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// F: Bit7=In     Bit6=In     Bit5=In     Bit4=In     Bit3=In     Bit2=In     Bit1=In     Bit0=In 
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=0       Bit6=0        Bit5=0        Bit4=0        Bit3=0        Bit2=0        Bit1=0      Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);


// Port C initialization
// F:  Bit7=Out     Bit6=Out   Bit5=Out    Bit4=Out    Bit3=Out    Bit2=Out    Bit1=Out    Bit0=Out 
DDRC=(1<<DDC7) | (1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit7=0       Bit6=0        Bit5=0        Bit4=0        Bit3=0        Bit2=0        Bit1=0      Bit0=T 
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);


// Port D initialization
// F: Bit7=In     Bit6=In     Bit5=In     Bit4=In     Bit3=In     Bit2=In     Bit1=In     Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T       Bit6=T        Bit5=T        Bit4=T       Bit3=T         Bit2=T        Bit1=T       Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);



// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 1 ms
//TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02) | (1<<CS01) | (1<<CS00);
//TCNT0=0x83;
//OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 31,250 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1 s
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x85;
TCNT1L=0xEE;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (1<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
MCUCSR=(0<<ISC2);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 10400
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x2F;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
SFIOR=(0<<ACME);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 7
// RD - PORTC Bit 1
// EN - PORTC Bit 6
// D4 - PORTC Bit 5
// D5 - PORTC Bit 4
// D6 - PORTC Bit 3
// D7 - PORTC Bit 2
// Characters/line: 16
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
     
             lcd_clear();
             lcd_gotoxy(0,0); 
              lcd_putsf("Test");
              
              
      { if (PIND.3 == 0) {                              // если нажали кнопку выбора режима
          delay_ms(15);
          if (PIND.3 == 0) {
            mode++;                                     // меняем режим
            if(mode>4){                                 
              mode=2;
            }
            TCCR1B=0x00;
            dsec = 0;                                   // сбрасываем замер времени 
            go = 0;
            zamer_finish = 0;
            first_draw = 1;                             // перерисовываем экран при первом заходе в режим
          }
        } 
      }
      
      if (PIND.4 == 0) {                              // если нажали кнопку сброса
          delay_ms(15);
          if (PIND.4 == 0) {
            if (mode == ReadError) {
              SendCommand(clearDiagnosticInformation,7);   // стираем ошибки
              delay_ms(500);                               // даём ЭБУ время на стирание ошибок
              first_draw = 1;                              // перерисовываем экран
            }
            else if (mode == SpeedSample) {
              TCCR1B=0x00;
              dsec = 0;                                    // сбрасываем замер времени 
              go = 0;
              zamer_finish = 0;
              first_draw = 1;                              // перерисовываем экран
            }
          }
        }
        
        
        switch (mode) {                                  // смотрим какой режим
          case Connect:                                  // если только что включились => подключаемся к ЭБУ
            if (StartSend == 1) { 
              lcd_clear();                               // очистка дисплея
              lcd_gotoxy(0,0);                           // 0 позиция, верхняя строка
              lcd_putsf("Conn");
              delay_ms(100);
              SendCommand(startCommunication,5);
              StartSend = 0;
              /*if (++Connect_Delay > 8) {                       // делаем 8 попыток подключиться                       
                put_string(28,60,"НЕТ СВЯЗИ С ЭБУ",0xAFE0,1);  // если нет ответа, то выводим соответствующее сообщение
                delay_ms(2000);                                // и через секунду пробуем подключиться вновь
                Connect_Delay = 0;
              } */
            }
            else {
              if (counter > 11) {                        // парсим  запрос + ответ 
                unsigned char i = 0;
                unsigned int crc = 0;
                for (i=5;i<11;i++) {                     // запрос + ответ = 12 байт
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
                if ( buffer[11] == i ) {                 // проверяем контрольную сумму
                  if ( buffer[8] == 0xC1 ) {             // положительный ответ startCommunication
                    //SendCommand(startDiagnosticSession,7);  // запрашиваем диагностику, ответ не проверяем (хотя надо бы...)
                    mode = ReadData;                     // переходим в режим чтения данных 
                    first_draw = 1;  
                  }                                         
                }
              counter = 0;                               // сбрасываем counter иначе опять попадем под условие if (counter > 11)    
              }
            }
            break;
            
          case ReadData:                                 // если режим чтения данных 
            if (first_draw == 1) {                       // если перешли в этот режим, то первый раз рисуем             
            lcd_init(16); 
             lcd_clear();
             
             /* put_string(-3,0,"ТЕМПЕРАТУРА",text_tablo,1); 
              put_string(98,0,"ДРОССЕЛЬ",text_tablo,1);  
              put_string(12,33,"ОБОРОТЫ",text_tablo,1);
              put_string(102,33,"РЕГ. ХХ",text_tablo,1); 
              put_string(1,66,"НАПРЯЖЕНИЕ",text_tablo,1);
              put_string(106,66,"ВПРЫСК",text_tablo,1);
              put_string(2,99,"МАСС.РАСХ.",text_tablo,1);
              put_string(93,99,"ДАТЧИК О2",text_tablo,1); */
              
              first_draw = 0;
            };                                           
            if (StartSend == 1) {                      
              SendCommand(readDataByLocalIdentifier_RLI_ASS,6);
              StartSend = 0;
            }
            else  { 
              if (counter>48) {                          //  6 байт запрос + 43 байта ответ (4-й байт в ответе - число байтов в посылке)
               unsigned char i = 0;
                unsigned int crc = 0;
                //unsigned char drossel = 0;
                for (i=6;i<48;i++) {                    
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
                if ( buffer[48] == i ) {                 // проверяем контрольную сумму      
                  i = buffer[20] - 0x28;                 // вычисляем температуру двигателя
                  if (i & 0x80) {                        // если она ниже нуля
                    i = 256 - i;
                    sprintf(convert,"-%d°",i); 
                    if (strlen(convert) <= 3)  {         // стираем лишнее справа от параметра в случае если он стал одинарным или двойным          
                     
                      lcd_gotoxy(0,1);                   
                      lcd_puts(strcat(convert, " "));            // выводим надпись в указанных координатах 
                    }
                    else {
                      
                      lcd_gotoxy(0,1);                   
                      lcd_puts(convert);  
                    }                   
                  }
                  else {                                 // если выше нуля
                    sprintf(convert,"%d°",i);
                    if (strlen(convert) <= 3)  {
                      
                    lcd_gotoxy(0,1);                   
                      lcd_puts(strcat(convert, " "));  
                     // put_string(25,11,strcat(convert, " "),text_parametr,2);
                      //put_string(25,11,strcat(" ", convert),text_parametr,2);
                    }
                    else {
                     // put_string(25,11,convert,text_parametr,2);
                     lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
                    }
                  }
                    }      
          case ReadError:                                // если режим чтения ошибок 
            if (first_draw == 1) {
              //fill_screen(bgcolor);
			  
             // put_string(5,5,"КОЛИЧЕСТВО ОШИБОК:",text_tablo,1);
              //first_draw = 0; 
              lcd_gotoxy(0,0);                   
                      lcd_putsf("Errs");
              lcd_clear();
              
            }
            if (StartSend == 1) {                      
              SendCommand(readDTCByStatus,8);
              StartSend = 0;
            }
            else  {                                      // !!!!!!!!!!! ответ может быть произвольной длины !!!!!!!!!!!!!!
              if (counter>12) {                          // парсим  запрос + ответ 
			    unsigned char cislo_oshibok = 0; 
			    unsigned char otvet_length = 0; 
                cislo_oshibok = buffer[12];              // смотрим число ошибок   
			    otvet_length = 13+(3*cislo_oshibok);     // длинна ответа
                if (counter > otvet_length) {            // ждем пока примутся все ошибки
                  unsigned char i = 0;
			      unsigned int crc = 0;
			      for (i=8;i<otvet_length;i++) {               
                    crc = crc + buffer[i];
                  }
                  i =  crc & 0xFF;                       // берем 2 младших разряда 
			      if ( buffer[otvet_length] == i ) {     // проверяем контрольную сумму
			        sprintf(convert,"%d",cislo_oshibok);
				    //put_string(150,5,convert,text_parametr,1);
                    lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
                    if (cislo_oshibok != 0) {
				      for (i=0;i < cislo_oshibok;i++) {
				        sprintf(convert,"Р%02x%02x",buffer[(13+(i*3))],buffer[(14+(i*3))]);
                        if (i < 6) {
                         
                        //  put_string(5,25+(i*15),convert,0xAFE0,1);
                          lcd_gotoxy(0,1);                   
                         lcd_puts(convert);
                         
                        }
                        else if (i>=6 && i<12) {
                        //  put_string(65,25+((i-6)*15),convert,0xAFE0,1);
                        lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
                        } 
                        else if (i>=12 && i<18) {
                        //  put_string(125,25+((i-12)*15),convert,0xAFE0,1);
                        lcd_gotoxy(0,1);                   
                      lcd_puts(convert);  
                        }
				      }
                    }
                  }
                counter = 0;                             // сбрасываем counter иначе опять попадем под условие if (counter>12)				
                }		  
			  }
            }
			break;
		}
           }
         
      }
}
		 /* case SpeedSample:                              // если режим замера скорости 0-100 км/ч
            if (first_draw == 1) {
              fill_screen(bgcolor);
              put_string(15,5,"РАЗГОН 0-100 КМ/Ч",text_tablo,1);
              put_string(65,25,"0.0",0xAFE0,2);
              put_string(52,70,"СКОРОСТЬ",text_tablo,1); 
              first_draw = 0;
            }
            if (StartSend == 1) {                      
              SendCommand(readDataByLocalIdentifier_RLI_ASS,6);
              StartSend = 0;
            }
            else  {
              if (counter>48) {                          //  6 байт запрос + 43 байта ответ (4-й байт в ответе - число байтов в посылке)
			    unsigned char i = 0;
			    unsigned int crc = 0;
                unsigned char speed = 0;
			    for (i=6;i<48;i++) {                    
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
			    if ( buffer[48] == i ) {                 // проверяем контрольную сумму 
                  speed = buffer[29];
                  if (speed == 0)  {                     // если машина остановлена
                    go = 1;                              // разрешаем замер скорости
                  }
                  if (speed > 0 && go == 1) {             // начали разгоняться    
                    if (zamer_finish) {
                      TCCR1B=0x00;
                    }
                    else {
                      TCCR1B=0x04;                       // запустили отсчет времени  
                      if (speed >= 100) {                 // замер разгона до 40 км/ч
                        zamer_finish = 1;
                        TCCR1B=0x00;                          
                      }
                    }                    
                  }
				  sprintf(convert,"%.1f",((float) (dsec * 0.1)));  // выводим время
				  put_string(65,25,convert,0xAFE0,2);
                  sprintf(convert,"%d",speed);                     // показываем текущую скорость
				  if (strlen(convert) < 3)  {                
                      put_string(65,90,strcat(convert, " "),0xAFE0,2);
				  }
				  else {
				      put_string(65,90,convert,0xAFE0,2);
				  }  
                }
              }
            }
			break; 
			
          default : break;*/			
		     

 

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

Остаётся всё комментировать и понемногу добавлять код и смотреть, где затык.
Использовать большие задержки delay_ms это плохо, необходимо использовать аппаратный таймер и флаги. Надо стремиться к тому, чтобы цикл while(1) выполнялся как можно быстрее.

Думаю, надо пересмотреть структуру программы.
Вот ссылка на мой шаблон программы с LCD и кнопками (avr_menu1), посмотрите как построена программа (компилятор iar).
https://ru.files.fm/u/a2sfccuf#/list/
 

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

смущает этот код:

lcd_gotoxy(0,0);                   
lcd_putsf("Errs");
lcd_clear();	// очистка после вывода

и если можно отформатируйте код

При отсутствии связи должна высвечиваться ошибка "НЕТ СВЯЗИ С ЭБУ" (у вас пока закомментировано). Я бы попытался добиться вывода этого сообщения на экран, потом продолжил бы заниматься связью с ЭБУ

Изменено пользователем dm37
Ссылка на комментарий
Поделиться на другие сайты

В 09.03.2017 в 21:18, dm37 сказал:

Остаётся всё комментировать и понемногу добавлять код и смотреть, где затык.
Использовать большие задержки delay_ms это плохо, необходимо использовать аппаратный таймер и флаги. Надо стремиться к тому, чтобы цикл while(1) выполнялся как можно быстрее.

Думаю, надо пересмотреть структуру программы.
Вот ссылка на мой шаблон программы с LCD и кнопками (avr_menu1), посмотрите как построена программа (компилятор iar).
https://ru.files.fm/u/a2sfccuf#/list/
 

По вашей подсказке, закомментировал и добавлял код. Оказалось дело было в таймерах. В итоге я поставил настройки таймеров от оригинального проекта(временно). Дисплей показывает, но только при нажатии кнопки и то кракозябры. Весь день просидел так и не нашел причину. Пробывал на железе и в проетусе запускать все то же самое. 

Код:

/*******************************************************
This program was created by the
CodeWizardAVR V3.12 Advanced
Automatic Program Generator
© Copyright 1998-2014 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : Lada ECU Monitor
Version : 1.02
Date    : 09.03.2017
Author  : mr_smit , inmixxx
Company : 
Comments: 


Chip type               : ATmega32
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*******************************************************/

#include <mega32.h>
#include <alcd.h>                 // Alphanumeric LCD functions
#include <delay.h>
#include <string.h>
#include <stdio.h>                // Standard Input/Output functions

#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif




#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

#define Connect      1
#define ReadData     2
#define ReadError    3
#define SpeedSample  4

int mode;

#define HI(x) ((x)>>8)
#define LO(x) ((x)& 0xFF)

char convert[32];

#define BUFFER_SIZE 200
unsigned char buffer[BUFFER_SIZE];                       // приемный буффер

flash unsigned char startCommunication[]                 = {0x81,0x10,0xf1,0x81,0x03};
flash unsigned char readDataByLocalIdentifier_RLI_ASS[]  = {0x82,0x10,0xF1,0x21,0x01,0xA5};
flash unsigned char readDTCByStatus[]                    = {0x84,0x10,0xF1,0x18,0x00,0x00,0x00,0x9D};
flash unsigned char clearDiagnosticInformation[]         = {0x83,0x10,0xf1,0x14,0x00,0x00,0x98};  

// для истории
// flash unsigned char startDiagnosticSession[]            = {0x83,0x10,0xF1,0x10,0x81,0x0A,0x1F};
// flash unsigned char stopCommunication[]                 = {0x81,0x10,0xf1,0x82,0x04};
// flash unsigned char stopDiagnosticSession[]             = {0x81,0x10,0xf1,0x20,0xA2};
// flash unsigned char testerPresent[]                     = {0x82,0x10,0xf1,0x3E,0x01,0xC2};
// flash unsigned char readDataByLocalIdentifier_RLI_FT[]  = {0x82,0x10,0xF1,0x21,0x03,0xA7};

volatile bit             StartSend, first_draw, go, zamer_finish;
volatile unsigned char   counter;
volatile unsigned int    ms;
volatile unsigned int    dsec;
unsigned char            Connect_Delay;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   buffer[counter] = data;
   if (++counter == BUFFER_SIZE) {
     counter = 0;
     }
   }
} 

void SendCommand (flash unsigned char *command, unsigned char length) {
  counter = 0; 
  while (length--) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
  // Reinitialize Timer 0 value
  TCNT0=0x06;
  if (++ms > 250) {
    ms = 0;
    StartSend = 1;       // разрешаем отправку запроса через каждые 250 мс
  }
}

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer1 value
TCNT1H=0xE796 >> 8;           // таймер срабатывает каждые 0,1 сек
TCNT1L=0xE796 & 0xff;

if (++dsec > 300) {           // даем на разгон 30 сек
  TCCR1B=0x00;
  go = 0;
  zamer_finish = 1;
  }
}




void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// F:  Bit7=In      Bit6=In   Bit5=In      Bit4=In     Bit3=In     Bit2=In     Bit1=In    Bit0=In 
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T       Bit6=T        Bit5=T        Bit4=T       Bit3=T         Bit2=T        Bit1=T       Bit0=T 
PORTA=(0<<PORTA7) | (1<<PORTA6) | (1<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// F: Bit7=In     Bit6=In     Bit5=In     Bit4=In     Bit3=In     Bit2=In     Bit1=In     Bit0=In 
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=0       Bit6=0        Bit5=0        Bit4=0        Bit3=0        Bit2=0        Bit1=0      Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);


// Port C initialization
// F:  Bit7=Out     Bit6=Out   Bit5=Out    Bit4=Out    Bit3=Out    Bit2=Out    Bit1=Out    Bit0=Out 
DDRC=(1<<DDC7) | (1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit7=0       Bit6=0        Bit5=0        Bit4=0        Bit3=0        Bit2=0        Bit1=0      Bit0=T 
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);


// Port D initialization
// F: Bit7=In     Bit6=In     Bit5=In     Bit4=In     Bit3=In     Bit2=In     Bit1=In     Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T       Bit6=T        Bit5=T        Bit4=T       Bit3=T         Bit2=T        Bit1=T       Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);



// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 250,000 kHz
TCCR0=0x03;
TCNT0=0x06;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0xE7;
TCNT1L=0x96;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (1<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
MCUCSR=(0<<ISC2);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 10400
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x2F;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
SFIOR=(0<<ACME);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 7
// RD - PORTC Bit 1
// EN - PORTC Bit 6
// D4 - PORTC Bit 5
// D5 - PORTC Bit 4
// D6 - PORTC Bit 3
// D7 - PORTC Bit 2
// Characters/line: 16
//StartSend =1;

// Global enable interrupts
#asm("sei")
lcd_init(16);
lcd_clear();
lcd_gotoxy(0,9);
lcd_putsf("Run");

while (1)
 {   
             //
            // lcd_gotoxy(0,9); 
            // lcd_putsf("Run");
             
              
      if (PINA.6 == 0) {                              // если нажали кнопку выбора режима
          delay_ms(15);
          if (PINA.6 == 0) {
             lcd_gotoxy(0,9); 
             lcd_putsf("mode++");
            mode++;                                     // меняем режим
            if(mode>4){                                 
              mode=2;
            }
            TCCR1B=0x00;
            dsec = 0;                                   // сбрасываем замер времени 
            go = 0;
            zamer_finish = 0;
           
            //first_draw = 1;                             // перерисовываем экран при первом заходе в режим
          }
        } 
      
      
      if (PINA.5 == 0) {                              // если нажали кнопку сброса
         delay_ms(15);
          if (PINA.5 == 0) {
            if (mode == ReadError) {
              SendCommand(clearDiagnosticInformation,7);   // стираем ошибки
              delay_ms(500);                               // даём ЭБУ время на стирание ошибок
             // first_draw = 1;
              lcd_gotoxy(0,9); 
             lcd_putsf("Rd.Err");                              // перерисовываем экран
            }
            else if (mode == SpeedSample) {
              lcd_gotoxy(0,9); 
             lcd_putsf("spdsamp");
              TCCR1B=0x00;
              dsec = 0;                                    // сбрасываем замер времени 
              go = 0;
              zamer_finish = 0;
             // first_draw = 1;                              // перерисовываем экран
            }
          }
        } 
     
        
        switch (mode) {                                  // смотрим какой режим
          case Connect:                                  // если только что включились => подключаемся к ЭБУ
            if (StartSend == 1) { 
                                            // очистка дисплея
              lcd_gotoxy(0,0);                           // 0 позиция, верхняя строка
              lcd_putsf("Conn");
              delay_ms(100);
              SendCommand(startCommunication,5);
              StartSend = 0;
                     if (++Connect_Delay > 8) {                       // делаем 8 попыток подключиться                       
                     lcd_clear();
                     lcd_gotoxy(0,0);
                     lcd_putsf("NO ECU");                            // если нет ответа, то выводим соответствующее сообщение
                     delay_ms(2000);                                // и через секунду пробуем подключиться вновь
                     Connect_Delay = 0; 
              }
            }
            else {
            lcd_gotoxy(0,9); 
             lcd_putsf("else.c");
              if (counter > 11) {
                                        // парсим  запрос + ответ 
                unsigned char i = 0;
                unsigned int crc = 0;
                for (i=5;i<11;i++) {                     // запрос + ответ = 12 байт
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда
                lcd_gotoxy(0,9); 
                lcd_putsf("c>11 "); 
                if ( buffer[11] == i ) {                 // проверяем контрольную сумму
                  if ( buffer[8] == 0xC1 ) {             // положительный ответ startCommunication
                    //SendCommand(startDiagnosticSession,7);  // запрашиваем диагностику, ответ не проверяем (хотя надо бы...)
                    mode = ReadData;                     // переходим в режим чтения данных 
                  //  first_draw = 1;  
                  }                                         
                }
              counter = 0;                               // сбрасываем counter иначе опять попадем под условие if (counter > 11)    
              }
            }  
            break;
            
          case ReadData:
           lcd_gotoxy(0,9); 
           lcd_putsf("Rd.Dat");                                  
            if (StartSend == 1) {
            lcd_gotoxy(0,9); 
             lcd_putsf("StartS");                      
              SendCommand(readDataByLocalIdentifier_RLI_ASS,6);
              StartSend = 0;
            }
            else { 
              if (counter>48) {                          //  6 байт запрос + 43 байта ответ (4-й байт в ответе - число байтов в посылке)
               unsigned char i = 0;
                unsigned int crc = 0;
                //unsigned char drossel = 0;
                for (i=6;i<48;i++) {                    
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
                if ( buffer[48] == i ) {                 // проверяем контрольную сумму      
                  i = buffer[20] - 0x28;                 // вычисляем температуру двигателя
                  if (i & 0x80) {                        // если она ниже нуля
                    i = 256 - i;
                    sprintf(convert,"-%d°",i); 
                    if (strlen(convert) <= 3)  {         // стираем лишнее справа от параметра в случае если он стал одинарным или двойным          
                     
                      lcd_gotoxy(0,1);                   
                      lcd_puts(strcat(convert, " "));            // выводим надпись в указанных координатах 
                    }
                    else {
                      
                      lcd_gotoxy(0,1);                   
                      lcd_puts(convert);  
                    }                   
                  }
                  else {                                 // если выше нуля
                    sprintf(convert,"%d°",i);
                    if (strlen(convert) <= 3)  {
                    lcd_gotoxy(0,1);                   
                      lcd_puts(strcat(convert, " ")); // put_string(25,11,strcat(convert, " "),text_parametr,2);  
                    }                                                                                          
                    else {
                     
                     lcd_gotoxy(0,1);                   
                     lcd_puts(convert);     // put_string(25,11,convert,text_parametr,2);
                      }
                      }
                    sprintf(convert,"%.3f",(float) 1.25*((float)buffer[32]/256));     // напряжение на датчике кислорода             
                     lcd_gotoxy(1,2);                   
                     lcd_puts(convert);     // put_string(99,110,convert,text_parametr,2);        
                }
			  counter = 0;                               // сбрасываем counter иначе опять попадем под условие if (counter > 47)
			  }
			}
			break;  
                
                
         case ReadError:                                // если режим чтения ошибок 
            if (StartSend == 1) {                      
              SendCommand(readDTCByStatus,8);
              StartSend = 0;
              first_draw = 0; 
              lcd_gotoxy(0,0);                   
              lcd_putsf("Errs");
              }
            else  {                                      // !!!!!!!!!!! ответ может быть произвольной длины !!!!!!!!!!!!!!
              if (counter>12) {                          // парсим  запрос + ответ 
			    unsigned char cislo_oshibok = 0; 
			    unsigned char otvet_length = 0; 
                cislo_oshibok = buffer[12];              // смотрим число ошибок   
			    otvet_length = 13+(3*cislo_oshibok);     // длинна ответа
                if (counter > otvet_length) {            // ждем пока примутся все ошибки
                  unsigned char i = 0;
			      unsigned int crc = 0;
			      for (i=8;i<otvet_length;i++) {               
                    crc = crc + buffer[i];
                  }
                  i =  crc & 0xFF;                       // берем 2 младших разряда 
			      if ( buffer[otvet_length] == i ) {     // проверяем контрольную сумму
			        sprintf(convert,"%d",cislo_oshibok);
				    //put_string(150,5,convert,text_parametr,1);
                    lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
                    if (cislo_oshibok != 0) {
				      for (i=0;i < cislo_oshibok;i++) {
				        sprintf(convert,"Р%02x%02x",buffer[(13+(i*3))],buffer[(14+(i*3))]);
                        if (i < 6) { 
                        //  put_string(5,25+(i*15),convert,0xAFE0,1);
                          lcd_gotoxy(0,1);                   
                         lcd_puts(convert);
                        }
                        else if (i>=6 && i<12) {
                        //  put_string(65,25+((i-6)*15),convert,0xAFE0,1);
                         lcd_gotoxy(0,1);                   
                         lcd_puts(convert);
                        } 
                        else if (i>=12 && i<18) {
                        //  put_string(125,25+((i-12)*15),convert,0xAFE0,1);
                         lcd_gotoxy(0,1);                   
                         lcd_puts(convert);  
                        }
				      }
                    }
                  }
                counter = 0;                             // сбрасываем counter иначе опять попадем под условие if (counter>12)				
                }
              } 
            }
			break;
		
           
         
      
         
		  case SpeedSample:                              // если режим замера скорости 0-100 км/ч
            
            if (StartSend == 1) {                      
              SendCommand(readDataByLocalIdentifier_RLI_ASS,6);
              StartSend = 0;
            }
            else  {
              if (counter>48) {                          //  6 байт запрос + 43 байта ответ (4-й байт в ответе - число байтов в посылке)
			    unsigned char i = 0;
			    unsigned int crc = 0;
                unsigned char speed = 0;
			    for (i=6;i<48;i++) {                    
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
			    if ( buffer[48] == i ) {                 // проверяем контрольную сумму 
                  speed = buffer[29];
                  if (speed == 0)  {                     // если машина остановлена
                    go = 1;                              // разрешаем замер скорости
                  }
                  if (speed > 0 && go == 1) {             // начали разгоняться    
                    if (zamer_finish) {
                      TCCR1B=0x00;
                    }
                    else {
                      TCCR1B=0x04;                       // запустили отсчет времени  
                      if (speed >= 100) {                 // замер разгона до 40 км/ч
                        zamer_finish = 1;
                        TCCR1B=0x00;                          
                      }
                    }                    
                  }
				  
                  sprintf(convert,"%.1f",((float) (dsec * 0.1)));  // выводим время
				   lcd_gotoxy(0,0);                   
                   lcd_puts(convert); 
                  sprintf(convert,"%d",speed);                     // показываем текущую скорость
				  if (strlen(convert) < 3)  {                
                      //put_string(65,90,strcat(convert, " "),0xAFE0,2);
                      lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
				  }
				  else {
				     // put_string(65,90,convert,0xAFE0,2);
                      lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
				  }  
                }
              }
            }
			break;  
			
          default : break;			
		     
                    

    }
 }
}  

 

123456789.DSN

Lada ECU monitor.hex

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

переменная mode после старта программы равна 0, вы считаете, что равна 1 и далее код

switch (mode) {                                  // смотрим какой режим
	case Connect:                                  // если только что включились => подключаемся к ЭБУ

вы пытаетесь угадать, меняя код, заработает или нет. Закомментируйте пока весь код и начните по порядку:
- добейтесь вывода на экран номера режима или его названия,
- нажимая кнопки выводите пока тестовые сообщения в каждом режиме (в каждом режиме разное сочетание кнопок и должны получить, то что хотели - тестовое сообщение, например, "m1 k0=0 k1=1", m-режим, k-кнопка). И мне не очень нравиться устранение дребезга контактов, возможны ложные срабатывания.
- потом занимайтесь связью.

Лучше всё же поменять структуру программы, вы взяли не очень хороший пример программы, хоть и рабочий

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

да, и ещё, тут уже где-то были сообщения по поводу CodeVisionAVR. Эта среда разработки не способствует пониманию работы микроконтроллера за счёт использования встроенных библиотек. По крайней мере для начинающих это зло. Выберите Atmel Studio или IAR.

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

12 минуты назад, snn_krs сказал:

Проверьте Фьюз JTAGEN. По умолчанию он включен и порт С используется для отладки

 

fusebit.jpg

10 часов назад, dm37 сказал:

переменная mode после старта программы равна 0, вы считаете, что равна 1 и далее код


switch (mode) {                                  // смотрим какой режим
	case Connect:                                  // если только что включились => подключаемся к ЭБУ

вы пытаетесь угадать, меняя код, заработает или нет. Закомментируйте пока весь код и начните по порядку:
- добейтесь вывода на экран номера режима или его названия,
- нажимая кнопки выводите пока тестовые сообщения в каждом режиме (в каждом режиме разное сочетание кнопок и должны получить, то что хотели - тестовое сообщение, например, "m1 k0=0 k1=1", m-режим, k-кнопка). И мне не очень нравиться устранение дребезга контактов, возможны ложные срабатывания.
- потом занимайтесь связью.

Лучше всё же поменять структуру программы, вы взяли не очень хороший пример программы, хоть и рабочий

Пока запустил, подает на порт нужные данные. Выводит 'Connect' раз 9 потом 'No ECU' 

Копаю дальше. Нужно сделать нормальный пункт меню, мне тоже не нравится это решение. Лёд тронулся.

/*******************************************************
This program was created by the
CodeWizardAVR V3.12 Advanced
Automatic Program Generator
© Copyright 1998-2014 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : Lada ECU Monitor
Version : 1.02
Date    : 09.03.2017
Author  : mr_smit , inmixxx
Company : 
Comments: 


Chip type               : ATmega32
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*******************************************************/

#include <mega32.h>
#include <alcd.h>                 // Alphanumeric LCD functions
#include <delay.h>
#include <string.h>
#include <stdio.h>                // Standard Input/Output functions

#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif




#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

#define Connect      1
#define ReadData     2
#define ReadError    3
#define SpeedSample  4

int mode;

#define HI(x) ((x)>>8)
#define LO(x) ((x)& 0xFF)

char convert[32];

#define BUFFER_SIZE 200
unsigned char buffer[BUFFER_SIZE];                       // приемный буффер

flash unsigned char startCommunication[]                 = {0x81,0x10,0xf1,0x81,0x03};
flash unsigned char readDataByLocalIdentifier_RLI_ASS[]  = {0x82,0x10,0xF1,0x21,0x01,0xA5};
flash unsigned char readDTCByStatus[]                    = {0x84,0x10,0xF1,0x18,0x00,0x00,0x00,0x9D};
flash unsigned char clearDiagnosticInformation[]         = {0x83,0x10,0xf1,0x14,0x00,0x00,0x98};  

// для истории
// flash unsigned char startDiagnosticSession[]            = {0x83,0x10,0xF1,0x10,0x81,0x0A,0x1F};
// flash unsigned char stopCommunication[]                 = {0x81,0x10,0xf1,0x82,0x04};
// flash unsigned char stopDiagnosticSession[]             = {0x81,0x10,0xf1,0x20,0xA2};
// flash unsigned char testerPresent[]                     = {0x82,0x10,0xf1,0x3E,0x01,0xC2};
// flash unsigned char readDataByLocalIdentifier_RLI_FT[]  = {0x82,0x10,0xF1,0x21,0x03,0xA7};

volatile bit             StartSend, first_draw, go, zamer_finish;
volatile unsigned char   counter;
volatile unsigned int    ms;
volatile unsigned int    dsec;
unsigned char            Connect_Delay;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   buffer[counter] = data;
   if (++counter == BUFFER_SIZE) {
     counter = 0;
     }
   }
} 

void SendCommand (flash unsigned char *command, unsigned char length) {
  counter = 0; 
  while (length--) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
  // Reinitialize Timer 0 value
  TCNT0=0x06;
  if (++ms > 250) {
    ms = 0;
    StartSend = 1;       // разрешаем отправку запроса через каждые 250 мс
  }
}

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer1 value
TCNT1H=0xE796 >> 8;           // таймер срабатывает каждые 0,1 сек
TCNT1L=0xE796 & 0xff;

if (++dsec > 300) {           // даем на разгон 30 сек
  TCCR1B=0x00;
  go = 0;
  zamer_finish = 1;
  }
}




void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization

DDRA=0b00000000;
PORTA=0b01100000;

DDRB=0b00000000; 
PORTB=0b00000000;

DDRC=0b11111111;
PORTC=0b00000000;

DDRD=0b00000000;
PORTD=0b00000000;


// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 250,000 kHz
TCCR0=0x03;
TCNT0=0x06;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Normal top=0xFFFF
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On

TCNT1H=0xE7;
TCNT1L=0x96;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0b00000101;


// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 10400
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x2F;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=0b10000000;
SFIOR=0;


StartSend =1;

// Global enable interrupts
#asm("sei")
lcd_init(16);
lcd_clear();
lcd_gotoxy(0,9);
lcd_putsf("Run");
mode=1;
while (1)
 {   
             //
            // lcd_gotoxy(0,9); 
            // lcd_putsf("Run");
             
              
      if (PINA.6 == 0) {                              // если нажали кнопку выбора режима
          delay_ms(15);
          if (PINA.6 == 0) {
             lcd_gotoxy(0,9); 
             lcd_putsf("mode++");
            mode++;                                     // меняем режим
            if(mode>4){                                 
              mode=2;
            }
            TCCR1B=0x00;
            dsec = 0;                                   // сбрасываем замер времени 
            go = 0;
            zamer_finish = 0;
           
            //first_draw = 1;                             // перерисовываем экран при первом заходе в режим
          }
        } 
      
      
      if (PINA.5 == 0) {                              // если нажали кнопку сброса
         delay_ms(15);
          if (PINA.5 == 0) {
            if (mode == ReadError) {
              SendCommand(clearDiagnosticInformation,7);   // стираем ошибки
              delay_ms(500);                               // даём ЭБУ время на стирание ошибок
             // first_draw = 1;
              lcd_gotoxy(0,9); 
             lcd_putsf("Rd.Err");                              // перерисовываем экран
            }
            else if (mode == SpeedSample) {
              lcd_gotoxy(0,9); 
             lcd_putsf("spdsamp");
              TCCR1B=0x00;
              dsec = 0;                                    // сбрасываем замер времени 
              go = 0;
              zamer_finish = 0;
             // first_draw = 1;                              // перерисовываем экран
            }
          }
        } 
     
        
        switch (mode) {                                  // смотрим какой режим
          case Connect:                                  // если только что включились => подключаемся к ЭБУ
            if (StartSend == 1) { 
              lcd_clear();                              // очистка дисплея
              lcd_gotoxy(0,0);                           // 0 позиция, верхняя строка
              lcd_putsf("Conn");
              delay_ms(100);
              SendCommand(startCommunication,5);
              StartSend = 0;
                     if (++Connect_Delay > 8) {                       // делаем 8 попыток подключиться                       
                     lcd_clear();
                     lcd_gotoxy(0,0);
                     lcd_putsf("NO ECU");                            // если нет ответа, то выводим соответствующее сообщение
                     delay_ms(2000);                                // и через секунду пробуем подключиться вновь
                     Connect_Delay = 0; 
              }
            }
            else {
              if (counter > 11) {
                     
                                        // парсим  запрос + ответ 
                unsigned char i = 0;
                unsigned int crc = 0;
                for (i=5;i<11;i++) {                     // запрос + ответ = 12 байт
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда
                   lcd_gotoxy(0,9); 
                   lcd_putsf("c>11 "); 
                if ( buffer[11] == i ) {                 // проверяем контрольную сумму
                  if ( buffer[8] == 0xC1 ) {             // положительный ответ startCommunication
                     lcd_gotoxy(0,0);
                     lcd_putsf("StComm");                            // если нет ответа, то выводим соответствующее сообщение
                     delay_ms(2000);
                    //SendCommand(startDiagnosticSession,7);  // запрашиваем диагностику, ответ не проверяем (хотя надо бы...)
                    mode = ReadData;                     // переходим в режим чтения данных 
                  //  first_draw = 1;  
                  }                                         
                }
              counter = 0;                               // сбрасываем counter иначе опять попадем под условие if (counter > 11)    
              }
            }  
            break;
            
          case ReadData:
           lcd_gotoxy(0,9); 
           lcd_putsf("Rd.Dat");                                  
            if (StartSend == 1) {
            lcd_gotoxy(0,9); 
             lcd_putsf("StartS");                      
              SendCommand(readDataByLocalIdentifier_RLI_ASS,6);
              StartSend = 0;
            }
            else { 
              if (counter>48) {                          //  6 байт запрос + 43 байта ответ (4-й байт в ответе - число байтов в посылке)
               unsigned char i = 0;
                unsigned int crc = 0;
                //unsigned char drossel = 0;
                for (i=6;i<48;i++) {                    
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
                if ( buffer[48] == i ) {                 // проверяем контрольную сумму      
                  i = buffer[20] - 0x28;                 // вычисляем температуру двигателя
                  if (i & 0x80) {                        // если она ниже нуля
                    i = 256 - i;
                    sprintf(convert,"-%d°",i); 
                    if (strlen(convert) <= 3)  {         // стираем лишнее справа от параметра в случае если он стал одинарным или двойным          
                     
                      lcd_gotoxy(0,1);                   
                      lcd_puts(strcat(convert, " "));            // выводим надпись в указанных координатах 
                    }
                    else {
                      
                      lcd_gotoxy(0,1);                   
                      lcd_puts(convert);  
                    }                   
                  }
                  else {                                 // если выше нуля
                    sprintf(convert,"%d°",i);
                    if (strlen(convert) <= 3)  {
                    lcd_gotoxy(0,1);                   
                      lcd_puts(strcat(convert, " ")); // put_string(25,11,strcat(convert, " "),text_parametr,2);  
                    }                                                                                          
                    else {
                     
                     lcd_gotoxy(0,1);                   
                     lcd_puts(convert);     // put_string(25,11,convert,text_parametr,2);
                      }
                      }
                    sprintf(convert,"%.3f",(float) 1.25*((float)buffer[32]/256));     // напряжение на датчике кислорода             
                     lcd_gotoxy(1,2);                   
                     lcd_puts(convert);     // put_string(99,110,convert,text_parametr,2);        
                }
			  counter = 0;                               // сбрасываем counter иначе опять попадем под условие if (counter > 47)
			  }
			}
			break;  
                
                
         case ReadError:                                // если режим чтения ошибок 
            if (StartSend == 1) {                      
              SendCommand(readDTCByStatus,8);
              StartSend = 0;
              first_draw = 0; 
              lcd_gotoxy(0,0);                   
              lcd_putsf("ErrsStat");
              }
            else  {                                      // !!!!!!!!!!! ответ может быть произвольной длины !!!!!!!!!!!!!!
              if (counter>12) {
                                                // парсим  запрос + ответ 
			    unsigned char cislo_oshibok = 0; 
			    unsigned char otvet_length = 0; 
                cislo_oshibok = buffer[12];              // смотрим число ошибок   
			    otvet_length = 13+(3*cislo_oshibok);     // длинна ответа
                if (counter > otvet_length) {            // ждем пока примутся все ошибки
                  unsigned char i = 0;
			      unsigned int crc = 0;
			      for (i=8;i<otvet_length;i++) {               
                    crc = crc + buffer[i];
                  }
                  i =  crc & 0xFF;                       // берем 2 младших разряда 
			      if ( buffer[otvet_length] == i ) {     // проверяем контрольную сумму
			        sprintf(convert,"%d",cislo_oshibok);
				    //put_string(150,5,convert,text_parametr,1);
                    lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
                    if (cislo_oshibok != 0) {
				      for (i=0;i < cislo_oshibok;i++) {
				        sprintf(convert,"Р%02x%02x",buffer[(13+(i*3))],buffer[(14+(i*3))]);
                        if (i < 6) { 
                        //  put_string(5,25+(i*15),convert,0xAFE0,1);
                          lcd_gotoxy(0,1);                   
                         lcd_puts(convert);
                        }
                        else if (i>=6 && i<12) {
                        //  put_string(65,25+((i-6)*15),convert,0xAFE0,1);
                         lcd_gotoxy(0,1);                   
                         lcd_puts(convert);
                        } 
                        else if (i>=12 && i<18) {
                        //  put_string(125,25+((i-12)*15),convert,0xAFE0,1);
                         lcd_gotoxy(0,1);                   
                         lcd_puts(convert);  
                        }
				      }
                    }
                  }
                counter = 0;                             // сбрасываем counter иначе опять попадем под условие if (counter>12)				
                }
              } 
            }
			break;
		
           
         
      
           /*
		  case SpeedSample:                              // если режим замера скорости 0-100 км/ч
            
            if (StartSend == 1) {                      
              SendCommand(readDataByLocalIdentifier_RLI_ASS,6);
         
            StartSend = 0;
            }
            else  {
              if (counter>48) {                          //  6 байт запрос + 43 байта ответ (4-й байт в ответе - число байтов в посылке)
			    unsigned char i = 0;
			    unsigned int crc = 0;
                unsigned char speed = 0;
			    for (i=6;i<48;i++) {                    
                  crc = crc + buffer[i];                 // считаем контрольную сумму
                }
                i =  crc & 0xFF;                         // берем 2 младших разряда 
			    if ( buffer[48] == i ) {                 // проверяем контрольную сумму 
                  speed = buffer[29];
                  if (speed == 0)  {                     // если машина остановлена
                    go = 1;                              // разрешаем замер скорости
                  }
                  if (speed > 0 && go == 1) {             // начали разгоняться    
                    if (zamer_finish) {
                      TCCR1B=0x00;
                    }
                    else {
                      TCCR1B=0x04;                       // запустили отсчет времени  
                      if (speed >= 100) {                 // замер разгона до 40 км/ч
                        zamer_finish = 1;
                        TCCR1B=0x00;                          
                      }
                    }                    
                  }
				  
                  sprintf(convert,"%.1f",((float) (dsec * 0.1)));  // выводим время
				   lcd_gotoxy(0,0);                   
                   lcd_puts(convert); 
                  sprintf(convert,"%d",speed);                     // показываем текущую скорость
				  if (strlen(convert) < 3)  {                
                      //put_string(65,90,strcat(convert, " "),0xAFE0,2);
                      lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
				  }
				  else {
				     // put_string(65,90,convert,0xAFE0,2);
                      lcd_gotoxy(0,1);                   
                      lcd_puts(convert);
				  }  
                }
              }
            }
            
			break; */ 
			
          default : break;			
		     
                    

    }
 }
}  

Данные пока что не принимает. Только отправляет. До 'StComm' не доходит

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

1 час назад, Inmixxx Channel сказал:

Нужно сделать нормальный пункт меню

у вас не получиться один к одному перенести проект на новый дисплей, т.к. на ваш дисплей выводится меньше информации. Отсюда напрашивается изменение всей структуры меню (да и программы тоже). Многие используют разработку MicroMenu (на данном форуме часто обсуждается, поищите), многие используют свои наработки. Я использую своё меню (ссылку давал выше).

1 час назад, Inmixxx Channel сказал:

Данные пока что не принимает. Только отправляет. До 'StComm' не доходит

у вас есть строчка
if (counter > 11)
т.е. сообщение 'StComm' выведется только после приёма 12 байт от ЭБУ,

в коде, который вы привели, передача по uart идёт без использования прерывания, а приём с использованием прерывания (странно). Может пока, для чернового запуска блока, приём тоже осуществлять без прерывания. Потом когда отладите код можно будет подумать над оптимизацией работы с uart (и приём и передачу сделать через прерывание, сейчас я понимаю для вас это сложно).

interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   buffer[counter] = data;			// этот код опасный, проверку counter проводите после записи в массив, а если здесь counter > BUFFER_SIZE?
   if (++counter == BUFFER_SIZE) {
     counter = 0;
     }
   }
} 

 

Изменено пользователем dm37
Ссылка на комментарий
Поделиться на другие сайты

12 часа назад, dm37 сказал:

Потом когда отладите код можно будет подумать над оптимизацией работы с uart (и приём и передачу сделать через прерывание, сейчас я понимаю для вас это сложно).

Да, пока сложновато

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...