⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 AVR ISO9141 OBDII Souce code
💻 C
📖 第 1 页 / 共 2 页
字号:
		{
			*(++iso_msg_pntr) = ascii2byte(serial_msg_pntr);
			serial_msg_pntr += 2;		
		}
	
		// send ISO message and save return code
		unsigned char return_code = 	iso_send_msg(iso_msg_buf, serial_msg_len+4);
	
		// skip receive in case of transmit error or RESPONSE disabled
		if( (return_code == ISO_RETURN_CODE_OK) && CHECKBIT(parameter_bits, RESPONSE) )
		{
			unsigned char time_count = 0;		

			do
			{
				/*
					Run this loop until we received a valid response frame, or response timed out,
					or the bus was idle for 100ms or an bus error occured.
				*/
			
				cnt = iso_recv_msg(iso_msg_buf);  // receive ISO respond

				/*
					timeout_multiplier is by default 25
					the iso_recv_msg() has a timeout of 4ms
					so the loop will run 100ms by default before timeout
				*/
				++time_count;	
				if(time_count >= timeout_multiplier)
					return ISO_RETURN_CODE_NO_DATA;
					
				/*
					Check for bus error. End the loop then.
				*/
				if( cnt == (ISO_RETURN_CODE_BUS_ERROR & 0x80) )  // check if we got an error code or just number of recv bytes
				{
					if(CHECKBIT(parameter_bits, PACKED))
					{
						serial_putc(0x80);  // lenght byte with error indicator set
						return ISO_RETURN_CODE_DATA;  // surpress any other output
					}
					else
						return cnt & 0x7F;  // return "receive message" error code
				}

				iso_msg_pntr = &iso_msg_buf[0];

			} while( auto_recv_addr != *(iso_msg_pntr+1) );	

			// check respond CS
			if( *(iso_msg_pntr+(cnt-1)) != iso_checksum(iso_msg_buf, cnt-1) )
			{
				if(CHECKBIT(parameter_bits, PACKED))
				{
					serial_putc(0x80);  // length byte with error indicator set
					return ISO_RETURN_CODE_DATA;  // surpress any other output
				}
				else
					return ISO_RETURN_CODE_DATA_ERROR;
			}

			// check for respond from correct addr in auto or man recv mode
			if( auto_recv_addr != *(iso_msg_pntr+1) )
			{
				if(CHECKBIT(parameter_bits, PACKED))
				{
					serial_putc(0x00);  // length byte
					return ISO_RETURN_CODE_DATA;  // surpress any other output
				}
				else
					return ISO_RETURN_CODE_NO_DATA;
			}
			
			if( !CHECKBIT(parameter_bits, HEADER) )
			{ // surpess CRC and header bytes output
				cnt -= 4; 
				iso_msg_pntr += 3;
			}

			if(CHECKBIT(parameter_bits, PACKED))
				serial_putc(cnt);  // length byte
			
			// output response data
			for(;cnt > 0; --cnt)
			{
				if(CHECKBIT(parameter_bits, PACKED))
					serial_putc(*iso_msg_pntr++);  // length byte
				else
				{
					serial_put_byte2ascii(*iso_msg_pntr++);
					serial_putc(' ');
				}
			}
			
			if(!CHECKBIT(parameter_bits, PACKED))
			{// formated output with CR and optional LF
				serial_putc('\r');
				if(CHECKBIT(parameter_bits, LINEFEED)) serial_putc('\n');
			}
			return ISO_RETURN_CODE_DATA;  // surpress any other output

		}  // end if ISO OK && RESPONSE
		else  // transmit error or show RESPONSE OFF, return error code
			return return_code;
		
	} // end if !AT
	
	// we should never reach this return
	return 0;
} // end serial_processing



/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: Send program ident string to terminal
** 
** 
** Parameters: none
** 
** 
** Returns: none
** 
** 
**--------------------------------------------------------------------------- 
*/ 
void ident(void)
{
	serial_puts_P(ident_txt);  // show code description
}


/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: Convert 2 byte ASCII hex to 1 byte decimal
** 
** 
** Parameters: Pointer to first ASCII char
** 
** 
** Returns: decimal value
** 
** 
**--------------------------------------------------------------------------- 
*/ 
static unsigned char ascii2byte(char *val)
{
	unsigned char temp = *val;
	
	if(temp > 0x60) temp -= 39;  // convert chars a-f
	temp -= 48;  // convert chars 0-9
	temp *= 16;
	
	temp += *(val+1);
	if(*(val+1) > 0x60) temp -= 39;  // convert chars a-f
	temp -= 48;  // convert chars 0-9	

	return temp;

}


/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: Send one byte via USART
** 
** Parameters: data byte
** 
** Returns: NULL
** 
**--------------------------------------------------------------------------- 
*/ 
void serial_putc(unsigned char data)
{
	// wait for USART to become available
		while ( (UCSRA & _BV(UDRE)) != _BV(UDRE));
		UDR = data; 									// send character
}; //end usart_putc


/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: Make 2 byte ASCII from one byte binary and send to terminal
** 
** Parameters: input byte
** 
** Returns: none
** 
**--------------------------------------------------------------------------- 
*/ 
void serial_put_byte2ascii(unsigned char val)
{
	unsigned char ascii1=val;
	serial_putc( ((ascii1>>4) < 10) ? (ascii1>>4) + 48 : (ascii1>>4) + 55 );  // upper nibble
	serial_putc( ((val&0x0f) < 10) ? (val&0x0f) + 48 : (val&0x0f) + 55 );  // lower nibble
}


/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: Print string in program memory to terminal
** 
** Parameters: Pointer to string
** 
** Returns: none
** 
**--------------------------------------------------------------------------- 
*/ 
void serial_puts_P(const char *s)
{
	while( pgm_read_byte(&*s)) serial_putc( pgm_read_byte(&*s++));// send string char by char
}


/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: Print command prompt to terminal
** 
** 
** Parameters: none
** 
** 
** Returns: none
** 
** 
**--------------------------------------------------------------------------- 
*/
void print_prompt(void)
{
	serial_puts_P(PSTR("\n\r>"));	// send new command prompt
}



/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: USART Receive Interrupt
** 
** Parameters: none
** 
** Returns: none
** 
**--------------------------------------------------------------------------- 
*/ 
SIGNAL(SIG_UART_RECV)
{
	signed char *hlp_pntr = &serial_msg_buf[sizeof(serial_msg_buf)-1];  // get end of serial buffer

	// check for buffer end, prevent buffer overflow
	if ( serial_msg_pntr > hlp_pntr )
	{
		serial_msg_pntr = &serial_msg_buf[sizeof(serial_msg_buf)-1];
	}
	
	unsigned char in_char = UDR;  // get received char

	if(CHECKBIT(parameter_bits,MON_RX) || CHECKBIT(parameter_bits,MON_TX))
	{
		CLEARBIT(parameter_bits,MON_RX);
		CLEARBIT(parameter_bits,MON_TX);
		print_prompt();  // command prompt to terminal
	}
	else
	{
		if( CHECKBIT(parameter_bits,ECHO) )  // return char when echo is on
			serial_putc(in_char);		

		// check for terminating char
		if(in_char == 0x0D)
		{
			*(serial_msg_pntr) = 0x00;	// terminate received message
			switch ( serial_processing() )  // process serial message
			{
				case ISO_RETURN_CODE_OK:  // success
					serial_puts_P(PSTR("\n\rOK"));
					print_prompt();  // command prompt to terminal
					break;
				case ISO_RETURN_CODE_BUS_BUSY:  // bus was busy
					serial_puts_P(bus_busy_txt);
					print_prompt();  // command prompt to terminal
					break;
				case ISO_RETURN_CODE_BUS_ERROR:  // bus error detected
					serial_puts_P(bus_error_txt);
					print_prompt();  // command prompt to terminal
					break;
				case ISO_RETURN_CODE_DATA_ERROR:  // data error detected
					serial_puts_P(data_error_txt);
			    print_prompt();  // command prompt to terminal						
					break;
				case ISO_RETURN_CODE_NO_DATA:  // no data response (response timeout)
					serial_puts_P(no_data_txt);
			    print_prompt();  // command prompt to terminal	
					break;
				case ISO_RETURN_CODE_INIT_ERROR:  // bus init failed
					serial_puts_P(bus_init_txt);
			    print_prompt();  // command prompt to terminal	
					break;
				case ISO_RETURN_CODE_DATA:     // data response
          serial_puts_P(PSTR("\n\r?"));
					break;			
				default: // unknown error
					serial_puts_P(PSTR("\n\r?"));
			    print_prompt();  // command prompt to terminal	
			}
			serial_msg_pntr = &serial_msg_buf[0];  // start new message
		}
	
		// received char was no termination
		if(isalnum((int)in_char))
		{  // check for valid alphanumeric char and save in buffer
			*serial_msg_pntr = in_char;
			++serial_msg_pntr;	
		}
  }
};// end of UART receive interrupt

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -