我想实现的功能是:
1、开发板1烧发送程序:
(1)按键1(PC0引脚)下降沿触发EXTI_Line0中断
(2)中断程序中添加
LED1_ON程序点亮LED1灯(PB9引脚);
CAN_Transmit(&TxMessage)函数发送数据 ;
2、开发板2烧接收程序:
(1)使能CAN接收中断,进入USB_LP_CAN_RX0_IRQHandler()中断函数
(2)中断函数中添加LED2_Flash程序,使LED2(PB7引脚)闪烁
我运行的结果是按开发板1的按键,开发板1的LED1亮,开发板2的LED2不闪烁!求解,以下是程序!
3、keil uvision4界面添加的程序文件目录
4、开发板1发送程序:
(1)stm32f103rbt6_can.c
#include "led.h"
#include "key.h"
#include "can.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_it.h"
CanTxMsg TxMessage;
/*******************************************************************************
* Function Name : main
* Description : main body function
* Input : None
* Output : None
* Return : None
*******************************************************************************/
int main()
{
LED_GPIO_INIT();
KEY_INIT();
CAN_Config();
CAN_SendMsgStructure();
LED1_OFF;
while(1)
{
}
}
(2)led.h
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stdint.h"
#define LED1_ON GPIO_SetBits(GPIOB, GPIO_Pin_9)
#define LED1_OFF GPIO_ResetBits(GPIOB, GPIO_Pin_9)
void LED_GPIO_INIT(void);
(3)led.c
#include "led.h"
GPIO_InitTypeDef LED_GPIO_Inistructure;
void LED_GPIO_INIT()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
LED_GPIO_Inistructure.GPIO_Pin=GPIO_Pin_9;
LED_GPIO_Inistructure.GPIO_Speed=GPIO_Speed_50MHz;
LED_GPIO_Inistructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &LED_GPIO_Inistructure);
}
(4)key.h
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_nvic.h"
void KEY_GPIO_INIT(void);
void KEY_EXTI_INIT(void);
void NVIC_Configuration(void);
void KEY_INIT(void);
(5)key.c
#include "key.h"
GPIO_InitTypeDef KEY_GPIO_Inistructure;
void KEY_GPIO_INIT()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
KEY_GPIO_Inistructure.GPIO_Pin=GPIO_Pin_0;
KEY_GPIO_Inistructure.GPIO_Speed=GPIO_Speed_50MHz;
KEY_GPIO_Inistructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOC, &KEY_GPIO_Inistructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0);
}
EXTI_InitTypeDef KEY_EXIT_Inistructure;
void KEY_EXTI_INIT()
{
KEY_EXIT_Inistructure.EXTI_Line=EXTI_Line0;
KEY_EXIT_Inistructure.EXTI_Mode=EXTI_Mode_Interrupt;
KEY_EXIT_Inistructure.EXTI_Trigger=EXTI_Trigger_Falling;
KEY_EXIT_Inistructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&KEY_EXIT_Inistructure);
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configure the nested vectored interrupt controller.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the EXTI0 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void KEY_INIT()
{
KEY_GPIO_INIT();
KEY_EXTI_INIT();
NVIC_Configuration();
}
(6)can.h
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_nvic.h"
#include "stm32f10x.h"
#include "stm32f10x_can.h"
void CAN_GPIO_Config(void);
void CAN_Mode_Config(void);
void CAN_Filter_Config(void);
void CAN_Config(void);
void CAN_SendMsgStructure(void);
(7)can.c
#include "can.h"
extern CanTxMsg TxMessage;
/********************************************************************************************
* 函数名:CAN_GPIO_Config
* 描述 :CAN的GPIO 配置,PA11上拉输入,PA12推挽输出
* 输入 :无
* 输出 : 无
* 调用 :内部调用
*********************************************************************************************/
void CAN_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*外设时钟设置*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
/*IO设置*/
/* Configure CAN pin: RX */ // PA11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN pin: TX */ // PA12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/******************************************************************************************
* 函数名:CAN_Mode_Config
* 描述 :CAN的模式 配置
* 输入 :无
* 输出 : 无
* 调用 :内部调用
******************************************************************************************/
void CAN_Mode_Config(void)
{
CAN_InitTypeDef CAN_InitStructure;
/************************CAN通信参数设置**********************************/
/*CAN寄存器初始化*/
CAN_DeInit();
CAN_StructInit(&CAN_InitStructure);
/*CAN单元初始化*/
CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 关闭时间触发通信模式使能
CAN_InitStructure.CAN_ABOM=DISABLE; //MCR-ABOM 自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE; //MCR-AWUM 使用自动唤醒模式
CAN_InitStructure.CAN_NART=ENABLE; //MCR-NART 禁止报文自动重传 DISABLE-自动重传
CAN_InitStructure.CAN_RFLM=DISABLE; //MCR-RFLM 接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文
CAN_InitStructure.CAN_TXFP=DISABLE; //MCR-TXFP 发送FIFO优先级 DISABLE-优先级取决于报文标示符
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //正常工作模式
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 2个时间单元
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; //BTR-TS1 时间段1 占用了6个时间单元
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq; //BTR-TS1 时间段2 占用了3个时间单元
CAN_InitStructure.CAN_Prescaler =5; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+2+3)/6=1Mbps
CAN_Init(&CAN_InitStructure);
}
/*******************************************************************************************
* 函数名:CAN_Filter_Config
* 描述 :CAN的过滤器 配置
* 输入 :无
* 输出 : 无
* 调用 :内部调用
*******************************************************************************************/
void CAN_Filter_Config(void)
{
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/*CAN过滤器初始化*/
CAN_FilterInitStructure.CAN_FilterNumber=0; //过滤器组0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //过滤器位宽为单个32位。
/* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */
CAN_FilterInitStructure.CAN_FilterIdHigh=0x00AA<<3; //要过滤的ID高位 地址设置的地方
CAN_FilterInitStructure.CAN_FilterIdLow= 0x0000; //要过滤的ID低位 地址设置的地方
CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x00FF<<3; //过滤器高16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000; //过滤器低16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FilterFIFO0; //过滤器被关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
/*CAN通信中断使能*/
CAN_ITConfig(CAN_IT_FMP0, ENABLE);
}
/*******************************************************************************************
* 函数名:CAN_Config
* 描述 :完整配置CAN的功能
* 输入 :无
* 输出 : 无
* 调用 :外部调用
*******************************************************************************************/
void CAN_Config(void)
{
CAN_GPIO_Config();
CAN_Mode_Config();
CAN_Filter_Config();
}
/*******************************************************************************************
* 函数名:CAN_SendMsgStructure
* 描述 :CAN通信报文内容设置
* 输入 :无
* 输出 : 无
* 调用 :外部调用
*******************************************************************************************/
void CAN_SendMsgStructure(void)
{
TxMessage.ExtId=0x00AA0000; //使用的扩展ID
TxMessage.IDE=CAN_ID_EXT; //扩展模式
TxMessage.RTR=CAN_RTR_DATA; //发送的是数据
TxMessage.DLC=1; //数据长度为1字节
TxMessage.Data[0]=0x16;
}
(8)stm32f10x_it.c
略去该文件中的其它函数
/*******************************************************************************
* Function Name : EXTI0_IRQHandler
* Description : This function handles External interrupt Line 0 request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void EXTI0_IRQHandler(void)
{
LED1_ON;
CAN_Transmit(&TxMessage);
EXTI_ClearFlag(EXTI_Line0);
}
5、开发板2接收程序
(1)stm32f103_can.c
#include "led.h"
#include "can.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_it.h"
CanRxMsg RxMessage; //接收缓冲区
/*******************************************************************************
* Function Name : main
* Description : main body function
* Input : None
* Output : None
* Return : None
*******************************************************************************/
int main()
{
LED_GPIO_INIT();
CAN_Config();
CAN_ReceiveMsgStructure();
LED2_OFF;
while(1)
{
}
}
(2)led.h
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stdint.h"
#define LED2_ON GPIO_SetBits(GPIOB, GPIO_Pin_7)
#define LED2_OFF GPIO_ResetBits(GPIOB, GPIO_Pin_7)
void LED_GPIO_INIT(void);
void Delay(volatile uint32_t nCount);
void LED2_flash(void);
(3)led.c
#include "led.h"
GPIO_InitTypeDef LED_GPIO_Inistructure;
void LED_GPIO_INIT()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
LED_GPIO_Inistructure.GPIO_Pin=GPIO_Pin_7;
LED_GPIO_Inistructure.GPIO_Speed=GPIO_Speed_50MHz;
LED_GPIO_Inistructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &LED_GPIO_Inistructure);
}
/*******************************************************************************
* Function Name : Delay
* Description : Time delays.
* Input : nCount
* Output : None
* Return : None
*******************************************************************************/
void Delay(volatile uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
/*******************************************************************************
* Function Name : LED2_flash
* Description : LED2 flashes.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void LED2_flash()
{
LED2_ON;
Delay(0xAFFFF);
LED2_OFF;
Delay(0xAFFFF);
}
(4)can.h
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_nvic.h"
#include "stm32f10x.h"
#include "stm32f10x_can.h"
void CAN_GPIO_Config(void);
void CAN_NVIC_Config(void);
void CAN_Mode_Config(void);
void CAN_Filter_Config(void);
void CAN_Config(void);
void CAN_ReceiveMsgStructure(void);
(5)can.c
#include "can.h"
extern CanRxMsg RxMessage;
/********************************************************************************************
* 函数名:CAN_GPIO_Config
* 描述 :CAN的GPIO 配置,PA11上拉输入,PA12推挽输出
* 输入 :无
* 输出 : 无
* 调用 :内部调用
*********************************************************************************************/
void CAN_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*外设时钟设置*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
/*IO设置*/
/* Configure CAN pin: RX */ // PA11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN pin: TX */ // PA12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*******************************************************************************************
* 函数名:CAN_NVIC_Config
* 描述 :CAN的NVIC 配置,第1优先级组,0,0优先级
* 输入 :无
* 输出 : 无
* 调用 :内部调用
*******************************************************************************************/
void CAN_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/*中断设置*/
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN_RX0_IRQChannel; //CAN1 RX0中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/******************************************************************************************
* 函数名:CAN_Mode_Config
* 描述 :CAN的模式 配置
* 输入 :无
* 输出 : 无
* 调用 :内部调用
******************************************************************************************/
void CAN_Mode_Config(void)
{
CAN_InitTypeDef CAN_InitStructure;
/************************CAN通信参数设置**********************************/
/*CAN寄存器初始化*/
CAN_DeInit();
CAN_StructInit(&CAN_InitStructure);
/*CAN单元初始化*/
CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 关闭时间触发通信模式使能
CAN_InitStructure.CAN_ABOM=DISABLE; //MCR-ABOM 自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE; //MCR-AWUM 使用自动唤醒模式
CAN_InitStructure.CAN_NART=DISABLE; //MCR-NART 禁止报文自动重传 DISABLE-自动重传
CAN_InitStructure.CAN_RFLM=DISABLE; //MCR-RFLM 接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文
CAN_InitStructure.CAN_TXFP=DISABLE; //MCR-TXFP 发送FIFO优先级 DISABLE-优先级取决于报文标示符
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //正常工作模式
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 2个时间单元
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; //BTR-TS1 时间段1 占用了6个时间单元
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq; //BTR-TS1 时间段2 占用了3个时间单元
CAN_InitStructure.CAN_Prescaler =5; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+2+3)/6=1Mbps
CAN_Init(&CAN_InitStructure);
}
/*******************************************************************************************
* 函数名:CAN_Filter_Config
* 描述 :CAN的过滤器 配置
* 输入 :无
* 输出 : 无
* 调用 :内部调用
*******************************************************************************************/
void CAN_Filter_Config(void)
{
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/*CAN过滤器初始化*/
CAN_FilterInitStructure.CAN_FilterNumber=0; //过滤器组0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //过滤器位宽为单个32位。
/* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */
CAN_FilterInitStructure.CAN_FilterIdHigh=0x00AA<<3; //要过滤的ID高位 地址设置的地方
CAN_FilterInitStructure.CAN_FilterIdLow= 0x0000; //要过滤的ID低位 地址设置的地方
CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x00FF<<3; //过滤器高16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000; //过滤器低16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FilterFIFO0; //过滤器被关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
/*CAN通信中断使能*/
CAN_ITConfig(CAN_IT_FMP0, ENABLE);
}
/*******************************************************************************************
* 函数名:CAN_Config
* 描述 :完整配置CAN的功能
* 输入 :无
* 输出 : 无
* 调用 :外部调用
*******************************************************************************************/
void CAN_Config(void)
{
CAN_GPIO_Config();
CAN_NVIC_Config();
CAN_Mode_Config();
CAN_Filter_Config();
CAN_ReceiveMsgStructure();
}
/*******************************************************************************************
* 函数名:CAN_ReceiveMsgStructure
* 描述 :CAN通信报文内容设置
* 输入 :无
* 输出 : 无
* 调用 :外部调用
*******************************************************************************************/
void CAN_ReceiveMsgStructure(void)
{
RxMessage.ExtId=0x00; //使用的扩展ID
RxMessage.IDE=0x00; //扩展模式
RxMessage.RTR=0x00; //接收的数据类型
RxMessage.DLC=0x00; //数据长度
RxMessage.Data[0]=0x00; //数据内容
}
(6)stm32f10x_it.h
该文件为库文件,我只添加了“include”,和声明一个外部变量
#include "stm32f10x_lib.h"
#include "led.h"
extern CanTxMsg TxMessage;
(7)stm32f10x_it.c
该文件为库文件,我只使用了其中的CAN接收中断函数,其它的文件内容略
/*******************************************************************************
* Function Name : USB_LP_CAN_RX0_IRQHandler
* Description : This function handles USB Low Priority or CAN RX0 interrupts
* requests.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USB_LP_CAN_RX0_IRQHandler(void)
{
LED2_flash();
}
|