版权声明:本文为博主原创文章,转载请附上原文出处链接。
文章目录
前言
今天介绍下STC32G12K128单片机CAN程序。
1.基于艾克姆科技的STC32G12K128开发板+CAN转TTL模块,提供CAN通信的测试程序,程序是库函数版本。
2.实验连接图如下:(本实验用到的是单片机的CAN2)
3.CAN总线通信肯定不能只有一个节点,所以用户还需电脑端连接个USB转CAN的转换器方便测试。USB转CAN转换器的CANH连接上图CANH端子,USB转CAN转换器的CANL连接上图CANL端子。
4.硬件连接好后,电脑打开USB转CAN测试用软件,设置波特率500K,通信界面如下:
5.程序源码基于Keil C251编写。详见附件。
单片机源程序如下:
/************* 功能说明 ****************************************************************************
上位机软件通过USB转CAN转换器连接CAN模块,MCU定时向上位机发送标准帧。
若上位机向MCU发送数据,MCU会回传相同的一帧数据。
注:下载时, 选择时钟 24MHZ (CAN波特率500KHz)。
********************************************************************************************************/
#include "config.h"
#include "can.h"
#include "STC32G_CAN.h"
#include "timer.h"
extern volatile uint8 B_1ms;
extern bit B_Can2Send;
extern bit B_Can2Read;
uint16 CAN2_ID; //CAN数据帧ID
uint8 RX2_BUF[8]; //CAN接收数组
uint8 TX2_BUF[8]; //CAN发送数组
uint16 msecond;
/***************************************************************************
* 描 述 : CAN2等待函数
* 入 参 : uint8 i
* 返回值 : 无
**************************************************************************/
void WaitCan2Send(uint8 i)
{
while((--i) && (B_Can2Send));
}
/***************************************************************************
* 描 述 : 主函数
* 入 参 : 无
* 返回值 : 无
**************************************************************************/
int main()
{
uint8 sr;
uint8 buffer[16];
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
Timer0Init(); //定时器0初始化
CAN_Init(); //CAN初始化
EA = 1; //打开总中断
//CAN一帧数据信息
CAN2_ID = 0x0123;
TX2_BUF[0] = 0x21;
TX2_BUF[1] = 0x22;
TX2_BUF[2] = 0x23;
TX2_BUF[3] = 0x24;
TX2_BUF[4] = 0x25;
TX2_BUF[5] = 0x26;
TX2_BUF[6] = 0x27;
TX2_BUF[7] = 0x28;
while(1)
{
if(B_1ms) //1ms到
{
B_1ms = 0;
if(++msecond >= 1000) //1秒到
{
msecond = 0;
//------------------处理CAN2模块-----------------------
AUXR2 |= 0x08; //选择CAN2模块
sr = CanReadReg(SR);
if((sr & 0x88)==0x80) //接收空闲,接收BUFFER有数据帧
{
CanReadFifo(buffer); //读取清除接收BUFFER
}
if(sr & 0x01) //判断是否有 BS:BUS-OFF状态
{
CANAR = MR;
CANDR &= ~0x04; //清除 Reset Mode, 从BUS-OFF状态退出
}
else
{
B_Can2Send = 1;
CanSendStandardFrame(CAN2_ID,TX2_BUF);
WaitCan2Send(50); //等待CAN2发送完毕
}
}
}
if(B_Can2Read)
{
B_Can2Read = 0;
AUXR2 |= 0x08; //选择CAN2模块
CAN2_ID = CanReadStandardFrame(RX2_BUF); //接收CAN总线数据
CanSendStandardFrame(CAN2_ID+1,RX2_BUF); //发送CAN总线数据
}
}
}
#include "can.h"
/**************************************************************************
功能描述:CAN口初始化
入口参数:无
返回值:无
*************************************************************************/
void CAN_Init(void)
{
CAN_InitTypeDef CAN_InitStructure; //结构定义
P0_MODE_IO_PU(GPIO_Pin_2|GPIO_Pin_3); //P0.2~P0.3 设置为准双向口
CAN2_SW(CAN2_P02_P03); //CAN2_P02_P03,CAN2_P52_P53,CAN2_P46_P47,CAN2_P72_P73
EAXSFR(); //将EAXFR位置1,以访问在XDATA区域的扩展SFR
CAN_InitStructure.CAN_Enable = ENABLE; //CAN功能使能 ENABLE或DISABLE
CAN_InitStructure.CAN_IMR = CAN_ALLIM; //CAN中断寄存器 CAN_DOIM,CAN_BEIM,CAN_TIM,CAN_RIM,CAN_EPIM,CAN_EWIM,CAN_ALIM,CAN_ALLIM,DISABLE
CAN_InitStructure.CAN_SJW = 0; //重新同步跳跃宽度 0~3
CAN_InitStructure.CAN_SAM = 0; //总线电平采样次数 0:采样1次; 1:采样3次
//CAN总线波特率=Fclk/((1+(TSG1+1)+(TSG2+1))*(BRP+1)*2)
CAN_InitStructure.CAN_TSG1 = 2; //同步采样段1 0~15
CAN_InitStructure.CAN_TSG2 = 1; //同步采样段2 1~7 (TSG2 不能设置为0)
CAN_InitStructure.CAN_BRP = 3; //波特率分频系数 0~63
//24000000/((1+3+2)*4*2)=500KHz
CAN_InitStructure.CAN_ACR0 = 0x00; //总线验收代码寄存器 0~0xFF
CAN_InitStructure.CAN_ACR1 = 0x00;
CAN_InitStructure.CAN_ACR2 = 0x00;
CAN_InitStructure.CAN_ACR3 = 0x00;
CAN_InitStructure.CAN_AMR0 = 0xff; //总线验收屏蔽寄存器 0~0xFF
CAN_InitStructure.CAN_AMR1 = 0xff;
CAN_InitStructure.CAN_AMR2 = 0xff;
CAN_InitStructure.CAN_AMR3 = 0xff;
CAN_Inilize(CAN2,&CAN_InitStructure); //CAN2 初始化
NVIC_CAN_Init(CAN2,ENABLE,Priority_1); //中断使能, CAN1/CAN2; ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
/*********************************END FILE********************************************/
本文含有隐藏内容,请 开通VIP 后查看