📄 main.c
字号:
#include "stc89c51.h"
#include "main.h"
#include "SJA1000_Peli_REG.h"
#include <intrins.h>
unsigned char error;
unsigned char RX_Total_NUM;
unsigned char TX_Total_NUM;
unsigned char RX_Total_NUM_COM;
unsigned char TX_Total_NUM_COM;
void mcu_init(void);
void sja_init(void);
void main()
{
/*初始化*/
mcu_init();
sja_init();
while(1)
{
WDT_CONTR = 0X34 ; //喂狗
if ( uart_buf_num >= 8 )
//如果已接受了8个字节,则打包转发到CAN总线上
{
unsigned char pdata * ptr ;
unsigned char i ;
while ( ( Peli_SR & 0x04 ) == 0 ) ; //等待发送缓冲区释放
Peli_TXFMINFO = 0x08 ; //标准数据帧,数据字节数为1
Peli_TXBUF1 = 0x00 ; //标识符
Peli_TXBUF2 = 0x20 ;
ptr = &Peli_TXBUF3 ;
for ( i = 0 ; i<8 ; i++)
{
*ptr++ = UART_BUF[uart_s_ptr] ;
TX_Total_NUM ++ ;
// SBUF = UART_BUF[uart_s_ptr] ;
// while ( TI == 0 );
// TI = 0 ;
if ( ++uart_s_ptr == UART_BUF_NUM )
uart_s_ptr = 0 ;
}
uart_buf_num -= 8 ;
while ( ( Peli_SR & 0x30 ) != 0 ) ;
Peli_CMR |= 0x01 ; //启动发送
LED0= !LED0;
}
else if ( ( uart_r_time >= 20 ) && ( uart_buf_num >0 ) )
// 如果超过一定时间未继续接受到数据,则将已接受到的数据打包发到CAN总线上
{
unsigned char pdata * ptr ;
// unsigned char i ;
while ( ( Peli_SR & 0x04 ) == 0 ) ; //等待发送缓冲区释放
Peli_TXFMINFO = ( uart_buf_num & 0x0f ); //标准数据帧,数据字节数为uart_buf_num
Peli_TXBUF1 = 0x00 ; //标识符
Peli_TXBUF2 = 0x20 ;
ptr = &Peli_TXBUF3 ;
for ( ; uart_buf_num > 0 ; uart_buf_num-- )
{
*ptr++ = UART_BUF[uart_s_ptr] ;
TX_Total_NUM ++ ;
// SBUF = UART_BUF[uart_s_ptr] ;
// while ( TI == 0 );
// TI = 0 ;
if ( ++uart_s_ptr == UART_BUF_NUM )
uart_s_ptr = 0 ;
}
while ( ( Peli_SR & 0x30 ) != 0 ) ;
Peli_CMR |= 0x01 ; //启动发送
LED1= !LED1;
}
}
}
void mcu_init(void)
{
AUXR = 0X03 ; //禁止使用片内扩展的外部RAM,常态下禁止ALE输出,提高EMI
WDT_CONTR = 0X34 ; //启用看门狗
//IO口初始化
//定时器初始化
TMOD = 0X10 ; //定时器0、1分别工作于方式0、1
//串口初始化
SCON = 0X50 ; //串口工作于方式1,数据位8位,波特率可变,允许接受
TCLK = 1 ; //定时器2用作波特率发生器
RCLK = 1 ;
//晶振 22.1184 , 6T ,波特率9600
RCAP2H = 0xff ;
RCAP2L = 0X70 ;
//外部中断初始化
IT0 = 1; //INT0由下降沿触发,其中断标志IE0在响应中断之后由硬件自动清零
//中断初始化
ET0 = 1 ; //允许T0中断
EX0 = 1 ; //允许外部中断INT0中断
ES = 1 ; //允许串口中断
EA = 1 ;
TR0 = 1 ; //启动定时器
TR2 = 1 ;
}
/*
*/
void sja_init( void )
{
// unsigned char i;
// unsigned char pdata * ptr ;
EA = 0 ; //先禁止SJA1000中断
SJA_CS = 0 ; //选中SJA1000
SJA_RST = 0 ; //硬件复位SJA1000
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
SJA_RST = 1 ;
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
// 确保SJA进入复位模式
while ( ( Peli_MOD & RM_RR_BIT ) == 0 )
Peli_MOD = 0X01 ;
// 设置时钟分频寄存器 REG_CAN_CDR
Peli_CDR = CLKOff_BIT|CBP_BIT|CANMode_BIT ;
// 设置时序寄存器
Peli_BTR0 = 0XCA ;
Peli_BTR1 = 0X39 ;
// 设置输出控制寄存器
Peli_OCR = 0X1A ; // 正常输出模式 、推挽是输出方式, 0:低 1:悬空
// 设置中断寄存器
Peli_IER = 0X07 ; // 允许发送、接受、错误中断
// 设置验收屏蔽寄存器
Peli_AMR0 = 0XFF ;
Peli_AMR1 = 0XFF ;
Peli_AMR2 = 0XFF ;
Peli_AMR3 = 0XFF ;
// 设置验收代码寄存器
// 进入操作模式
Peli_MOD &= ~RM_RR_BIT ;
while ( ( Peli_MOD & RM_RR_BIT ) != 0 )
Peli_MOD &= ~RM_RR_BIT ;
EA = 1 ;
// LED0 = 0 ;
}
void time0_isr ( void ) interrupt 1
{
if ( uart_r_time <100 )
uart_r_time++ ;
}
void uart_isr ( void ) interrupt 4
{
// LED0 = !LED0 ;
if ( RI == 1 )
{
/* if ( SBUF == 1)
{
Peli_TXFMINFO = 0x01 ; //标准数据帧,数据字节数为1
Peli_TXBUF1 = 0x00 ; //标识符
Peli_TXBUF2 = 0x20 ;
Peli_TXBUF3 = 0x88 ; //数据
Peli_CMR |= 0x01 ; //启动发送
}
*/
RI = 0 ;
if ( SBUF == 0XFF)
{
ES = 0 ;
TI = 0 ;
SBUF = Peli_SR ;
while ( TI == 0 ) ;
TI = 0 ;
ES = 1 ;
return ;
}
if ( SBUF == 0XFE)
{
ES = 0 ;
TI = 0 ;
SBUF = TX_Total_NUM ;
while ( TI == 0 ) ;
TI = 0 ;
SBUF = RX_Total_NUM ;
while ( TI == 0 ) ;
TI = 0 ;
SBUF = RX_Total_NUM_COM ;
while ( TI == 0 ) ;
TI = 0 ;
SBUF = TX_Total_NUM_COM ;
while ( TI == 0 ) ;
TI = 0 ;
ES = 1 ;
return ;
}
if ( SBUF == 0XFD)
{
TX_Total_NUM = 0 ;
RX_Total_NUM = 0 ;
RX_Total_NUM_COM = 0 ;
TX_Total_NUM_COM = 0 ;
return ;
}
uart_r_time = 0 ; // 接收计时清零
if ( ++uart_buf_num > UART_BUF_NUM ) // 判断串口接受缓冲区是否溢出,溢出则不接收数据
return ;
UART_BUF[ uart_r_ptr ] = SBUF ;
RX_Total_NUM_COM++ ;
if( ++uart_r_ptr == UART_BUF_NUM ) // 接受指针是否需要归零
uart_r_ptr = 0 ;
LED3 = !LED3 ;
}
if ( TI == 1 )
{
TI = 0 ;
if ( can_buf_num > 0 ) //CAN缓冲区中是否有数据待发送到RS232上
{
SBUF = CAN_BUF[can_s_ptr] ;
if ( ++can_s_ptr == CAN_BUF_NUM )
can_s_ptr = 0 ;
can_buf_num-- ;
TX_Total_NUM_COM++ ;
send_going = 1;
}
else
send_going = 0;
}
}
void sja_isr ( void ) interrupt 0
{
Peli_IR_buf = Peli_IR ;
if ( ( Peli_IR_buf & TI_BIT ) != 0 ) //判断是否发送中断
{
// LED1 = ! LED1;
return ;
}
if ( ( Peli_IR_buf & RI_BIT ) != 0 ) //判断是否接受中断
{
/*
if ( (Peli_RXFMINFO == 0X01 ) && ( Peli_RXBUF1 == 0x00 ) && ( Peli_RXBUF2 == 0x20 ) && ( Peli_RXBUF3 == 0x88 ) )
*/
if ( ( Peli_RXFMINFO & 0xf0 ) == 0 ) //暂时只接受标准数据帧
{
unsigned char len ;
unsigned char pdata * ptr ;
len = Peli_RXFMINFO ;
ptr = &Peli_RXBUF3 ;
LED2 = !LED2 ;
while ( ( len > 0 ) && ( can_buf_num < CAN_BUF_NUM ) )
{
if ( send_going == 0 ) //如果前面没有正在往串口发送数据,则置位TI使得CAN数据能够转发到RS232上
TI = 1 ;//如果当前已经正在发送数据,置位TI反而可能引起错误
CAN_BUF[can_r_ptr] = *ptr++ ;
RX_Total_NUM ++ ;
if ( ++can_r_ptr == CAN_BUF_NUM )
can_r_ptr = 0 ;
can_buf_num ++ ;
len-- ;
}
}
Peli_CMR |= 0X04 ; //释放缓冲区
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -