求CAN通信C程序。SJA1000+PC82C250.晶振是12M的。

求CAN通信C程序。SJA1000+PC82C250.晶振是12M的。,第1张

这里有两个晶振,一个是单片机的你选择12M,一个是sja1000的推荐选择16M。

给你程序你不一定能用啊,还要和硬件对应啊,比如你的地址确定问题。

这就是网络的程序为什么大多不能直接使用的原因啊。

给你提供一些思路

1、sja1000初始化

2、发送子程序

3、中断方式接收

下面是一些程序段

你参考下(已用于产品)

/**********SJA1000初始化***********//

void Init_SJA1000(void)

{

uchar state

uchar ACRR[4]={0XAA,0XFF,0X22,0X11}// 接收代码寄存器

uchar AMRR[4]={0xff,0xff,0xff,0xff}// 接收屏蔽寄存器

//uchar AMRR[4]={0x00,0x00,0xff,0xff}// 接收屏蔽寄存器

do// 使用do--while语句确保进入悉携复位模式

{

MODR = 0x09// 设置MOD.0=1--进入复位模式,以便设置相应的寄存器

state = MODR

}

while( !(state &0x01) )

// 对SJA1000部分寄存器进行初始化设置

CDR = 0x88// CDR为时钟分频器,CDR.3=1--时钟关闭, CDR.7=0---basic CAN, CDR.7=1---Peli CAN

BTR0 = 0x04//0x31// 总线定时寄存器0 ;总线波特率设定

BTR1 = 0x1c//0x1c// 总线定时寄存器1 ;总线波特率设定

IER = 0x01// IER.0=1--接收中断使能; IER.1=0--关闭发送中断使能

OCR = 0xaa// 配置输出控制寄存器

CMR = 0x04// 释放接收缓冲器

ACR0 = ACRR[0]// 初始化接收代码寄存器

ACR1 = ACRR[1]

ACR2 = ACRR[2]

ACR3 = ACRR[3]

AMR0 = AMRR[0]// 初始化逗扰接收屏蔽寄存器

AMR1 = AMRR[1]

AMR2 = AMRR[2]

AMR3 = AMRR[3]

do// 使用do--while语句确保退出复位模式山陆旦

{

MODR = 0x08//MOD.3=0--双滤波器模式

state = MODR

}

while( state &0x01 )

}//////////////////////////////////////

//**********CAN发送数据到CAN-Bus***********//

void CAN_TXD(void)

{

uchar state

//初始化标示码头信息

TX_buffer[0] = 0x88//.7=0--扩展帧;.6=0--数据帧.0-.3=100--数据长度为8字节

// TX_buffer[1] = 0xFF//本帧信息的ID

//TX_buffer[2] = 0xFF

TX_buffer[3] = 0xFF

TX_buffer[4] = 0xFF

do //查询SJA1000是否处于接收状态,当SJA1000不处于接收状态时才可继续执行

{

state = SR //SR为SJA1000的状态寄存器

}

while( state &0x10 ) //SR.4=1 正在接收,等待

do //查询SJA1000是否处于发送完毕状态

{

state = SR

}

while(!(state &0x08))//SR.3=0,发送请求未处理完,等待直到SR.3=1

do //查询发送缓冲器状态

{

state = SR

}

while(!(state &0x04))//SR.2=0,发送缓冲器被锁。等待直到SR.2=1

//将待发送的一帧数据信息存入SJA1000的相应寄存器中

TBSR0 = TX_buffer[0]

TBSR1 = TX_buffer[1]

TBSR2 = TX_buffer[2]

TBSR3 = TX_buffer[3]

TBSR4 = TX_buffer[4]

TBSR5 = TX_buffer[5]

TBSR6 = TX_buffer[6]

TBSR7 = TX_buffer[7]

TBSR8 = TX_buffer[8]

TBSR9 = TX_buffer[9]

TBSR10 = TX_buffer[10]

TBSR11 = TX_buffer[11]

TBSR12 = TX_buffer[12]

CMR = 0x04//置位发送请求

}//////////////////////////////////////

//**********中断接收来自CAN-Bus数据***********//

void inter1_can_rxd( void ) interrupt 0

{

uchar state

EA = 0 //关CPU中断

IE0 = 0//由于是中断INT1是电平触发方式,所以需要软件将INT1的中断请求标志IE0清零

state = IR//IR为SJA1000的中断寄存器

if( state &0x01) //若IR.0=1--接收中断

{

RX_buffer[0] = RBSR0

RX_buffer[1] = RBSR1

RX_buffer[2] = RBSR2

RX_buffer[3] = RBSR3

RX_buffer[4] = RBSR4

RX_buffer[5] = RBSR5

RX_buffer[6] = RBSR6

RX_buffer[7] = RBSR7

RX_buffer[8] = RBSR8

RX_buffer[9] = RBSR9

RX_buffer[10] = RBSR10

RX_buffer[11] = RBSR11

RX_buffer[12] = RBSR12

RXD_flag = 1//接收标志置位,以便进入接收处理程序

CMR = 0x04 //CMR.2=1--接收完毕,释放接收缓冲器

state = ALC//释放仲裁随时捕捉寄存器(读该寄存器即可)

state = ECC//释放错误代码捕捉寄存器(读该寄存器即可)

}

IER = 0x01 // IER.0=1--接收中断使能

EA = 1 //重新开启CPU中断

}//////////////////////////////////////

//********** ***********//

希望对你能有帮助

ain() { unsigned int aRCC_Configuration()/*初肆缺如始化扮烂 GPIOC时钟*/ // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE)USART_Configuration()Delay(10)CAN_configure()// LedInit()while(1) { //CAN_ClearFlag(CAN_FLAG_BOF)GPIO_SetBits(GPIOB,GPIO_Pin_7)Delay(10)GPIO_ResetBits(GPIOB,GPIO_Pin_7)Delay(10)GPIO_SetBits(GPIOB,GPIO_Pin_7)Delay(10)GPIO_ResetBits(GPIOB,GPIO_Pin_7)Delay(10)can_send(0x57)a=can_rev()USART1_Putc(a)} } -------------------------------------------------------------------------------------------------- #include"stm32f10x_lib.h" void CAN_configure(void) { u8 wrongCAN_InitTypeDef CAN_InitStructureCAN_FilterInitTypeDef CAN_FilterInitStructureGPIO_InitTypeDef GPIO_InitStructure// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE)/裂启/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE)// RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE)/* Configure CAN pin: RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPUGPIO_Init(GPIOA, &GPIO_InitStructure)/* Configure CAN pin: TX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PPGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHzGPIO_Init(GPIOA, &GPIO_InitStructure)/*can register int*/ CAN_DeInit()CAN_StructInit(&CAN_InitStructure)/*can cell init*/ CAN_InitStructure.CAN_TTCM=DISABLECAN_InitStructure.CAN_ABOM=DISABLECAN_InitStructure.CAN_AWUM=DISABLECAN_InitStructure.CAN_NART=DISABLECAN_InitStructure.CAN_RFLM=DISABLECAN_InitStructure.CAN_TXFP=DISABLECAN_InitStructure.CAN_Mode=CAN_Mode_LoopBackCAN_InitStructure.CAN_SJW=CAN_SJW_1tqCAN_InitStructure.CAN_BS1=CAN_BS1_8tqCAN_InitStructure.CAN_BS2=CAN_BS2_7tqCAN_InitStructure.CAN_Prescaler=5wrong=CAN_Init(&CAN_InitStructure)while(wrong==CANINITFAILED){} /* CAN filter init */ CAN_FilterInitStructure.CAN_FilterNumber=0CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMaskCAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bitCAN_FilterInitStructure.CAN_FilterIdHigh=0x0000//((u32)0x0020<<21)>>16//标识符 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000//(((u32)0x0020<<21)|CAN_ID_STD|CAN_RTR_DATA)// CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0CAN_FilterInitStructure.CAN_FilterActivation=ENABLECAN_FilterInit(&CAN_FilterInitStructure)// CAN_ITConfig(CAN_IT_FMP0, ENABLE)} void can_send(unsigned char data) { CanTxMsg TxMessageu8 TransmitMailbox = 0TxMessage.StdId=0x0020//标识符 TxMessage.RTR=CAN_RTR_DATATxMessage.IDE=CAN_ID_STDTxMessage.DLC=2TxMessage.Data[0]=dataTxMessage.Data[1]=0xFETransmitMailbox=CAN_Transmit(&TxMessage)while(CAN_TransmitStatus(TransmitMailbox) != CANTXOK){}//等待发送 } unsigned char can_rev(void) { CanRxMsg RxMessageRxMessage.StdId=0x11//不需要设置 RxMessage.IDE=CAN_ID_STDRxMessage.DLC=2RxMessage.Data[0]=0x00RxMessage.Data[1]=0x00while (CAN_MessagePending(CAN_FIFO0)==0)//等到接收 CAN_Receive(CAN_FIFO0, &RxMessage)CAN_FIFORelease(CAN_FIFO0)return RxMessage.Data[0]} ------------------------------------------------------------------------------------------------- void RCC_Configuration(void) { //*** ErrorStatus HSEStartUpStatus//*** //* system clocks configuration -----------------系统时钟配置-------------------/// //* RCC system reset(for debug purpose) // RCC_DeInit()//将外设RCC寄存器重设为缺省值 //* Enable HSE * RCC_HSEConfig(RCC_HSE_ON)//开启外部高速晶振(HSE) //* Wait till HSE is ready / HSEStartUpStatus = RCC_WaitForHSEStartUp()//等待HSE起振 if(HSEStartUpStatus == SUCCESS) //若成功起振,(下面为系统总线时钟设置) { //* Enable Prefetch Buffer / FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable)//使能FLASH预取指缓存 //* Flash 2 wait state / FLASH_SetLatency(FLASH_Latency_2)//设置FLASH存储器延时时钟周期数(根据不同的系统时钟选取不同的值) //* HCLK = SYSCLK / RCC_HCLKConfig(RCC_SYSCLK_Div1)//设置AHB时钟=72 MHz //* PCLK2 = HCLK/2 / RCC_PCLK2Config(RCC_HCLK_Div2)//设置APB1时钟=36 MHz(APB1时钟最大值) //* PCLK1 = HCLK/2 / RCC_PCLK1Config(RCC_HCLK_Div2)//设置APB2时钟=72 MHz //* Configure ADCCLK such as ADCCLK = PCLK2/2 / // RCC_ADCCLKConfig(RCC_PCLK2_Div2)//RCC_PCLK2_Div2,4,6,8 //* PLLCLK = 8MHz * 9 = 72 MHz / RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9)//PLL必须在其激活前完成配置(设置PLL时钟源及倍频系数) //* Enable PLL / RCC_PLLCmd(ENABLE)//* Wait till PLL is ready / while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } //* Select PLL as system clock source / RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK)//* Wait till PLL is used as system clock source / while(RCC_GetSYSCLKSource() != 0x08) { } } //***** RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE)RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE)//***/ }


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12356360.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存