J1850-PWM
硬件说明:
MCU: GD32C103 120M,128K,32k RAM.
输入:USB 5V.
OBD功能口定义:OBD(2,10)VPWM、OBD 7(K线)、OBD 6(CAN H)、OBD 14(CAN L)、OBD 15(L线).
软件说明:
一、汽车CAN2.0(双线OBD 6、14)
1、支持波特率:1M、800K、500K、250K、125K、100K、62K、50K、33.3K、25K
二、汽车CAN FD(双线OBD 6、14)
1、仲裁区波特率:1M、500K
2、数据区波特率5M 4M 2M 1M
三、汽车KWP/LIN(OBD 7)总线数据采集说明
1、波特率:5、4800、9600、10416、57600、115200 BPS
三、SAE J1850(OBD 2、10)
1、PWM 协议发送接收
2、VPW 协议发送接收
第10章 J1850-PWM
- 电路图
2.例程说明
电平
• 5V
初始是低电平
PWM 是高低电平组合 成 BIT0 1,高位在前 低位在后
交互
• PWM协议支持的数据交互模式是双线双向半双工方式。
位格式
• 数据位: 8, 无数据起始位和结束位 ,无校验位。
逻辑
• PWM是OBD接头中的2和10号脚通信,下面我们以2号脚的电平信号为例来认识bit 1和bit 0 。
以2号脚位的电平信号为正逻辑,10号脚电平信号为负逻辑。
帧格式:SOF+DATA+EOF
SOF 常规为48us 高电平
EOF 72us 低电平
DATA 格式如下,以2号脚电平为例子
一个周期固定24us表示一个BIT
上升沿8us,下降沿=16us时BIT=1
上升沿16us,下降沿=8us时BIT=0
注:用OBD 一分2线接上开发板与CAN/K 采集器
3.软件设计
(1)main主要流程
//J1850PWM_Init();//PWM 初始化
//J1850_PWM_SendFrame(dat,sizeof(dat));//发送PWM 命令
J1850PWM_Init();//PWM 初始化
uint8_t dat[]={0x61,0x6A,0xF1,0x01,0x00,0x0a};
uint8_t dat1[]={0x41,0x6B,0x10,0x41,0x00,0x56,0xF9,0x0A,0x99,0xF9};
/* main loop */
while (1)
{
J1850_PWM_SendFrame(dat,sizeof(dat));
Delay_ms(500);
J1850_PWM_SendFrame(dat1,sizeof(dat1));
Delay_ms(500);
}
(2) vpwm.c 函数说明
1 PWM初始化J1850PWM_Init
void J1850PWM_Init(void)
{
// timer_oc_parameter_struct timer_ocinitpara;
// timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER3);rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_AF);
//gpio_pin_remap_config(GPIO_TIMER1_PARTIAL_REMAP0,ENABLE);//
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);gpio_init(GPIOB, GPIO_MODE_IPD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);//VPW 引脚设置成输入//gpio_bit_reset(GPIOB,GPIO_PIN_7);//0输出TIM1_CH0_Cap_Init();//输入
}
2 PWM数据转为电平周期DatToPWM
3 PWM 发送发送命令J1850_PWM_SendAndGet
u16 J1850_PWM_SendAndGet(VPWM_DATA vdat )
{
uint16_t iRet=0;
if( vdat->Num == 0 )
{
return 0;
}
vdat->Index = 0;
vdat->State=PWM_OUTPUT;
uint16_t Period = vdat->Period[vdat->Index]+0;
uint16_t CCR_Val = vdat->Duty[vdat->Index];
vdat->Index++;
timer_oc_parameter_struct timer_ocinitpara;
timer_parameter_struct timer_initpara;
timer_deinit(TIMER3);
/ initialize TIMER init parameter struct */
timer_struct_para_init(&timer_initpara);
/* initialize TIMER channel output parameter struct */
timer_channel_output_struct_para_init(&timer_ocinitpara);
/* CH0, CH1 and CH2 configuration in PWM mode */
timer_ocinitpara.outputstate = TIMER_CCX_ENABLE;//是否使能输出
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;//
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;//输出极性
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;//输出死区延时的极性
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;//空闲状态 输出极性
timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;//空闲状态 互补输出极性
timer_channel_output_config(TIMER3, TIMER_CH_0, &timer_ocinitpara);
/* TIMER1 configuration */
timer_initpara.period = Period;//周期
timer_initpara.prescaler = 120-1;//1us
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER3, &timer_initpara);/* CH2 configuration in PWM mode0, duty cycle 75% */
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_0, CCR_Val);//占空比 即高电平时间
timer_channel_output_mode_config(TIMER3, TIMER_CH_0, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER3, TIMER_CH_0, TIMER_OC_SHADOW_ENABLE);//必须 ENABLE/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER3);//必须接收关闭中断//timer_interrupt_disable(TIMER1,TIMER_INT_CH1|TIMER_INT_UP); //TIME1 接收中断关闭timer_disable(TIMER1);//开启/* auto-reload preload enable */
timer_enable(TIMER3);Delay_us(10);timer_flag_clear(TIMER3, TIMER_FLAG_CH0);//清标志while(vdat->State!=VPWM_IDLE)
{//if( TIM_GetFlagStatus(vpwm->TxPPin.Tim,vpwm->TxPPin.TimFlagCc) == RESET )if(RESET == timer_flag_get(TIMER3, TIMER_FLAG_CH0)) //TIMER_INT_FLAG_CH1 TIMER_FLAG_CH1{//TIM_IT_CC3continue;}Delay_us(1);timer_flag_clear(TIMER3, TIMER_FLAG_CH0);//清标志//TIM_ClearFlag(vpwm->TxPPin.Tim,vpwm->TxPPin.TimFlagCc);if( !PWM_Update(vdat) )//更新占空比{timer_disable(TIMER3);
// gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
// gpio_bit_reset(GPIOB,GPIO_PIN_7);
vdat->State = VPWM_IDLE;
}
}
//等待接收//必须接收关闭中断iJ1850EofFlag=0;iReCount=0;//iHBitSum=0;iLBitSum=0;//timer_interrupt_enable(TIMER1,TIMER_INT_CH1|TIMER_INT_UP);timer_enable(TIMER1);//开启GetTimer6Cnt();//timer_disable(TIMER1);//开启//timer_interrupt_disable(TIMER1,TIMER_INT_CH1|TIMER_INT_UP); //TIME1 接收中断关闭return iRet;
}
4.PC平台效果
EcuSimulator 工具设置J1850 PWM,显示数据如下图所示
源码地址
单片机源码
硬件地址