|
本帖最后由 byxzwz 于 2020-3-12 14:11 编辑
新手 虽然水到高级会员 哈哈一个简单的KEA128的CAN收发程序 希望能帮到有需要的人
过程中用到的资料也会发上来
话不多说 上代码
uint8_t rec_data[8]={0};
void CAN_Init(uint8_t clk,uint8_t sjw,uint8_t brp,uint8_t tseg1,uint8_t tseg2)
{
//MSCAN的引脚复用选择CAN_TX为PTC7,CAN_RX为PTC6
SIM_PINSEL1 &= ~SIM_PINSEL1_MSCANPS_MASK;
//MSCAN模块时钟门控制;SIM_SCGC的MSCAN位=1:使能总线给MSCAN时钟;
//SIM_SCGC的MSCAN位=0:禁止总线给MSCAN时钟
SIM_SCGC |= SIM_SCGC_MSCAN_MASK;
//MSCAN12模块使能
MSCAN_CANCTL1 |= MSCAN_CANCTL1_CANE_MASK;
//0 MSCAN 时钟源是振荡器时钟。
//1 MSCAN 时钟源是总线时钟。
if(1 == clk)
MSCAN_CANCTL1 |= MSCAN_CANCTL1_CLKSRC_MASK;
else
MSCAN_CANCTL1 &= ~MSCAN_CANCTL1_CLKSRC_MASK;
//禁止侦听模式,即开启正常模式
MSCAN_CANCTL1 &= ~MSCAN_CANCTL1_LISTEN_MASK;
//进入初始化模式
MSCAN_CANCTL0 |= MSCAN_CANCTL0_INITRQ_MASK;
//等待应答进入初始化模式
while((MSCAN_CANCTL1 & MSCAN_CANCTL1_INITAK_MASK)== 0);
//使用2个32位接收过滤器,查阅芯片手册寄存器MSCAN_CANIDAC
MSCAN_CANIDAC &= ~MSCAN_CANIDAC_IDAM_MASK;
//如果不设置为0xff,就需要对每一位进行过滤
//0为需要过滤 1为不需要过滤
MSCAN_BASE_PTR->CANIDAR_BANK_1[0]=0xff;
MSCAN_BASE_PTR->CANIDAR_BANK_1[1]=0xff;
MSCAN_BASE_PTR->CANIDAR_BANK_1[2]=0xff;
MSCAN_BASE_PTR->CANIDAR_BANK_1[3]=0xff;
MSCAN_BASE_PTR->CANIDMR_BANK_1[0]=0xff;
MSCAN_BASE_PTR->CANIDMR_BANK_1[1]=0xff;
MSCAN_BASE_PTR->CANIDMR_BANK_1[2]=0xff;
MSCAN_BASE_PTR->CANIDMR_BANK_1[3]=0xff;
MSCAN_BASE_PTR->CANIDAR_BANK_2[0]=0xff;
MSCAN_BASE_PTR->CANIDAR_BANK_2[1]=0xff;
MSCAN_BASE_PTR->CANIDAR_BANK_2[2]=0xff;
MSCAN_BASE_PTR->CANIDAR_BANK_2[3]=0xff;
MSCAN_BASE_PTR->CANIDMR_BANK_2[0]=0xff;
MSCAN_BASE_PTR->CANIDMR_BANK_2[1]=0xff;
MSCAN_BASE_PTR->CANIDMR_BANK_2[2]=0xff;
MSCAN_BASE_PTR->CANIDMR_BANK_2[3]=0xff;
//波特率配置(按照公式:波特率=clk/((1+tseg1+tseg2)*分频因数(BRP+1)))
//有几点需要注意的 1+tseg1+tseg2的范围[8,25]
MSCAN_CANBTR0 = MSCAN_CANBTR0_SJW(sjw) ;
MSCAN_CANBTR0 = MSCAN_CANBTR0_BRP(brp);
MSCAN_CANBTR1 = MSCAN_CANBTR1_TSEG1(tseg1);
MSCAN_CANBTR1 = MSCAN_CANBTR1_TSEG2(tseg2);
MSCAN_CANBTR1 &= ~MSCAN_CANBTR1_SAMP_MASK;
//退出初始化模式
MSCAN_CANCTL0 &= ~MSCAN_CANCTL0_INITRQ_MASK;
while((MSCAN_CANCTL1 & MSCAN_CANCTL1_INITAK_MASK) == 1);
//CAN 模块使能
MSCAN_CANCTL1 |= MSCAN_CANCTL1_CANE_MASK;
}
void CAN_Send(uint32_t mscan_addr,const uint8_t * mscan_data,uint8_t mscan_dlr,uint8_t mscan_ide)
{
uint8_t u8TransmitterEmptyFlag;
//read MSCAN_CANTFLG_TXE register ==> able use cache
u8TransmitterEmptyFlag = MSCAN_CANTFLG & MSCAN_CANTFLG_TXE_MASK;
//select transmitter channel
MSCAN_CANTBSEL = MSCAN_CANTBSEL_TX(u8TransmitterEmptyFlag);
if(mscan_ide == 1){
//allocation address
MSCAN_TEIDR0 = ((mscan_addr>>21)&0xff);
MSCAN_TEIDR1 = ((mscan_addr>>13)&0xe0)|0x18|((mscan_addr>>15)&0x07);
MSCAN_TEIDR2 = ((mscan_addr>>7)&0xff);
MSCAN_TEIDR3 = ((mscan_addr<<1)&0xfe);
}
if(mscan_ide == 0){
MSCAN_TSIDR0 = (mscan_addr >> 3) & 0xff ;//前3位数据不要 TSIDR1:10-3 数据>>3 & 0xff(&为了准确赋值寄存器)
MSCAN_TSIDR1 = (mscan_addr << 5) & 0xe0 ;//前3位数据放到TSIDR0的后3位 TSIDR0:2-0 数据<<5 & 0xe0(&为了准确赋值寄存器)
}
//allocation data
memcpy((void *)&MSCAN_TEDSR0,(void *)mscan_data,mscan_dlr);
MSCAN_TDLR = mscan_dlr;
MSCAN_TBPR = 0;
MSCAN_CANTFLG = (MSCAN_CANTBSEL&MSCAN_CANTBSEL_TX_MASK)&0x07;
}
uint8_t CAN_Receive()
{
if( (MSCAN_CANRFLG & 0x01) == 0)// (CAN0RFLG_RXF == 0)
{
return 1; //未接收到帧
}
if((MSCAN_CANRFLG & 0x01) == 1) //判断是否接收到数据
{
uint8_t i = 0 ;
if((MSCAN_RSIDR1 & 0x08) == 0)
for(i = 0 ; i < (MSCAN_RDLR & 0x0f) ; i ++)
{
rec_data = MSCAN_REDSR(i) ;
}
return re_success ;
}
MSCAN_CANRFLG = 1 ;
return no_infor ; //无接收数据
}
|
|