?? can.c
字號:
//------------------------------------------------------------
//
// CAN總線通信測試程序
//
// 主控制芯片 : AT89C52,12MHZ晶振
// CAN控制芯片 : SJA1000,16MHZ晶振
//
//------------------------------------------------------------
//------------------------------------------------------------
//頭文件
#include <reg52.h>
#include <absacc.h>
#include "CAN.h"
//------------------------------------------------------------
//常量定義
#define TIMER0_1S 50
#define T0_L 0xb0
#define T0_H 0x3c
#define YES 1
#define NOT 0
//------------------------------------------------------------
//變量定義
unsigned char Timer0_counter;
unsigned char CAN_TX_buffer[8] = {0x00,0xff,0x55,0xaa,0x00,0xff,0x55,0xaa};
unsigned char CAN_RX_buffer[10] = {0,0,0,0,0,0,0,0,0,0};
bit UART_transmit_flag;
bit CAN_ERROR_flag;
//------------------------------------------------------------
//函數預定義
void Interrupt_ini(void);
void CAN_ini(void);
void CAN_Transmit(void);
void Timer0_ini(void);
void UART_ini(void);
void UART_transmit(void) ;
void Delay(unsigned char m);
//------------------------------------------------------------
// 函數: 主函數
// 入口參數: 無
// 返回值 : 無
// 函數說明: 定時器控制,每1S中向CAN總線發送一個報文
// 接收到報文后,把接收到的數通過RS232串口
// 發送到計算機
//
//------------------------------------------------------------
void main(void)
{
Delay(100); //延時,等待系統穩定
UART_transmit_flag = NOT;
CAN_ERROR_flag = NOT;
EA = 0;
Timer0_ini();
UART_ini();
CAN_ini();
Interrupt_ini();
EA = 1;
for (;;)
{
if (Timer0_counter >= TIMER0_1S) //到達1S,啟動CAN發送
{
Timer0_counter = 0;
CAN_Transmit();
}
if (UART_transmit_flag == YES) //串口發送
{
UART_transmit_flag = NOT;
UART_transmit();
}
if (CAN_ERROR_flag == YES) //CAN總線錯誤或異常
{
CAN_ERROR_flag = NOT;
CAN_ini();
}
}
}
//------------------------------------------------------------
// 函數: 外部中斷0初始化函數
// 入口參數: 無
// 返回值 : 無
// 函數說明: 下降沿觸發,用于得到CAN總線中斷
//------------------------------------------------------------
void Interrupt_ini(void)
{
IT0 = 1;
EX0 = 1;
}
//------------------------------------------------------------
// 函數: CAN初始化函數
// 入口參數: 無
// 返回值 : 無
// 函數說明: 為了保證操作的準確性,需要在函數運行時禁止
// 中斷
//------------------------------------------------------------
void CAN_ini(void)
{
EA = 0; //關全局中斷
Delay(1);
do //進入復位請求
{
CONTROL_REG = 0x01;
}
while(!((CONTROL_REG&0x01) == 0x01));
CDR_REG = 0x08; //Basic CAN模式,使用輸入比較器,clk_out關閉
ACR_REG = 0x11;
AMR_REG = 0x00;
BTR0_REG = 0x01; //400kbps,sjw = 1,BTL cycle = 10,sam = 3
BTR0_REG = 0xa5;
OCR_REG = 0xaa; //normal output
CONTROL_REG |= 0x1a; //溢出,出錯,接收中斷使能
//退出復位狀態
do
{
CONTROL_REG &= ~0x01;
}
while((CONTROL_REG&0x01) == 0x01); //退出復位模式
EA = 1;
}
//------------------------------------------------------------
// 函數: CAN接收中斷函數
// 入口參數: 無
// 返回值 : 無
// 函數說明: 使用單片機的外部中斷0
//------------------------------------------------------------
void CAN_INT(void) interrupt 0 using 1
{
unsigned char interrupt_reg;
unsigned char can_status;
EA = 0;
interrupt_reg = INTERRUPT_REG;
if ((interrupt_reg&0x01) == 0x01) //接收中斷么?
{
do
{
can_status = STATUS_REG;
CAN_RX_buffer[0] = Rx_ID_0_REG;
CAN_RX_buffer[1] = Rx_ID_1_REG;
CAN_RX_buffer[2] = Rx_Data_1_REG;
CAN_RX_buffer[3] = Rx_Data_2_REG;
CAN_RX_buffer[4] = Rx_Data_3_REG;
CAN_RX_buffer[5] = Rx_ID_0_REG;
CAN_RX_buffer[6] = Rx_ID_1_REG;
CAN_RX_buffer[7] = Rx_Data_1_REG;
CAN_RX_buffer[8] = Rx_Data_2_REG;
CAN_RX_buffer[9] = Rx_Data_2_REG;
COMMAND_REG |= Release_Rx_buf; //釋放接收緩沖區
}
while ((can_status&0x01) == 0x01); //接收緩沖區不空則繼續接收
UART_transmit_flag = YES;
}
else
{
CAN_ERROR_flag = YES; //CAN總線出錯
}
EA = 1;
}
//------------------------------------------------------------
// 函數: CAN總線發送函數
// 入口參數: 無
// 返回值 : 無
// 函數說明: 發送一個CAN報文
//------------------------------------------------------------
void CAN_Transmit(void)
{
unsigned char can_status;
do
{
can_status = STATUS_REG;
}
while ((can_status&0x04) != 0x04); //發送緩沖區空么?
Tx_ID_0_REG = CAN_TX_buffer[0];
Tx_ID_1_REG = CAN_TX_buffer[1];
Tx_Data_1_REG = CAN_TX_buffer[0];
Tx_Data_2_REG = CAN_TX_buffer[1];
Tx_Data_3_REG = CAN_TX_buffer[2];
Tx_Data_4_REG = CAN_TX_buffer[3];
Tx_Data_5_REG = CAN_TX_buffer[4];
Tx_Data_6_REG = CAN_TX_buffer[5];
Tx_Data_7_REG = CAN_TX_buffer[6];
Tx_Data_8_REG = CAN_TX_buffer[7];
COMMAND_REG |= Tx_Request; //啟動發送請求
}
//------------------------------------------------------------
// 函數: 定時器0初始化
// 入口參數: 無
// 返回值 : 無
// 函數說明: 50mS定時中斷設置,定時器0,方式1
//------------------------------------------------------------
void Timer0_ini(void)
{
TMOD = 0x01;
TL0 = T0_L;
TH0 = T0_H;
ET0 = 1;
TCON = 0x10;
}
//------------------------------------------------------------
// 函數: 定時器0中斷服務函數
// 入口參數: 無
// 返回值 : 無
// 函數說明: 50ms中斷一次
//------------------------------------------------------------
void Timer0_INT(void) interrupt 1 using 1
{
Timer0_counter += 1;
TL0 = T0_L;
TH0 = T0_H;
}
//------------------------------------------------------------
// 函數: 串口初始化
// 入口參數: 無
// 返回值 : 無
// 函數說明: 波特率9600
//------------------------------------------------------------
void UART_ini(void)
{
SCON = 0x50; //方式1,8bits,接受允許,無校驗位
PCON = 0x80; //SMOD = 1
TMOD = 0x20; //timer1 mode 2
TL1 = 0xe8; // f
TH1 = 0xe8; // 波特率=---------------------
// 32*2^smod*12*(256-TL1)
TCON = 0x40; //start
ES = 1; //串行中斷使能
}
//------------------------------------------------------------
// 函數: 串口發送函數
// 入口參數: 無
// 返回值 : 無
// 函數說明: ,查詢方式發送,把接收到的CAN報文發送到計算機
//------------------------------------------------------------
void UART_transmit(void)
{
unsigned char i;
for ( i=0; i<11; i++)
{
SBUF = CAN_RX_buffer[i];
while (TI == 0) //等待發送完畢
{
}
}
}
//------------------------------------------------------------
// 函數: 串口接收中斷函數
// 入口參數: 無
// 返回值 : 無
// 函數說明: 本實例未使用,留作擴展
//------------------------------------------------------------
void Rx_INT(void) interrupt 4 using 3
{
unsigned char temp;
RI = 0;
temp = SBUF;
}
//------------------------------------------------------------
// 函數: 延時子函數
// 入口參數: 延時常數
// 返回值 : 無
// 函數說明: 軟件延時,不要求精確
//------------------------------------------------------------
void Delay(unsigned char m)
{
unsigned char i;
unsigned int j;
for( i = 0; i < m; i++)
{
for( j = 0; j < 3000; j++)
{
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -