http://avrobdii.googlecode.com/svn/trunk/code/J1850.c

/*
Copyright (C) Trampas Stern name of author This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ /*******************************************************************
* File: J1850.c
*
* Copyright ©, Trampas Stern. All Rights Reserved.
* Date: 5/19/2006 9:34:55 PM
*******************************************************************/
#include "scanner.h"
#include "time.h" #define PWM_UNKNOWN 0
#define PWM_BUS_ERROR 1
#define PWM_SOF 2
#define PWM_DATA 3
#define PWM_EOD 4
#define PWM_EOF 5
#define PWM_IDLE 6 #define PWM_BIT_US 24 //us for bit time
#define PWM_EOD_US 51 //us for End of Data time
#define PWM_EOF_US 72 //us for End of Frame time
#define PWM_IDLE_US 96 //us till idle #define TP1 8
#define TP2 16
#define TP3 24
#define TP4 48
#define TP5 72
#define TP7 32 #define PWM_OUT(x) {if (x) BIT_SET(PORTB,5); else BIT_CLEAR(PORTB,5);}
#define PWM_IN BIT_TEST(ACSR,5) #define J1850_ARRAY_N 16
#define J1850_ARRAY_PKTS 4 //must be power of 2
UINT8 J1850Data[ J1850_ARRAY_PKTS ][ J1850_ARRAY_N ];
UINT8 J1850DataBytes[ J1850_ARRAY_PKTS ];
UINT8 J1850DataTime[ J1850_ARRAY_PKTS ]; volatile UINT8 J1850_dataRead;
volatile UINT8 J1850_dataWrite; volatile UINT8 PWMState; volatile UINT8 *ptrWrite; volatile UINT8 NumPktBytes; /****************
Basic Operation
The J1850 comes in two flavors a PWM (pluse width modulation) and VPW
(variable pluse width modulation). For our initial system what we
are going to do is have the analog comparitor trigger on rising and
falling edges. Then we will have this trigger the timer/caputre (TC1).
This will tell allow us to measure the pulse widths.
*****************/ /******************************************************************
** J1850Init
*
* DESCRIPTION:
*
* Create: 5/19/2006 9:35:25 PM - Trampas Stern
*******************************************************************/
INT J1850Init( void )
{
//Set up data direction registers
BIT_SET( DDRB, ); //set OUT_VPW as output
BIT_SET( DDRB, ); //set OUT_PWM as output //ENABLE PWM
//BIT_SET(DDRC,2); //set pin as ouput
//BIT_CLEAR(PORTC,2); //drive pin low BIT_CLEAR( PORTB, ); //Turn off OUT_VPW
BIT_CLEAR( PORTB, ); //Turn off OUT_PWM //setup the analog comparator
ADCSRB = 0x00; //use negative input on compartor
ACSR = 0x08; //Output capture mode all disconnected
TCCR1A = 0x00; //noise canceler on (bit 7)
// prescaller clk/8==tick every half microSecond
TCCR1B = 0x82; //ignore the force output compare
TCCR1C = 0x00; //set count to zero
TCNT1 = 0x00; //The timer is reset on the rising edge of bits
//the EOD,EOF,and Idle time are based on end of last bit
// Thus we have to add bit time to each
//double due to timer runing twice as fast
OCR1A = ( PWM_EOD_US + PWM_BIT_US ) * ; //EOD time
OCR1B = ( PWM_EOF_US + PWM_BIT_US ) * ; //EOF time
OCR1C = ( PWM_IDLE_US + PWM_BIT_US ) * ; //IDLE time TIMSK1 = 0x0E; J1850_dataWrite = ;
J1850_dataRead = ;
NumPktBytes = ;
ptrWrite = J1850Data[ J1850_dataWrite ];
PWMState = PWM_UNKNOWN;
return NO_ERROR;
} ISR( TIMER1_COMPA_vect )
{
if ( BIT_TEST( ACSR, ) == ) //passive bus state
{
if ( PWMState < PWM_EOD )
{
PWMState = PWM_EOD;
if ( NumPktBytes > )
{
J1850DataBytes[ J1850_dataWrite ] = NumPktBytes;
J1850_dataWrite++;
J1850_dataWrite = J1850_dataWrite & ( J1850_ARRAY_PKTS - );
ptrWrite = J1850Data[ J1850_dataWrite ];
}
NumPktBytes = ;
}
}
else
{
PWMState = PWM_BUS_ERROR;
}
} ISR( TIMER1_COMPB_vect )
{
if ( BIT_TEST( ACSR, ) == ) //passive bus state
{
PWMState = PWM_EOF;
}
else
{
PWMState = PWM_BUS_ERROR;
}
} ISR( TIMER1_COMPC_vect )
{
if ( BIT_TEST( ACSR, ) == ) //passive bus state
{
PWMState = PWM_IDLE;
}
else
{
PWMState = PWM_BUS_ERROR;
}
// Note we do not want the timer to overflow so
// we reset it to some nominal amount.
//TCNT1=48*2+1;
} /******************************************************************
** Analog Comparator ISR
*
* DESCRIPTION:
*
* Create: 6/4/2006 9:21:43 AM - Trampas Stern
*******************************************************************/
ISR( ANALOG_COMP_vect )
{
static UINT8 data = ;
static UINT8 bits = ; UINT8 t; //read timer1
t = TCNT1L;
if ( BIT_TEST( ACSR, ) != )
{
//rising edge
TCNT1L = 0x00;
if ( PWMState > PWM_DATA )
{
J1850DataTime[ J1850_dataWrite ] = t;
} }
else //we have falling edge
{
//Falling edge
if ( t <= && t >= )
{
PWMState = PWM_DATA;
data = data << ;
if ( t <= )
data = data | 0x01;
bits++;
if ( bits > )
{
*ptrWrite = data;
NumPktBytes = NumPktBytes + ;
if ( NumPktBytes < J1850_ARRAY_N )
{
ptrWrite++;
//if (ptrWrite>(J1850Data + (4*16)))
//{
// ptrWrite--;
//}
}
bits = ;
}
}
if ( t >= && t <= )
{
PWMState = PWM_SOF;
bits = ;
}
} } /******************************************************************
** J1850test
*
* DESCRIPTION:
*
* Create: 6/4/2006 9:33:15 AM - Trampas Stern
*******************************************************************/
INT J1850test( void )
{
UBYTE i; if ( J1850_dataWrite != J1850_dataRead )
{
printf_P( PSTR( "\nPWMSTATE=%d\n" ), PWMState );
printf_P( PSTR( "J1850_DATA %d(us) " ),
J1850DataTime[ J1850_dataRead ] / );
for ( i = ; i < J1850DataBytes[ J1850_dataRead ]; i++ )
{
UINT8 d;
d = J1850Data[ J1850_dataRead ][ i ];
printf_P( PSTR( "%X " ), d );
}
J1850_dataRead++;
J1850_dataRead = J1850_dataRead & ( J1850_ARRAY_PKTS - ); } return NO_ERROR;
} /******************************************************************
** PWM_get
*
* DESCRIPTION: Gets a PWM packet
*
* Create: 6/11/2006 7:05:01 PM - Trampas Stern
*******************************************************************/
INT pwm_get( UINT8 *ptr, UINT8 count, UINT16 time_out_ms )
{
TIME ptrTime;
UINT8 i = ;
//get current time
GetTime( &ptrTime ); while ( !done )
{
if ( J1850_dataWrite != J1850_dataRead )
{
//printf_P(PSTR("\nPWMSTATE=%d\n",PWMState);
//printf_P(PSTR("J1850_DATA %d(us) ",J1850DataTime[J1850_dataRead]/2);
for ( i = ; i < J1850DataBytes[ J1850_dataRead ] && i < count; i++ )
{
//UINT8 d;
*ptr++ = J1850Data[ J1850_dataRead ][ i ];
//printf_P(PSTR("%X ",d);
}
J1850_dataRead++;
J1850_dataRead = J1850_dataRead & ( J1850_ARRAY_PKTS - ); } //check timne
if ( GetElaspMs( ptrTime ) > time_out_ms )
{
done = ;
}
} //while return i;
} /******************************************************************
** pwm_put
*
* DESCRIPTION:
*
* Create: 6/11/2006 7:10:50 PM - Trampas Stern
*******************************************************************/
INT pwm_put( UINT8 *data, UINT8 count, UINT16 time_out_ms )
{ TIME ptrTime;
UINT8 done = ;
UINT8 i = ;
INT8 bit;
UINT8 time;
//get current time
GetTime( &ptrTime ); while ( !done )
{
//first check that the PWM bus is idle
if ( PWMState >= PWM_IDLE )
{
//disable the receive ISRs
TIMSK1 = 0x00;
ACSR = 0x00; //Transmit SOF
TCNT1L = 0x00;
PWM_OUT( );
while ( TCNT1L < TP7 )
;
if ( PWM_IN != )
{
//enable reciever
ACSR = 0x08;
TIMSK1 = 0x0E;
return ;
}
while ( TCNT1L < ( TP7 * ) )
;
//drive low
PWM_OUT( );
while ( TCNT1L < ( TP4 * ) )
;
TCNT1L = 0x00;
PWM_OUT( ); //now lets drive the bits
for ( i = ; i < count; i++ )
{
UINT8 t;
t = *data++;
for ( bit = ; bit >= ; bit-- )
{
UINT8 b;
b = ( t >> bit ) & 0x01;
time = TP1;
if ( b == )
{
time = TP2;
}
while ( TCNT1L < ( time ) )
;
if ( PWM_IN != )
{
//drive low
PWM_OUT( );
//enable reciever
ACSR = 0x08;
TIMSK1 = 0x0E;
return ;
}
while ( TCNT1L < ( time * ) )
;
PWM_OUT( );
while ( TCNT1L < ( TP3 * ) )
;
TCNT1L = 0x00;
PWM_OUT( );
}
}
} //if PWMstate
//check time
if ( GetElaspMs( &ptrTime ) > time_out_ms )
{
done = ;
}
} //while(!done)
//drive low
PWM_OUT( );
//enable reciever
ACSR = 0x08;
TIMSK1 = 0x0E;
return i;
} //does CRC calculations
UINT8 crc( UINT8 *data, UINT8 len )
{
UINT8 result;
UINT8 i;
UINT8 mask;
UINT8 j;
UINT8 temp;
UINT8 poly; result = 0xFF;
for ( i = ; i < len; i++ )
{
mask = 0x80;
temp = data[ i ];
for ( j = ; j < ; j++ )
{
if ( temp & mask ) //bit is 1
{
poly = 0x1c;
if ( result & 0x80 )
{
poly = ;
}
result = ( ( result << ) | 0x01 ) ^ poly; }
else
{
poly = ;
if ( result & 0x80 )
{
poly = 0x1D;
}
result = ( ( result << ) ) ^ poly; }
mask = mask >> ;
}
}
return ~result;
}

J1850 Implement的更多相关文章

  1. SAE J1850 VPW Implement

    ---恢复内容开始--- OBDII Interface Project When I can ever find enough time away from schoolwork, I try to ...

  2. [LeetCode] Implement Queue using Stacks 用栈来实现队列

    Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...

  3. [LeetCode] Implement Stack using Queues 用队列来实现栈

    Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...

  4. [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  5. [LeetCode] Implement strStr() 实现strStr()函数

    Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...

  6. svn: E200007: Runner for 'org.tmatesoft.svn.core.wc2.SvnMerge' command have not been found; probably not yet implement in this API.

    myeclipse分支合并主干(分支->team->合并->选择主干)的时候出现这个错误: svn: E200007: Runner for 'org.tmatesoft.svn.c ...

  7. Leetcode Implement Queue using Stacks

    Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...

  8. The easy way to implement a Red-Black tree

    Red-Black trees are notorious for being nightmares of pointer manipulation. Instructors will show th ...

  9. How to implement a neural network

    神经网络的实践笔记 link: http://peterroelants.github.io/posts/neural_network_implementation_part01/ 1. 生成训练数据 ...

随机推荐

  1. Python程序员之面试必回习题

    写在前面 近日恰逢学生毕业季,课程后期大家“期待+苦逼”的时刻莫过于每天早上内容回顾和面试题问答部分[临近毕业每天课前用40-60分钟对之前内容回顾.提问和补充,专挑班里不爱说话就的同学回答]. 期待 ...

  2. 叉积(POJ - 2318 )

    题目链接:https://cn.vjudge.net/contest/276358#problem/A 题目大意:给你一个矩阵的左上角和右下角,然后n个竖杠,这n个竖杠将这个矩阵分成n+1个方块,给你 ...

  3. C - Balanced Number HDU - 3709 (数位dp)

    题目链接:https://cn.vjudge.net/contest/278036#problem/C 题目大意:手首先是T组数据,然后每一次输入两个数l,r,求这个区间里面满足以某个数字为中心的两侧 ...

  4. E - 食物链

    题目链接:https://cn.vjudge.net/contest/66964#problem/E 关系式: ra->rb=(ra->b + b->rb )%3; ra->b ...

  5. 【干货】linux系统信息收集 ----检测是否被恶意程序执行了危险性命令

    这些实战完全可以练习以下命令,已经找到需要观察的交互点,真实工作的时候,把数据都导入到自己U盘或者工作站内. 在kali 或者centos下训练都一样,关于kali教学,这里推荐掌控安全团队的课程:掌 ...

  6. http和socket之长连接和短连接区别【转】

    转自:https://blog.csdn.net/mengyafei43/article/details/25195445 TCP/IP TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层 ...

  7. Eureka的自我保护模式

    一 Eureka的自我保护模式 进入自我保护模式最直观的体现就是Eureka Server首页的警告,如下图: 默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,E ...

  8. python 双层函数调用顺序

    读大神代码,见到大神封装的接口很多都是采用双层函数形式. def 外层函数(外层参数) def 内层函数(内层参数) 函数体 return 值 return 内层函数 类似这样的形式,使用 外层函数( ...

  9. PHP isset()、empty()、is_null()的使用区别详解

    PHP的isset()函数 一般用来检测变量是否设置 格式:bool isset ( mixed var [, mixed var [, ...]] ) 功能:检测变量是否设置 返回值: 若变量不存在 ...

  10. .NetCore 分布式日志收集Exceptionless 在Windows下本地安装部署及应用实例

    自己安装时候遇到很多问题,接下来把这些问题写出来希望对大家有所帮助 搭建环境: 1.下载安装 java 8 SDK (不要安装最新的10.0) 并配置好环境变量(环境变量的配置就不做介绍了) 2.下载 ...