CAN总线通信程序
//---------------------------------
//串行口初始化设置
//方式1,8数据位,一个停止位,无奇偶校验
//串口中断允许
//------------------------------------
void UART_ini(void)
{
SCON = 0x50;//方式1,波特率可变,8bits,接受允许
PCON&= 0x7F;//SMOD = 0
TMOD |= 0x20;//timer1 mode 2
TL1 = UART_BTR[2];//|f
//|波特率=----------------------
TH1 = UART_BTR[2];//|32*2^smod*12*(256-TL1)
TCON |= 0x40;//start
TI = 0;
}
//-----------------------------------------------
//
//看门狗“喂狗”程序,WDT的一个下降沿触发一次
//
//-----------------------------------------------
void W_WDT(void)//triggle WDT
{
unsigned char i;
WDT = 1;
for (i=0;i<10;i++)
{
}
WDT = 0;
}
//---------------------------------------------------
//
//中断初始化
//
//----外部中断0有效,下降沿触发,用于SJA1000产生CAN事件中断
//----定时器中断,用于判定串口接收的顺序两个字节是否分属两帧
//----串口中断,RX使用中断,TX未使用
//----中断优先级暂时未设定
//
//---------------------------------------------------
void Interrupt_init(void)
{
//IP = 0x00;
IT0 = 0x01; //外部0中断沿触发
ET0 = 1;//定时器0中断使能
EX0 = 1;//外部中断使能
ES = 1; //串行中断使能
}
//---------------------------------------------------
//
//定时中断程序
//
//一旦中断,说明一帧的接收已经结束,开始启动CAN发送程序
//把串口接收到的数据准备好给CAN总线发送
//RX_buffer ===> CAN_TX_buffer
//
//---------------------------------------------------
void Timer0_ISR(void) interrupt 1 using 2
{
static unsigned char i;
//unsigned char counter;
//TH0 = temp_TH0;
//TL0 = temp_TL0;
/*counter += 1;
if (counter == 20)//到1S了么?
{
//UART_flag = YES;
}
if (counter == 40)//到2S了么?
{
//CAN_flag = YES;
counter = 0;
}*/
//AAA = !AAA;
TR0 = 0;//定时器关,开始次CAN信息传送
for (i=0;iuart_datalength;i++)
{
CAN_TX_Data[i] = UART_RX_Data[i];
}
UART_Length = UART_DataLength;
UART_DataLength = 0;
CAN_flag = YES;
}
//---------------------------------------------------------------
//
//串口中断服务程序
//
//----只有接收使用
//----每收一个数重新初始化定时器
//
//----------------------------------------------------------------
void RX_INT(void) interrupt 4 using 3
{
static unsigned char n;
if (RI==1)
{
do
{
RI = 0;
}
while (RI != 0);
//UART_RX_Data[UART_DataLength++] = SBUF;
n = SBUF;
UART_Send_Byte(n);
TH0 = temp_TH0;
TL0 = temp_TL0;
TR0 = 1;//启动数据间隔定时,判断是否分属两帧
}
else
{
//TX
}
}
//---------------------------------------------------------------
//
//串口发送单字节程序
//
//----------------------------------------------------------------
void UART_Send_Byte(unsigned char Data)
{
SBUF = Data;
while (TI == 0)//等待发送完毕
{
}
TI = 0;
}
//---------------------------------------------------------------
//
//初始化定时器程序
//
//----定时器0方式1,定时器1方式2留给串口
//
//----------------------------------------------------------------
void Timer_init(void)
{
TMOD |= 0x01;//使用定时器0-方式1
TH0 = temp_TH0;
TL0 = temp_TL0;
//TR0 = 1;//这里不打开定时器
}
void CAN_init(void)
{
EA = 0;
MOD_CAN1 |= 0x08;//单滤波方式
do
{
MOD_CAN1 |= 0x01; //request to reset mode
}
while ((MOD_CAN1&0x01) != 0x01);
CDR_CAN1 = 0xc8;//选择PeliCAN模式,使用输入比较器,clk_out关闭
IER_CAN1 = 0x01;//允许发送中断,其他中断禁能
ACR0_CAN1 = ACR_ID[0];
ACR1_CAN1 = ACR_ID[1];
ACR2_CAN1 = ACR_ID[2];
ACR3_CAN1 = ACR_ID[3];
AMR0_CAN1 = AMR_ID[0];
AMR1_CAN1 = AMR_ID[1];
AMR2_CAN1 = AMR_ID[2];
AMR3_CAN1 = AMR_ID[3];
//ECC_CAN1 = 0;
//TXERR_CAN1 = 0;
//RBSA_CAN1 = 0;
BTR0_CAN1 = CAN_BTR0[0];
BTR1_CAN1 = CAN_BTR1[0];
OCR_CAN1 = 0xaa;//normal output
W_WDT();
do
{
MOD_CAN1 &= 0xfe;
}
while ((MOD_CAN1&0x01) != 0x00);
EA = 1;
}
//-----------------------------------
//
//串口发送一帧接受到的CAN数据
//
//----长度1-8,根据接收到的CAN信息来确定
//
//-----------------------------------
void UART_Transmit(void) //using 0
{
unsigned char i;
LED3 = !LED3;
for (i=0;i
UART_Send_Byte(CAN_RX_Data[i]);
}
}
//-----------------------------------
//
//CAN发送接受到的一帧串口数据
//
//----最大长度255,根据接收到的串口信息的
//个数来确定
//----按每依次8个数据作为一个CAN帧的报文部分
//不足8个或超过8的倍数的部分按实际个数作
//为CAN报文
//----F
CAN总线通信程 相关文章:
- 基于STM32的CAN总线通信程序(11-24)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)