求救M128与sja1000的自收发程序问题
#include <mega128.h>#define uchar unsigned char
#define uint unsigned int
#define clk 16000000
#definesja_baseaddr 0x4000
#defineMODE 0x00
#defineCMR 0x01
#defineSR 0x02
#defineIR 0x03
#defineIER 0x04
#defineBTR0 0x06
#defineBTR1 0x07
#defineOCR 0x08
#defineRXERR 0x0E //接收错误计数器
#defineTXERR 0x0F //发送错误计数器
#defineACR0 0x10
#defineACR1 0x11
#defineACR2 0x12
#defineACR3 0x13
#defineAMR0 0x14
#defineAMR1 0x15
#defineAMR2 0x16
#defineAMR3 0x17
#defineRMC 0x1D //RX报文计数器
#defineRBSA 0x1E //接收缓冲区起始地址
#defineCDR 0x1F
//发送缓冲器
#define TXbuffer0 0x10
#define TXbuffer1 0x11
#define TXbuffer2 0x12
#define TXbuffer3 0x13
#define TXbuffer4 0x14
#define TXbuffer5 0x15
#define TXbuffer6 0x16
#define TXbuffer7 0x17
#define TXbuffer8 0x18
#define TXbuffer9 0x19
#define TXbuffer10 0x1A
#define TXbuffer11 0x1B
#define TXbuffer12 0x1C
// 接收缓冲器
#define Rxbuffer0 0x10
#define Rxbuffer1 0x11
#define Rxbuffer2 0x12
#define Rxbuffer3 0x13
#define Rxbuffer4 0x14
#define Rxbuffer5 0x15
#define Rxbuffer6 0x16
#define Rxbuffer7 0x17
#define Rxbuffer8 0x18
#define Rxbuffer9 0x19
#define Rxbuffer10 0x1A
#define Rxbuffer11 0x1B
#define Rxbuffer12 0x1C
void uart_send(uchar data);
uchar *sja_address;
uchar read_sja( uchar addr) //读SJA1000状态寄存器子程序
{
sja_address=(uchar *)sja_baseaddr;
sja_address=sja_address+addr;
return (*sja_address);
}
void write_sja(uchar addr,uchar val) //写SJA1000寄存器子程序
{
sja_address=(uchar *)sja_baseaddr;
sja_address=sja_address+addr;
*sja_address=val;
}
void delay(uint x)
{
uint i,j;
for(i=x;i>0;i--)
{
for (j=1000;j>0;j--);
}
}
voidcan_read()
{
uchar a;
int i;
a=read_sja(Rxbuffer0);
a=read_sja(Rxbuffer1);
a=read_sja(Rxbuffer2);
a=read_sja(Rxbuffer3);
a=read_sja(Rxbuffer4);
a=read_sja(Rxbuffer5);
a=read_sja(Rxbuffer6);
a=read_sja(Rxbuffer7);
a=read_sja(Rxbuffer8);
a=read_sja(Rxbuffer9);
a=read_sja(Rxbuffer10);
a=read_sja(Rxbuffer11);
a=read_sja(Rxbuffer12);
write_sja(CMR,0X04); //release RXbuffer
for(i=0;i<13;i++)
{
uart_send(a);
}
}
/*interrupt void ex0()
{
if(IR&0x01==0x01) //产生了接收中断
can_read();
} */
void uart_send(uchar data)
{
while (!UCSR0A.5 ); //判断发送缓冲器是否准备好接收新数据
UDR0 = data; //发送数据
}
void mcu_init()
{
UBRR0H=((clk/16/9600)-1)/256; //波特率设置
UBRR0L=((clk/16/9600)-1)%256;
UCSR0B=0x18; //接收和发送使能
UCSR0C=0x06; //数据帧位数
MCUCR=0x80; //允许外部并行扩展接口
SREG=0x00; //关总中断
EIMSK=0x01; //外部中断0使能
EICRA=0x02; //INT0下降沿产生中断请求
}
/*
***** **************************************
函数功能:初始化sja1000
内容:复位、波特率设置、开放中断等等
*******************************************
*/
void sja1000_init()
{
write_sja(MODE,0x01); //进入复位模式
while(!(read_sja(MODE)&0x01)) //检测SJA1000是否达到复位模式
{
write_sja(MODE,0x01); //进入复位模式
}
delay(500);
write_sja(CMR,0x12); //自收自发
write_sja(MODE,0x08); //单滤波器
write_sja(IER,0x01); // 接收中断使能
write_sja(RBSA,0x00); //缓存器起始地址寄存器设置为0
write_sja(RXERR,0x00);
write_sja(TXERR,0x00);
write_sja(IR,0x00);
write_sja(ACR0,0x00); //acceptcode buffer
write_sja(ACR1,0x00);
write_sja(ACR2,0x00);
write_sja(ACR3,0x00);
write_sja(AMR0,0xff); //验收屏蔽寄存器,接收任何标识符的数据包
write_sja(AMR1,0xff);
write_sja(AMR2,0xff);
write_sja(AMR3,0xff);
write_sja(BTR0,0x00); //设置1M的波特率通信
write_sja(BTR1,0x14);
write_sja(OCR,0x1a); //配置输出管脚,TX1 悬空,TX0推挽输出
write_sja(CDR,0xc8); // 关闭时钟,工作于pelican模式
write_sja(MODE,0x00); //进入工作模式
}
void CAN_Tx()
{
uchar state;
state=read_sja(SR);
while(!(state & 0x04)); //检查发送缓冲器是否被锁定
write_sja(TXbuffer0,0x88); //扩展帧,数据帧,长度为8字节
write_sja(TXbuffer1,0x22); //节点IP
write_sja(TXbuffer2,0x00);
write_sja(TXbuffer3,0x0F);
write_sja(TXbuffer4,0x30);
write_sja(TXbuffer5,0x05);
write_sja(TXbuffer6,0x06);
write_sja(TXbuffer7,0x06);
write_sja(TXbuffer8,0x07);
write_sja(TXbuffer9,0x07);
write_sja(TXbuffer10,0x08);
write_sja(TXbuffer11,0x0b);
write_sja(TXbuffer12,0x0c);
write_sja(CMR,0x01); //启动发送
while(read_sja(SR)&0x08) ; // 检测发送是否完成
SREG=0x80; //开总中断
}
/*
****************************
函数说明:主函数
****************************
*/
voidmain()
{
mcu_init();
sja1000_init();
DDRC=0xff;
PORTC=0x40; //choose the sja1000
while(1)
{CAN_Tx();
can_read();
}
}
大家帮帮忙 我的自收发程序 总是搞不通哪里有问题谢了
最近也在调SJA1000,我的硬件应该没问题(见下面的测试过程),不知道哪里出了问题
你搞定了吗?搞定的话能不能发个demo啊
测试过程:
1、在正常模式下(地址0寄存器写入0)读写测试寄存器(地址0x09)正常;写入55读回55,写入aa读回aa;
2、在上述写完测试寄存器后立刻切入测试模式(地址0寄存器写入1)写时钟分频寄存器(地址0x1f),连续写C8/C4/C0(关闭clockout、clock=Fosc/2、clock=Fosc/10),用仿真器单步跟踪可以看到clockout频率分别为0(无输出)、8MHz、1.6MHz(注:Fosc=16MHz)。
从上述两点应该看可否得出结论:1、MCU和SJA1000硬件连接正常;2、SJA1000正常工作;
现在的我调试时发现:初始化(PeriCAN模式,初始化代码不能确定是否正确)完毕后(实际上是写完时钟分频寄存器后)状态寄存器(偏址0x02)是0X3C,也即收、发状态都是1(忙),无法进一步操作
以上测试已经断开TJA1050与SJA1000的TX/RX。)。
#include <REG52.H> /* special function register declarations */
/* for the intended 8051 derivative */
#include <stdio.h> /* prototype declarations for I/O functions */
#include <absacc.h> /* 主要是用于寻址外部存储器*/
#include "sja1000_reg.h" /* sja1000T的寄存器定义文件*/
#include "sja1000.h"
sbit SJARst = P1^0; //复位控制
#define XtalFreq (12000000) /* main crystal frequency */
#define CntrFreq (XtalFreq/12) /* main counter frequency */
#define BaudRate (4800) /* baud rate */
#define UARTOPEN
void main (void)
{
unsigned char tmp;
#ifdef UARTOPEN
SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD = 0x21;
/* TMOD: timer 1, mode 2, 8-bit reload*/
/* TMOD: timer 0, mode 1, 16-bit */
PCON |= 0x80; /* SMOD = 1 Double Baud Rate for TH1 load */
TH0=TL0 = 0;
// TH1=TL1 = (unsigned int)(256 - ( (XtalFreq / BaudRate) / 192));
TH1=TL1 = (unsigned int)(256 - ( XtalFreq/ BaudRate / ((PCON&0x80)?1:2) ) / 192) ;
TR1 = 1; /* TR1:timer 1 run */
TI = 1; /* TI: set TI to send first char of UART*/
// SCON= 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
// TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
// TH1 = 0xFD; /* TH1:reload value for 9600 baud @ 11.0595MHZ */
// TR1 = 1; /* TR1:timer 1 run */
// TI = 1; /* TI: set TI to send first char of UART */
#endif
PX0=1; //外部中断0高优先级
IT0=1; //设置INT0为下降沿中断
IE0=0;/* 清中断标志 */
EX0=1; //使能INT0中断
/*------------------------------------------------
Note that an embedded program never exits (because
there is no operating system to return to).It
must loop and execute forever.
------------------------------------------------*/
printf ("Hello World\n"); /* Print "Hello World" */
SJA_Init();//主要是使芯片复位
tmp = SJA_Test();
/* Enter the reset Mode */
REG_MODE = 0x01;
while((REG_MODE&0x01)!= 0x01); //确定进入复位模式
printf("1.Enter the Reset Mode,REG_MODE=0x%.4x\n",REG_MODE);
REG_CDR = 0xc0;//设置时钟分频寄存器。CDR.7 = 1,PeliCAN模式;CDR.6(RX0激活,关闭RX1)fCLKOUT = fOSC/2, CDR.3(CLKOUT ON)
REG_CDR = 0xc4;//设置时钟分频寄存器。CDR.7 = 1,PeliCAN模式;CDR.6(RX0激活,关闭RX1)fCLKOUT = fOSC/10, CDR.3(CLKOUT ON)
REG_CDR = 0xc8;//设置时钟分频寄存器。CDR.7 = 1,PeliCAN模式;CDR.6(RX0激活,关闭RX1)fCLKOUT = fOSC/2, CDR.3(CLKOUT off)
REG_RBSA = 0x00;//RX缓冲器起始地址
/*Configure acceptance code and mask register*/
REG_ACR0 = 0xff;//验收码寄存器
REG_ACR1 = 0xff;
REG_ACR2 = 0xff;
REG_ACR3 = 0xff;
REG_AMR0 = 0xff;//验收屏蔽寄存器,接收任何标识符的数据包
REG_AMR1 = 0xff;
REG_AMR2 = 0xff;
REG_AMR3 = 0xff;
/*configure bus timing registers*/
REG_BTR0 = 0x49;//0x00;
REG_BTR1 = 0x14;//0x14; //100k@12MHz
REG_IR_ABLE = 0x01;//Peli模式中断使能,接收中断使能,发送中断禁止
REG_IR_ABLE = 0xff;//Peli模式中断使能,接收中断使能,发送中断禁止
REG_OCR = 0x1a;//设置输出模式:正常输出,从TX0口输出;TX1悬空
REG_MODE = 0x0c; //进入自接收模式.CDR.3(选择单个验收滤波器),CDR.2 (此模式可以检测所有节点)
do
{
tmp = REG_MODE;
}while(tmp != 0x0c);//确定进入自接收模式下
printf("2.Enter the self-test Mode\n",REG_MODE);
printf("REG_SR=0x%.4x\n",REG_SR);
SJA1000_TxData();//发送数据
printf("\n\n");
//SJA1000_Rx_Display();//接收数据展示
EA = 1;//使能全局中断
while(1);
}
void SJA1000_TxData(void)
{
while(REG_SR & 0x10) /*printf("REG_SR=0x%.4x\n", REG_SR)*/;//当SJA1000不处于接收状态时才可继续执行,SR.4==0x1,正在接收,等待
while(!(REG_SR & 0x08))printf("REG_SR=0x%.4x\n", REG_SR); //SR.3=0,发送请求未处理完,等待直到SR.3=1
while(!(REG_SR & 0x04))printf("REG_SR=0x%.4x\n", REG_SR); //SR.2=0,发送缓冲器被锁。等待直到SR.2=1
REG_TxBuffer0 = 0x08;//帧信息,标准帧,数据帧,8字节
REG_TxBuffer1 = 0xFF;//标识符1
REG_TxBuffer2 = 0xFF;//标识符2
REG_TxBuffer3 = 0x11;//发送数据位:1
REG_TxBuffer4 = 0x22;//发送数据位:2
REG_TxBuffer5 = 0x33;
REG_TxBuffer6 = 0x44;
REG_TxBuffer7 = 0x55;
REG_TxBuffer8 = 0x66;
REG_TxBuffer9 = 0x77;
REG_TxBuffer10 = 0x88;//here Over
SJA1000_Tx_Display();
REG_CMD = 0x10;//自接收
while(!(REG_SR & 0x08));//检测发送完毕
}
void SJA1000_Tx_Display(void)
{
printf( " TBSR3 = 0x%.4x \n", REG_TxBuffer3 );
printf( " TBSR4 = 0x%.4x \n", REG_TxBuffer4 );
printf( " TBSR5 = 0x%.4x \n", REG_TxBuffer5 );
printf( " TBSR6 = 0x%.4x \n", REG_TxBuffer6 );
printf( " TBSR7 = 0x%.4x \n", REG_TxBuffer7 );
printf( " TBSR8 = 0x%.4x \n", REG_TxBuffer8 );
printf( " TBSR9 = 0x%.4x \n", REG_TxBuffer9 );
printf( " TBSR10 = 0x%.4x \n",REG_TxBuffer10);
}
void SJA_Init(void)
{
//SJA1000复位
unsigned char i;
for(i = 0;i < 125;i++);
SJARst = 0;
for(i = 0;i < 125;i++);//给RST引脚一个低脉冲
SJARst = 1;
for(i = 0;i < 125;i++);
}
unsigned char SJA_Test(void)
{
unsigned char tmp;
REG_MODE = 0;
tmp = 0;
tmp = REG_TEST;
tmp = 255;
do
{
REG_TEST = tmp;
if(REG_TEST != tmp) return tmp;
} while(tmp--);
return 0;
}
/************************************************************
函数:ex0_int
说明:中断服务程序
入口:无
返回:无
***********************************************************/
void handle_int(void) interrupt 0 using 1
{
if(REG_IR & 0x01) //产生了接收中断
{
#pragma disable
printf( " Received message.\n");
printf( " RBSR3 = %x \n", REG_RxBuffer3 );
printf( " RBSR4 = %x \n", REG_RxBuffer4 );
printf( " RBSR5 = %x \n", REG_RxBuffer5 );
printf( " RBSR6 = %x \n", REG_RxBuffer6 );
printf( " RBSR7 = %x \n", REG_RxBuffer7 );
printf( " RBSR8 = %x \n", REG_RxBuffer8 );
printf( " RBSR9 = %x \n", REG_RxBuffer9 );
printf( " RBSR10 = %x \n",REG_RxBuffer10);
}
}
页:
[1]