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

📄 main.c

📁 AVR ISO9141 OBDII Souce code
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
**  AVR ISO 9141/14230-2 Interface
**  by Michael Wolf
**
**  Released under GNU GENERAL PUBLIC LICENSE
**
**  contact: webmaster@mictronics.de
**  homepage: www.mictronics.de
**
**  Revision History
**
**  when         what  	who			why
**
**  Used develompent tools (download @ www.avrfreaks.net):
**  Programmers Notepad v2.0.5.32
**  WinAVR (GCC) 3.4.1
**  AvrStudio4 for simulating and debugging
**
**  [           Legend:          ]
**  [ + Added feature            ]
**  [ * Improved/changed feature ]
**  [ - Bug fixed (I hope)       ]
**
**	ToDo:
**
**************************************************************************/
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <avr/wdt.h>
#include "main.h"
#include "iso.h"

/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: Main routine
** 
** 
** Parameters: none
** 
** 
** Returns: NULL
** 
** 
**--------------------------------------------------------------------------- 
*/ 
int main(void)
{
	wdt_disable();	// make sure the watchdog is not running
	UBRRH = UART_BAUDRATE>>8;		// set baud rate
	UBRRL = UART_BAUDRATE;
	UCSRB =((1<<RXCIE)|(1<<RXEN)|(1<<TXEN));	// enable Rx & Tx, enable Rx interrupt
	UCSRC =((1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0));	// config USART; 8N1
	serial_msg_pntr = &serial_msg_buf[0];  // init serial msg pointer
  
  iso_glob.uart_n_baud = N_10400;  // set baud rate to 10,4kBaud	
	iso_hardware_init();  // init ISO hardware
	iso_uart_init();  // init ISO software UART
	
  ident();	// send identification to terminal
	serial_putc('>');  // send initial command prompt
  
  sei();  // enable interrupts

	for(;;)
	{
		while( CHECKBIT(parameter_bits, MON_RX) || CHECKBIT(parameter_bits, MON_TX) )
		{
			unsigned char iso_msg_buf[260];  // ISO message buffer
			unsigned char *iso_msg_pntr = &iso_msg_buf[0];  //  msg pointer
			unsigned int recv_nbytes;  // byte counter		
		  
			recv_nbytes = iso_recv_msg(iso_msg_buf);	// get ISO message

			if( !(recv_nbytes & 0x8000) ) // proceed only with no errors
			{
				iso_msg_pntr = &iso_msg_buf[0];
			
				// check for respond from correct addr or monitor all mode
				if( (CHECKBIT(parameter_bits, MON_RX) && CHECKBIT(parameter_bits, MON_TX))
				    || 
						((mon_receiver == *(iso_msg_pntr+1)) && CHECKBIT(parameter_bits, MON_RX) )
						||
						((mon_transmitter == *(iso_msg_pntr+2)) && CHECKBIT(parameter_bits, MON_TX) )
					)
				{
/*        
					if( !CHECKBIT(parameter_bits, HEADER) )
					{ // surpess CRC and header bytes output
						recv_nbytes -= 4; 
						iso_msg_pntr += 3;
					}

					if(CHECKBIT(parameter_bits, PACKED))
					{ // check respond CRC
						if( *(iso_msg_pntr+(recv_nbytes-1)) == iso_checksum(iso_msg_buf, recv_nbytes-1) )
							serial_putc(recv_nbytes);  // length byte 
						else
							serial_putc(recv_nbytes&0x8000);  // length byte with error indicator set
					}
*/			
					// output response data
					for(;recv_nbytes > 0; --recv_nbytes)
					{
						if(CHECKBIT(parameter_bits, PACKED))
							serial_putc(*iso_msg_pntr++);  // data 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');
					}					
					
				}  // end if valid monitoring addr
			} // end if message recv
		} // end while monitoring active
	}	// endless loop
	
	return 0;
}


/* 
**--------------------------------------------------------------------------- 
** 
** Abstract: Processing of received serial string
** 
** Parameters: none
** 
** Returns: 0 = unknown
**          1 = OK
**          2 = bus busy
**          3 = bus error
**          4 = data error
**          5 = no data
**          6 = data ( also to surpress any other output )
** 
**--------------------------------------------------------------------------- 
*/ 
char serial_processing(void)
{
	signed char *serial_msg_pntr = strlwr(serial_msg_buf);  // convert string to lower
	signed char serial_msg_len = strlen(serial_msg_buf);  // get string length
  signed char *var_pntr = 0;  // point to different variables

	if( (*(serial_msg_pntr)=='a') && (*(serial_msg_pntr+1)=='t'))  // check for "at" or hex
	{  // is AT command
		// AT command found
		switch( *(serial_msg_pntr+2) )  // switch on "at" command
		{
			case 'a':  // auto receive address on
				if(*(serial_msg_pntr+3) == 'r')	SETBIT(parameter_bits, AUTO_RECV);
				if( iso_req_header[0] & 0x80)  // check for functional or physical addr
					auto_recv_addr = iso_req_header[2]; // use physical recv addr
				else if( iso_req_header[0] & 0xC0)
					auto_recv_addr = iso_req_header[1]+1;  // use funct recv addr
				return 1;
		
			case 'd':  // set defaults
				parameter_bits = ECHO|LINEFEED|RESPONSE|AUTO_RECV;
				timeout_multiplier = 0x19;	// set default timeout to 4ms * 25 = 100ms
				iso_req_header[0] = 0xC1;  // functional addressing
				iso_req_header[1] = 0x33;  // tester addr
				iso_req_header[2] = 0xF1;  // target addr
  			return 1;
		
			case 'e':  // echo on/off
				if(*(serial_msg_pntr+3) == '1')
					SETBIT(parameter_bits, ECHO);
				else
					CLEARBIT(parameter_bits, ECHO);
				return 1;
			
			case 'i':  // send ident string
				ident();
				return 1;

			case 'l': // linefeed on/off (only for data strings)
				if(*(serial_msg_pntr+3) == '1')
					SETBIT(parameter_bits, LINEFEED);
				else
					CLEARBIT(parameter_bits, LINEFEED);
				return 1;			

			case 'h': // show headers on/off
				if(*(serial_msg_pntr+3) == '1')
					SETBIT(parameter_bits, HEADER);
				else
					CLEARBIT(parameter_bits, HEADER);
				return 1;

			case 'r': // show response on/off
				if(*(serial_msg_pntr+3) == '1')
					SETBIT(parameter_bits, RESPONSE);
				else
					CLEARBIT(parameter_bits, RESPONSE);
				return 1;

			case 'f': // send formated
				if(*(serial_msg_pntr+3) == 'd')
					CLEARBIT(parameter_bits, PACKED);
				return 1;

			case 'p': // send packed data
				if(*(serial_msg_pntr+3) == 'd')
					SETBIT(parameter_bits, PACKED);
				return 1;

			case 'm':  // switch into monitoring mode
				switch(*(serial_msg_pntr+3))
				{
					case 'a':
						SETBIT(parameter_bits, MON_RX);  // monitor all
						SETBIT(parameter_bits, MON_TX);
						return 6; // return, no following parameter
					
					case 'r':  // monitor only receiver addr
						SETBIT(parameter_bits, MON_RX);  // monitor receiver only
						CLEARBIT(parameter_bits, MON_TX);
						var_pntr = &mon_receiver;
						break;  // get following parameter					

					case 't':  // monitor only transmitter addr
						CLEARBIT(parameter_bits, MON_RX);
						SETBIT(parameter_bits, MON_TX);  // monitor transmitter only
						var_pntr = &mon_transmitter;
						break;  // get following parameter		
				}
				if(
						isxdigit(*(serial_msg_pntr+4)) && isxdigit(*(serial_msg_pntr+5)) 
						&&	( serial_msg_len == 6)
					)  // proceed when next two chars are hex
					{
					  // make 1 byte hex from 2 chars ASCII and save
						*var_pntr = ascii2byte(serial_msg_pntr+4);
						return 6;
					}

			case 's': // commands SH,SR or ST
				if(	isxdigit(*(serial_msg_pntr+4)) && isxdigit(*(serial_msg_pntr+5)) )
				{  // proceed when next two chars are hex
					switch(*(serial_msg_pntr+3))
					{
						case 'h':  // set header bytes
							if(
									isxdigit(*(serial_msg_pntr+6)) && isxdigit(*(serial_msg_pntr+7)) 
									&&	isxdigit(*(serial_msg_pntr+8)) && isxdigit(*(serial_msg_pntr+9)) 
									&&	( serial_msg_len == 10)
								)  // proceed when next four chars are hex
								{
								  // make 3 byte hex from 6 chars ASCII and save
									iso_req_header[0]=ascii2byte(serial_msg_pntr+4);
									iso_req_header[1]=ascii2byte(serial_msg_pntr+6);
									iso_req_header[2]=ascii2byte(serial_msg_pntr+8);
									if( CHECKBIT(parameter_bits, AUTO_RECV) )
									{
										if( iso_req_header[0] & 0x04)  // check for functional or physical addr
											auto_recv_addr = iso_req_header[2]; // use physical recv addr
										else
											auto_recv_addr = iso_req_header[1]+1;  // use funct recv addr
									}
									return 1;
								}
								break;
					
						case 't':  // set response timeout multipler
								var_pntr = &timeout_multiplier;
								break;
								
						case 'r':  // set receive address and manual receive mode
								var_pntr = &auto_recv_addr;
								CLEARBIT(parameter_bits, AUTO_RECV);
								break;
					} // end switch char 3
					if(serial_msg_len == 6) 
					{
						*var_pntr =ascii2byte(serial_msg_pntr+4);
						if (timeout_multiplier < 8)  timeout_multiplier = 8;  // set multiplier for minimum of 32ms timout
						return 1;
					}
				} // end if char 4 and 5 isxdigit
				return 0;

			case 'z':  // reset all and restart device
				wdt_enable(WDTO_15MS);	// enable watdog timeout 15ms
				for(;;);	// wait for watchdog reset
		
			default:  // return error, unknown command
				return 0;		
		}

	}
  else
	{  // is OBD hex command
		// no AT found, must be HEX code
		if( (serial_msg_len & 1) || (serial_msg_len > 16) )  // check for "even" message lenght
			return 0;                                           // and maximum of 8 data bytes

		serial_msg_len /= 2;  // use half the string lenght for byte count

		while( *serial_msg_pntr )  // check all chars are valid hex chars
		{
			if(!isxdigit(*serial_msg_pntr))
				return 0;
			++serial_msg_pntr;
		}
		serial_msg_pntr = &serial_msg_buf[0];  // reset pointer
	
	  unsigned char iso_msg_buf[260];  // ISO message to be send
		unsigned char *iso_msg_pntr = &iso_msg_buf[0];  //  msg pointer
		unsigned char cnt;  // byte counter

		// convert serial message from 2 byte ASCII to 1 byte binary and store
		for(cnt = 0; cnt < serial_msg_len; ++cnt)

⌨️ 快捷键说明

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