求助:SJA1000+51调试寄存器读写正常,状态寄存器不正常
最近调试SJA1000+stm32,不通,前两天重新做了个51的板子,找了个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; //复位控制
/*------------------------------------------------
The main C function.Program execution starts
here after stack initialization.
------------------------------------------------*/
#define lab8k
#ifdef lab8k /* 如果用LAB8000调试,晶振为12MHz,最高波特率为4800*/
/*----------------------------------------------------------------------*/
#define XtalFreq (12000000) /* main crystal frequency */
#define CntrFreq (XtalFreq/12) /* main counter frequency */
#define BaudRate (4800) /* baud rate */
/*----------------------------------------------------------------------*/
#else
/*----------------------------------------------------------------------*/
#define XtalFreq (11059490) /* main crystal frequency */
#define CntrFreq (XtalFreq/12) /* main counter frequency */
#define BaudRate (9600) /* baud rate */
#define CntrTime (8) /* number of cycles for counter */
#define Ftar (32768.0) /* target crystal frequency */
/*----------------------------------------------------------------------*/
#endif
#define UARTOPEN
void main (void)
{
unsigned char tmp;
/*------------------------------------------------
Setup the serial port for 9600 baud at 11.0592MHz.
------------------------------------------------*/
#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);
}
} 很好奇,这个年代了为什么还有用外扩CAN芯片的。。。 huangqi412 发表于 2015-2-1 14:46
很好奇,这个年代了为什么还有用外扩CAN芯片的。。。
485改CAN,动主控工作量较大,退而求其次选择外扩,不知道SPI接口的MCP2515是不是好用些
页:
[1]