1 博客内容
博客内容基于STM32F103 RET6芯片(Keil.STM32F1xx_DFP.2.3.0.pack)+PCA82C250,使用CAN通讯环回模式测试CAN收发。CAN引脚对应PA11(RX)和PA12(TX),使用PB11电压测试数据是否成功。实际测试中PB11输出正常,但PA11和PA12异常,接示波器排查判断PCA82C250硬件故障。
2 STM32芯片、TJA1050、上位机
STM32芯片引脚电平为3.3V,而CAN逻辑电压为0和2.5V。因此STM32芯片和CAN解析器(eg:周立功_USBCAN/Vector_CANape)之间需要收发器,将TTL电平转CAN逻辑电压。本文使用的收发器为PCA82C250,其中TJA1050和PCA82C250可以相互替换。
3 CAN环回模式、轮询/中断接收模式
CAN环回模式用于CAN测试,对外发送同时自己接收。
CAN接收理解两种模式:
- 轮询接收模式。不论收件箱是否有邮件,都在不停收,直到收到为止。博客内容参考STM32官方帮助文件。文件位置:D:SoftKeilDemoen.stsw-stm32054STM32F10x_StdPeriph_Lib_V3.5.0ProjectSTM32F10x_StdPeriph_ExamplesCANLoopBack。
- 中断接收模式。CAN接收FIFO(( First Input First Output))寄存器CAN_RF0R,到有消息到达,该寄存器的0和1位会累加(硬件执行),显示消息挂起。通过该位判断是否接收。
中断模式查看挂起消息数量(官方自带库函数):
uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber)
{
uint8_t message_pending=0;
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_FIFO(FIFONumber));
if (FIFONumber == CAN_FIFO0)
{
message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03);
}
else if (FIFONumber == CAN_FIFO1)
{
message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03);
}
else
{
message_pending = 0;
}
return message_pending;
}
4 程序原理
CAN对外发送(TX)标准ID为0x11的数据帧,长度为2个字节(内容为0xCA,0xFE)。对接收(RX)内容进行判断,如果全部正确,PB11高电平(实际该引脚连接接示波器,未连接LED)。
if (RxMessage.StdId!=0x11)
{
return 0;
}
if (RxMessage.IDE!=CAN_ID_STD)
{
return 0;
}
if (RxMessage.DLC!=2)
{
return 0;
}
if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)
{
return 0;
}
5 主程序(Main.c)
//================================================
// 名称: Main.c
// 作者: Morven_X
// 版本: 1.1
// 编制: 2021/03/5 23:55
// 更新: 2021/03/08 20:37
// 功能: 基于STM32F103 RET6芯片,使用CAN发送和接收信息
// 简介: 使用回环模式查看CAN发送,使用USBCAN接收数据(失败)
// Email: morven_xie@163.com
//================================================
# include "stm32f10x.h"
# include "stm32f10x_gpio.h"
# include "stm32f10x_can.h"
# include "Delay.h"
# include "CAN.h"
int main(void)
{
LED_Init();
LED_PB_Init();
Delay_Init();
CAN_GPIO_Init();
NVIC_Configuration();
JTAG_Init();
/* Turns selected LED Off */
LED_Off_PB11;
LED_Off_PB12;
LED_Off_PB13;
LED_Off_PB14;
int i;
int TestRx;
while (1)
{
/* CAN transmit at 125Kb/s and receive by polling in loopback mode */
TestRx = CAN1_Polling();
if (TestRx == 0)
{
/* Faild to turn on led PB13 */
LED_On_PB13;
}
else
{
/*Success to turn on PB11 */
LED_On_PB11;
}
/*PC3-LED_ON */
LED_On;
Delay_ms(100);
// while(i < 0xFFFFF)
// {
// i++;
// }
LED_Off_PB11;
LED_Off_PB12;
LED_Off;
// while(i >0x01)
// {
// i--;
// }
Delay_ms(100);
}
}
6 CAN程序(CAN.c)
# include "stm32f10x_rcc.h"
# include "stm32f10x_gpio.h"
# include "CAN.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能C口GPIO时钟
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //选择推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3 | GPIO_Pin_6; //指定引脚3
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //设置输出速率50MHz//
GPIO_Init(GPIOC,&GPIO_InitStruct); //初始化外设GPIOx寄存器
}
void LED_PB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能B口GPIO时钟
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //选择推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; //指定引脚
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //设置输出速率50MHz//
GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化外设GPIOx寄存器
}
void CAN_GPIO_Init(void)
{
//**********GPIO初始化**********//
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能A口GPIO时钟
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11 ; //指定引脚PA11,CAN_RX上拉输入
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //设置输出速率50MHz//
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU; //选择上拉输入
GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化外设GPIOA寄存器
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12 ; //指定引脚PA12,CAN_TX复用推挽
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //设置输出速率50MHz//
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //选择推挽输出
GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化外设GPIOA寄存器
}
/**
* @brief Configures the NVIC and Vector Table base address.
* @param None
* @retval None
*/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void JTAG_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //先开启开启AFIO复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能GPIOB外设时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//关闭JTAG,保留SWD(若同时关闭SWD,芯片作废)
}
int CAN1_Polling(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
CanRxMsg RxMessage;
uint32_t i = 0;
uint8_t TransmitMailbox = 0;
/* CAN register init */
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
/* Baudrate = 125kbps*/
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;
CAN_InitStructure.CAN_Prescaler=48;
CAN_Init(CAN1, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
/* transmit */
TxMessage.StdId=0x11;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.IDE=CAN_ID_STD;
TxMessage.DLC=2;
TxMessage.Data[0]=0xCA;
TxMessage.Data[1]=0xFE;
TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);
i = 0;
while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFFFF))
{
i++;
}
i = 0;
while((CAN_MessagePending(CAN1, CAN_FIFO0) < 1) && (i != 0xFFFF))
{
i++;
}
/* receive */
RxMessage.StdId=0x00;
RxMessage.IDE=CAN_ID_STD;
RxMessage.DLC=0;
RxMessage.Data[0]=0x00;
RxMessage.Data[1]=0x00;
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
if (RxMessage.StdId!=0x11)
{
return 0;
}
if (RxMessage.IDE!=CAN_ID_STD)
{
return 0;
}
if (RxMessage.DLC!=2)
{
return 0;
}
if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)
{
return 0;
}
return 1; /* Test Passed */
}
7 CAN头文件(CAN.h)
#ifndef _CAN_H
#define _CAN_H
void LED_Init(void);
void LED_PB_Init(void);
void NVIC_Configuration(void);
void CAN_GPIO_Init(void);
void JTAG_Init(void);
int CAN1_Polling(void);
#define LED_On GPIO_SetBits(GPIOC,GPIO_Pin_3) ;
#define LED_On_PB11 GPIO_SetBits(GPIOB,GPIO_Pin_11) ;
#define LED_On_PB12 GPIO_SetBits(GPIOB,GPIO_Pin_12) ;
#define LED_On_PB13 GPIO_SetBits(GPIOB,GPIO_Pin_13) ;
#define LED_On_PB14 GPIO_SetBits(GPIOB,GPIO_Pin_14) ;
#define LED_Off_PB11 GPIO_ResetBits(GPIOB,GPIO_Pin_11) ;
#define LED_Off_PB12 GPIO_ResetBits(GPIOB,GPIO_Pin_12) ;
#define LED_Off_PB13 GPIO_ResetBits(GPIOB,GPIO_Pin_13) ;
#define LED_Off_PB14 GPIO_ResetBits(GPIOB,GPIO_Pin_14) ;
#define LED_Off GPIO_ResetBits(GPIOC,GPIO_Pin_3) ;
#endif
1 博客内容
博客内容基于STM32F103 RET6芯片(Keil.STM32F1xx_DFP.2.3.0.pack)+PCA82C250,使用CAN通讯环回模式测试CAN收发。CAN引脚对应PA11(RX)和PA12(TX),使用PB11电压测试数据是否成功。实际测试中PB11输出正常,但PA11和PA12异常,接示波器排查判断PCA82C250硬件故障。
2 STM32芯片、TJA1050、上位机
STM32芯片引脚电平为3.3V,而CAN逻辑电压为0和2.5V。因此STM32芯片和CAN解析器(eg:周立功_USBCAN/Vector_CANape)之间需要收发器,将TTL电平转CAN逻辑电压。本文使用的收发器为PCA82C250,其中TJA1050和PCA82C250可以相互替换。
3 CAN环回模式、轮询/中断接收模式
CAN环回模式用于CAN测试,对外发送同时自己接收。
CAN接收理解两种模式:
- 轮询接收模式。不论收件箱是否有邮件,都在不停收,直到收到为止。博客内容参考STM32官方帮助文件。文件位置:D:SoftKeilDemoen.stsw-stm32054STM32F10x_StdPeriph_Lib_V3.5.0ProjectSTM32F10x_StdPeriph_ExamplesCANLoopBack。
- 中断接收模式。CAN接收FIFO(( First Input First Output))寄存器CAN_RF0R,到有消息到达,该寄存器的0和1位会累加(硬件执行),显示消息挂起。通过该位判断是否接收。
中断模式查看挂起消息数量(官方自带库函数):
uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber)
{
uint8_t message_pending=0;
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_FIFO(FIFONumber));
if (FIFONumber == CAN_FIFO0)
{
message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03);
}
else if (FIFONumber == CAN_FIFO1)
{
message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03);
}
else
{
message_pending = 0;
}
return message_pending;
}
4 程序原理
CAN对外发送(TX)标准ID为0x11的数据帧,长度为2个字节(内容为0xCA,0xFE)。对接收(RX)内容进行判断,如果全部正确,PB11高电平(实际该引脚连接接示波器,未连接LED)。
if (RxMessage.StdId!=0x11)
{
return 0;
}
if (RxMessage.IDE!=CAN_ID_STD)
{
return 0;
}
if (RxMessage.DLC!=2)
{
return 0;
}
if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)
{
return 0;
}
5 主程序(Main.c)
//================================================
// 名称: Main.c
// 作者: Morven_X
// 版本: 1.1
// 编制: 2021/03/5 23:55
// 更新: 2021/03/08 20:37
// 功能: 基于STM32F103 RET6芯片,使用CAN发送和接收信息
// 简介: 使用回环模式查看CAN发送,使用USBCAN接收数据(失败)
// Email: morven_xie@163.com
//================================================
# include "stm32f10x.h"
# include "stm32f10x_gpio.h"
# include "stm32f10x_can.h"
# include "Delay.h"
# include "CAN.h"
int main(void)
{
LED_Init();
LED_PB_Init();
Delay_Init();
CAN_GPIO_Init();
NVIC_Configuration();
JTAG_Init();
/* Turns selected LED Off */
LED_Off_PB11;
LED_Off_PB12;
LED_Off_PB13;
LED_Off_PB14;
int i;
int TestRx;
while (1)
{
/* CAN transmit at 125Kb/s and receive by polling in loopback mode */
TestRx = CAN1_Polling();
if (TestRx == 0)
{
/* Faild to turn on led PB13 */
LED_On_PB13;
}
else
{
/*Success to turn on PB11 */
LED_On_PB11;
}
/*PC3-LED_ON */
LED_On;
Delay_ms(100);
// while(i < 0xFFFFF)
// {
// i++;
// }
LED_Off_PB11;
LED_Off_PB12;
LED_Off;
// while(i >0x01)
// {
// i--;
// }
Delay_ms(100);
}
}
6 CAN程序(CAN.c)
# include "stm32f10x_rcc.h"
# include "stm32f10x_gpio.h"
# include "CAN.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能C口GPIO时钟
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //选择推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3 | GPIO_Pin_6; //指定引脚3
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //设置输出速率50MHz//
GPIO_Init(GPIOC,&GPIO_InitStruct); //初始化外设GPIOx寄存器
}
void LED_PB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能B口GPIO时钟
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //选择推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; //指定引脚
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //设置输出速率50MHz//
GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化外设GPIOx寄存器
}
void CAN_GPIO_Init(void)
{
//**********GPIO初始化**********//
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能A口GPIO时钟
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11 ; //指定引脚PA11,CAN_RX上拉输入
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //设置输出速率50MHz//
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU; //选择上拉输入
GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化外设GPIOA寄存器
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12 ; //指定引脚PA12,CAN_TX复用推挽
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //设置输出速率50MHz//
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //选择推挽输出
GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化外设GPIOA寄存器
}
/**
* @brief Configures the NVIC and Vector Table base address.
* @param None
* @retval None
*/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void JTAG_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //先开启开启AFIO复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能GPIOB外设时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//关闭JTAG,保留SWD(若同时关闭SWD,芯片作废)
}
int CAN1_Polling(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
CanRxMsg RxMessage;
uint32_t i = 0;
uint8_t TransmitMailbox = 0;
/* CAN register init */
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
/* Baudrate = 125kbps*/
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;
CAN_InitStructure.CAN_Prescaler=48;
CAN_Init(CAN1, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
/* transmit */
TxMessage.StdId=0x11;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.IDE=CAN_ID_STD;
TxMessage.DLC=2;
TxMessage.Data[0]=0xCA;
TxMessage.Data[1]=0xFE;
TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);
i = 0;
while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFFFF))
{
i++;
}
i = 0;
while((CAN_MessagePending(CAN1, CAN_FIFO0) < 1) && (i != 0xFFFF))
{
i++;
}
/* receive */
RxMessage.StdId=0x00;
RxMessage.IDE=CAN_ID_STD;
RxMessage.DLC=0;
RxMessage.Data[0]=0x00;
RxMessage.Data[1]=0x00;
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
if (RxMessage.StdId!=0x11)
{
return 0;
}
if (RxMessage.IDE!=CAN_ID_STD)
{
return 0;
}
if (RxMessage.DLC!=2)
{
return 0;
}
if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)
{
return 0;
}
return 1; /* Test Passed */
}
7 CAN头文件(CAN.h)
#ifndef _CAN_H
#define _CAN_H
void LED_Init(void);
void LED_PB_Init(void);
void NVIC_Configuration(void);
void CAN_GPIO_Init(void);
void JTAG_Init(void);
int CAN1_Polling(void);
#define LED_On GPIO_SetBits(GPIOC,GPIO_Pin_3) ;
#define LED_On_PB11 GPIO_SetBits(GPIOB,GPIO_Pin_11) ;
#define LED_On_PB12 GPIO_SetBits(GPIOB,GPIO_Pin_12) ;
#define LED_On_PB13 GPIO_SetBits(GPIOB,GPIO_Pin_13) ;
#define LED_On_PB14 GPIO_SetBits(GPIOB,GPIO_Pin_14) ;
#define LED_Off_PB11 GPIO_ResetBits(GPIOB,GPIO_Pin_11) ;
#define LED_Off_PB12 GPIO_ResetBits(GPIOB,GPIO_Pin_12) ;
#define LED_Off_PB13 GPIO_ResetBits(GPIOB,GPIO_Pin_13) ;
#define LED_Off_PB14 GPIO_ResetBits(GPIOB,GPIO_Pin_14) ;
#define LED_Off GPIO_ResetBits(GPIOC,GPIO_Pin_3) ;
#endif
举报