【STC32G12K128开发板】——STC32G12K128单片机CAN程序

发布于:2022-12-18 ⋅ 阅读:(949) ⋅ 点赞:(0)

版权声明:本文为博主原创文章,转载请附上原文出处链接。


前言

今天介绍下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 后查看