- 打卡等级:初来乍到
- 打卡总天数:4
- 最近打卡:2024-11-16 09:51:54
注册会员
- 积分
- 127
|
本人使用的是STC32G8K64型号的芯片和STM32F303进行can通信,STM32F303作为数据发动段,STC32G8K64作为读取和处理数据端。can波特率为500kHz,接收端的程序是仿照着官方例程来写的。但是在通信过程中无法接收到数据。通过调试发现接收端程序无法进入到if(B_Can1Read){}判断里面,我尝试着用串口打印CAN状态寄存器(SR)的值,发现会返回0x22和0x2A两个值,通过查看STC32G8的芯片手册发现
CAN状态寄存器(SR)中的B1位始终为1,即ES:CAN模块错误状态位始终为1。但是对于芯片手册中关于这一位的描述有点摸不着头脑:该位为1时表示"CAN模块至少有一个错误寄存器的值达到或超过了96",但是在芯片手册中找了一段时间发现没有对can的错误寄存器进行叙述。现求教论坛内的大佬,知道这是什么原因吗?代码需要修改哪里才能成功实现两块芯片之间的can通信?
//相关宏定义
#define TSG1 2 //0~15
#define TSG2 1 //1~7 (TSG2 不能设置为0)
#define BRP 3 //0~63
#define SJW 0 //重新同步跳跃宽度
#define SAM 0 //总线电平采样次数: 0:采样1次; 1:采样3次
//can波特率设置函数
void CANSetBaudrate()
{
CanWriteReg(BTR0,(SJW << 6) + BRP);
CanWriteReg(BTR1,(SAM << 7) + (TSG2 << 4) + TSG1);
}
void app_can_init(void)
{
CANEN = 1; //CAN1模块使能
CANSEL = 0; //选择CAN1模块
P_SW1 = (P_SW1 & ~(3<<4)) | (0<<4);
CanWriteReg(MR ,0x04);//使能 Reset Mode
CANSetBaudrate(); //设置波特率
//不进行滤波,接收所有报文
CanWriteReg(ACR0,0x00); //总线验收代码寄存器
CanWriteReg(ACR1,0x00);
CanWriteReg(ACR2,0x00);
CanWriteReg(ACR3,0x00);
CanWriteReg(AMR0,0xFF); //总线验收屏蔽寄存器
CanWriteReg(AMR1,0xFF);
CanWriteReg(AMR2,0xFF);
CanWriteReg(AMR3,0xFF);
CanWriteReg(IMR ,0xff); //中断寄存器
CanWriteReg(ISR ,0xff); //清中断标志
CanWriteReg(MR ,0x01);//退出 Reset Mode, 采用单滤波设置(设置过滤器后注意选择滤波模式)
CANICR = 0x02;//CAN中断使能
}
//can通信处理函数
void vApp_Can_Process(void)
{
u8 n,i,j;
u8 sr;
if(msecond >= 1000) //1秒到
{
msecond = 0;
sr = CanReadReg(SR);
printf("%#x\r\n", sr);
if(sr & 0x01) //判断是否有 BS:BUS-OFF状态
{
CANAR = MR;
CANDR &= ~0x04; //清除 Reset Mode, 从BUS-OFF状态退出
}
}
if(B_Can1Read)//判断 CAN1 是否接收到数据
{
B_Can1Read = 0;
//CANSEL = CAN1; //选择CAN1模块
n = CanReadMsg(CAN1_Rx); //读取接收内容
if(n>0)
{
for(i=0;i<n;i++)
{
// CanSendMsg(&CAN1_Rx[i]); //CAN总线原样返回
printf("CAN1 ID=0x%08lX DLC=%d FF=%d RTR=%d ",CAN1_Rx[i].ID,CAN1_Rx[i].DLC,CAN1_Rx[i].FF,CAN1_Rx[i].RTR); //串口打印帧信息
for(j=0;j<CAN1_Rx[i].DLC;j++)
{
printf("0x%02X ",CAN1_Rx[i].DataBuffer[j]); //从串口输出收到的数据
}
printf("\r\n");
}
}
}
}
//定时器配置函数
void Timer_config(void)
{
TIM_InitTypeDef TIM_InitStructure; //结构定义
TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TI
TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
TIM_InitStructure.TIM_Value = (u16)(65536UL - (MAIN_Fosc / 1000UL)); //中断频率, 1000次/秒
TIM_InitStructure.TIM_PS = 0; //8位预分频器(n+1), 0~255
TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或D
Timer_Inilize(Timer0,&TIM_InitStructure); //初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4
NVIC_Timer0_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
//定时器中断函数
void Timer0_ISR_Handler (void) interrupt TMR0_VECTOR //锟斤拷锟叫讹拷时锟窖撅拷锟斤拷锟斤拷锟斤拷?
{
msecond++;
}
//main函数
void main(void)
{
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXSFR(); //扩展SFR(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
// GPIO_config();
P1_MODE_IO_PU(GPIO_Pin_0 | GPIO_Pin_1);
Timer_config();
UART_config();
app_can_init();
EA = 1;
B_Can1Send = 0;
while (1)
{
vApp_Can_Process();
}
}
|
-
|