hi all:
I want to send lin break ,used MC9S12ZVL, my code:
//--------------------------------------------------------------------------------
//
//SCI0 Lin init 总线时钟 24MHZ 配置波特率:19200 KB/S
//-------------------------------------------------------------------------------
void init_SCI0(void)
{
SCI0SR2_AMAP = 0;//
SCI0ACR2_IREN = 0;//红外遥控解码 功能禁止
SCI0BD = 1250; // 波特率设置 24000000/1302 = 19201 =19.2K
//SCI0CR1 = 0x00; //SCI0 控制寄存器1配置
SCI0CR1_PT = 0; //奇偶校验位 0 偶校验, 1:奇校验 ,只有当PE =1,时有效
SCI0CR1_PE = 0; //奇偶校验使能位 0:禁止 1:使能
SCI0CR1_ILT = 0 ; //空闲线类型为 ,异步模式必须为0
SCI0CR1_WAKE = 0; //唤醒条件位,0:空闲线唤醒, 1:地址线唤醒
SCI0CR1_M = 0; //数据格式选择位 0:8位 1:9位
SCI0CR1_RSRC = 0; // SCI环路模式下的接收源选择位 ,只有当 LOOPS = 1,时才有效
SCI0CR1_SCISWAI = 0; //等待模式下的 停止位 0: 使能 1:禁止
SCI0CR1_LOOPS = 0; // 环路和正常模式选择位 0:正常模式
//-----------------------------------------------------------------
// SCI0CR2 = 0x2c; //SCI0 控制寄存器1配置
SCI0CR2_SBK = 0; //
SCI0CR2_RWU = 0; //
SCI0CR2_RE = 1; // 接收器接收使能位 1: 使能 0:禁止
SCI0CR2_TE = 1; // 发送器发送使能位 1: 使能 0:禁止
SCI0CR2_ILIE = 0; //
SCI0CR2_RIE = 1; //接收满中断使能
SCI0CR2_TCIE = 0; //
SCI0CR2_TIE = 0; // 发送完中断使能 ///ggg
LP0CR_LPE = 1; //LIN 处于普通收发模式
LP0CR_RXONLY = 0; //
RX_FLAGS.byte = 0; //接收标志复位
//---------------------------------------------------------
SCI0SR2_AMAP = 1;//
SCI0ACR1_BKDIE = 1;//2017 02 09 break interrupt enable
SCI0ACR2_BKDFE = 1;//break intrrupt LOGIC enable
SCI0SR2_RXPOL = 0;// edge active for falling
SCI0ACR1_RXEDGIE = 0; //
LP0CR_LPE = 1;//LIN physical init
LP0CR_LPWUE = 1;
}
//---------------------------------------------------------
//
//send break and 0x55
//--------------------------------------------------------
void send_break_hand(void)
{
SCI0SR2_BRK13 = 1; //13 BIT BREAK
SCI0CR2_SBK = 1; //START TO SEND
}
//-----------------------------------------------------------------------
//函数功能:system clock congfig 配置内晶振,使能PLL 得到 25Mhz总线频率
//入口参数:无
//出口参数:无
//----------------------------------------------------------------------
void init_OSC(void)
{
CPMUOSC_OSCE = 0; // 1:外晶体 使能 0:片内时钟
__asm (NOP);
__asm (NOP);
CPMUCLKS_PLLSEL =0; //不使能锁相环时钟,等配置好后再使能 rest =1
CPMUREFDIV_REFDIV0=0; //fREF = fIRCIM = 1M, 故 REFFRQ【1:0】 = 00
CPMUREFDIV_REFDIV1=0;
CPMUSYNR_SYNDIV0 = 1; // fvoc = 48M
CPMUSYNR_SYNDIV1 = 1; //由 fvoc = 2*fosc*(SYNDIV + 1) // SYNDIV = 23
CPMUSYNR_SYNDIV2 = 1; //
CPMUSYNR_SYNDIV3 = 0; //
CPMUSYNR_SYNDIV4 = 1; //
//CPMUSYNR_SYNDIV0 = 0; //0 = 0
// 48MHZ < fvco <= 64MHZ VCOFRQ[1:0] = 01
CPMUSYNR_VCOFRQ0 = 1;
CPMUSYNR_VCOFRQ1 = 0;
// CPMUIFLG_LOCK = 1; // if lock = 1
//fPLL = fvoc / (POSTDIV +1) //
//取 POSTDIV = 0 ===> fPLL = fvoc = 48Mhz
// fbusclock = fPLL/2 = 24MHZ
CPMUPOSTDIV_POSTDIV0 = 0;
CPMUPOSTDIV_POSTDIV1 = 0;
CPMUPOSTDIV_POSTDIV2 = 0;
CPMUPOSTDIV_POSTDIV3 = 0;
CPMUPOSTDIV_POSTDIV4 = 0;
__asm (NOP);
__asm (NOP);
while(CPMUIFLG_LOCK==0 ) //等待锁相环稳定
{
;
}
CPMUCLKS_PLLSEL = 1; //使能锁相环
ECLKCTL_NECLK = 0; //disable BUS CLOCK output on the ECLK PIN 0/1 ENABLI/DISABLE
//-----WATCHDOG ENABLE-----
CPMUCOP_CR2 = 1;
CPMUCOP_CR1 = 0;
CPMUCOP_CR0 = 0;
}
void main(void)
{
init_OSC( );
tim0ch0_init( );
init_SCI0( );
init_key( );
init_ad( );
init_pluse_io( );
init_moto( );
EnableInterrupts;
init_ram( );
send_break_hand( );
while(1)
{
}
}
but LIN BUS allways is hight ,why?
Solved! Go to Solution.
Hi Congmin,
I suppose, that your question is connected to the previous thread:
https://community.nxp.com/thread/451254
Correct?
We should toggle with SBK bit for transmitting break signal. For example:
SCI0CR2_SBK = 1; //START TO SEND
SCI0CR2_SBK = 0; //STOP SENDING BREAK
A break character contains all logic 0s and has no start, stop, or parity bit. As long as SBK is at logic 1, transmitter logic continuously loads break characters into the transmit shift register. After software clears the SBK bit, the shift register finishes transmitting the last break character and then transmits at least one logic 1. The automatic logic 1 at the end of a break character guarantees the recognition of the start bit of the next frame.
So, when we just set SBK bit without clearing SBK bit (as in the code in next thread), the SCI TX output will be kept in dominant level whole time. However, the LIN PHY has TxD-dominant timeout feature enabled by default. Therefore, the LIN transmitter will be shut down after a while and you will not see the dominant level at LIN pin.
Please check LPSR_LPDT flag.
There is the LIN stack:
http://www.nxp.com/assets/downloads/data/en/device-drivers/FSL_LIN_2.X_STACK.zip
The simple LIN example code for your inspiration (for the older S12G family) may be found here:
https://community.nxp.com/docs/DOC-93792
Other obvious and potential issues in your code:
SCI0SR2_AMAP = 0;//
SCI0ACR2_IREN = 0;//红外遥控解码 功能禁止
doesn’t make sense, since SCI0ACR2_IREN bit is available only when you switch into the alternative map (AMAP=1).
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Radek Sestak,
Think you very much for your reply.now i send for loop mode, OK:
void send_break_hand(void)
{
// SCI0SR1_TDRE = 1;
//SCI0DRL = 0x00;
// SCI1CR1_M = 0;
//SCI0CR2_TE = 1; // 发送器发送使能位 1: 使能 0:禁止
//SCI0SR1_TC = 1;
SCI0CR1_LOOPS = 1; // 环路和正常模式选择位 0:正常模式
SCI0CR1_RSRC = 1; // SCI环路模式下的接收源选择位 ,只有当 LOOPS = 1,时才有效
SCI0SR2_BRK13 = 1; //13 BIT BREAK
SCI0CR2_SBK = 1; //START TO SEND
delay(1);
SCI0CR2_SBK = 0; //START TO SEND
SCI0CR1_LOOPS = 0; // 环路和正常模式选择位 0:正常模式
SCI0CR1_RSRC = 0; // SCI环路模式下的接收源选择位 ,只有当 LOOPS = 1,时才有效
SCI0DRL = 0X55;
read_back = SCI0DRL;
while(SCI0SR1_TC==0)
{
;
}
}
Hi Congmin,
I am glad that it works now correctly.
Just note: You don’t need delay(1); code.
When you set SBK bit, the transmit buffer will be filled with zeros. When you clear SBK bit, the transmitter will finish current task anyway.
Instead of this, I would like to recommend rather test/wait loop for TDRE bit prior start of any transmitting. For example:
while(!SCI0SR1_TDRE); //wait for transmit data register empty flag
SCI0CR2_SBK = 1; //START SENDING BREAK
SCI0CR2_SBK = 0; //STOP SENDING BREAK
or
while(!SCI0SR1_TDRE); //wait for transmit data register empty flag
SCI0DRL = 0X55;
The TDRE bit signalize whether TX buffer is ready for new data.
When we will use TDRE bit instead TC bit, the SCI throughput may be slightly higher – The TX buffer may be loaded prior previous transfer finish.
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Congmin,
I suppose, that your question is connected to the previous thread:
https://community.nxp.com/thread/451254
Correct?
We should toggle with SBK bit for transmitting break signal. For example:
SCI0CR2_SBK = 1; //START TO SEND
SCI0CR2_SBK = 0; //STOP SENDING BREAK
A break character contains all logic 0s and has no start, stop, or parity bit. As long as SBK is at logic 1, transmitter logic continuously loads break characters into the transmit shift register. After software clears the SBK bit, the shift register finishes transmitting the last break character and then transmits at least one logic 1. The automatic logic 1 at the end of a break character guarantees the recognition of the start bit of the next frame.
So, when we just set SBK bit without clearing SBK bit (as in the code in next thread), the SCI TX output will be kept in dominant level whole time. However, the LIN PHY has TxD-dominant timeout feature enabled by default. Therefore, the LIN transmitter will be shut down after a while and you will not see the dominant level at LIN pin.
Please check LPSR_LPDT flag.
There is the LIN stack:
http://www.nxp.com/assets/downloads/data/en/device-drivers/FSL_LIN_2.X_STACK.zip
The simple LIN example code for your inspiration (for the older S12G family) may be found here:
https://community.nxp.com/docs/DOC-93792
Other obvious and potential issues in your code:
SCI0SR2_AMAP = 0;//
SCI0ACR2_IREN = 0;//红外遥控解码 功能禁止
doesn’t make sense, since SCI0ACR2_IREN bit is available only when you switch into the alternative map (AMAP=1).
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------