目录
BF7006是BYD半导体推出的汽车AECQ100 GRADE1品质等级的32位通用MCU,ARM Cortex-M0内核,最高32MHz,Flash最大96KB,EEPROM最大2KB,SRAM最大4KB。封装形式为 LQFP64、LQFP48、TSSOP28,适合如电动车窗、电动座椅、雨刮、车灯、门锁等多种汽车电子车身控制应用。
1. 芯片系统构成
2. 硬件平台
平台选择官方的EVB,这个板子默认是采用5V,芯片本身支持的电压范围是3.6V-5.5V,所以注意调试用的工具必须要支持5V的电压。
3. 建立工程
IDE选择MDK,编译器选择armcc或gcc编译。
3.1 启动文件
安装好官方提供的MDK PACK后,在例程中可以找到对应的启动文件startup_BF7006AMxx.s。可以对比stm32f030的启动代码,差别主要是中断向量表。因为例程中的只有MDK的启动文件,所以可以参考stm32f030修改一个gcc版本的启动文件。
3.2 系统配置文件
和其他芯片类似,系统初始化文件对应system_BF7006AMxx.c,不过对应的头文件是system_ARMCM0.h,可以改成system_BF7006AMxx.h,不过底层一些代码会include这个文件,这块需要改,可以新建一个system_ARMCM0.h文件,然后这个文件只包含system_BF7006AMxx.h即可。
3.3 驱动文件
在PACK安装目录内,例如:
C:\Keil_v5\ARM\PACK\BYD\BYDMicro_DFP\1.2.1\Device
文件夹Include和Source分别对应外设驱动的头文件和源文件。
3.4 CMSIS文件
和STM32F030一样即可,或者拷贝例程的中CMSIS头文件。
3.5 选择MCU
MDK中选择对应的MCU
和ST的例程不同,没有其他宏定义需要设置。
3.6 RTE_Components.h
驱动库会包含文件RTE_Components.h,将此文件拷贝到工程内,此时应该可以编译通过了。
3.7 关闭看门狗
芯片的看门狗默认是开着的,所以开始的时候可以先把看门狗关掉,否则程序会不停的重启。
WDT_CS = 0; //Disable WatchDog
4. GPIO
BF7006最多支持 54 个通用 GPIO,分别对应 A0~A7,B0~B7,C0~C7,D0~D7,E0~E7,F0~F7,G0~G5。可以看出GPIO是8位一组。所有 GPIO 均支持内部上拉功能,上拉电阻 20K。其中端口 A、B、D 支持外部中断功能,共24个外部中断,而PA7端口支持NMI中断, 中断类型可选,包括上升沿、下降沿、高电平、低电平四种中断类型。
注意,上电期间GPIO的状态是不定的,而当VCC电压下降至 3.1V,芯片产生掉电复位,此时 GPIO 端口为输入高阻态。
4.1 设置方向
设置GPIO_PTDD( GPIO x )寄存器的对应位就可以设置方向。0x1:输出,0x0:输入(注意和一般的设置是反的)。例如设置B0-B3口为输出:
GPIO_PTDD(GPIOB) |= 0x0f; //Set GPIOB0-3 output
4.2 输出或输入
输出时写 GPIO_PTD( GPIO x )寄存器,输入时读入这个寄存器。例如设置B0-B3口输出高电平:
GPIO_PTD(GPIOB) |= 0x0f; //GPIOB0-3 output high
4.3 设置上拉
通过设置GPIO_PTPE(GPIOx)寄存器使能输入上拉。例如设置B0上拉:
GPIO_PTPE(GPIOB) |= 0x01; //Enable Pull Up
4.4 外部中断
4.4.1 设置触发模式
通过设置GPIO_PTSC(GPIOx)寄存器的位0设置中断检测模式。注意只有GPIOA、GPIOB、GPIOD支持。
如果需要上升沿或下降沿触发中断,这个位需要设置为0;如果是高低电平触发,则设置为1。例如设置GPIOB6为下降沿触发
GPIO_PTSC(GPIOB) &= (uint8_t)~(1 << 6); //Edge trigge
通过设置GPIO_PTES(GPIOx)寄存器的对应位设置对应GPIO的中断类型。
GPIO_PTES(GPIOB) &= (uint8_t)~(1 << 6); //Falling trigger
4.4.2 使能中断
通过设置GPIO_PTES(GPIOx)寄存器的对应位设置对应GPIO的中断使能。
GPIO_PTPS(GPIOB) |= (1 << 6); //Enable int
通过设置GPIO_PTSC(GPIOx)寄存器的位1设置全局中断使能。
GPIO_PTSC(GPIOB) |= (1 << 1);
NVIC_EnableIRQ(GPIO_IRQn);
4.4.3 中断函数
中断处理函数是GPIO_IRQHandler,可以通过GPIO_PTSC(GPIOx)寄存器的位3判断是否是端口中断
例如GPIOB6产生中断,判断GPIOB的PTSC寄存器的位3即可:
if((GPIO_PTSC(GPIOB) & (1 << 3)) == 0x00)
return;
然后通过GPIOA_INTSTA、GPIOA_INTSTB、GPIOA_INTSTD判断是哪个GPIO中断,1表示有中断。接着写这个寄存器清零中断状态,最后设置PTSC寄存器的位2清除中断。
uint8_t status = GPIOB_INTSTA;
if((status & (1 << 6)) > 0)
{
GPIOB_INTSTA |= (1 << 6);
GPIO_PTSC(GPIOB) |= (1 << 2);
Printf("GPIOB6 Interrupt\n");
}
4.4.4 设置上拉(可选)
板子上有预留上拉电阻,但是没有贴,所以需要设置对应的GPIO为上拉。
GPIO_PTPE(GPIOB) |= (1 << 6);
4.5 NMI中断
注意只有GPIOA7支持NMI中断。
4.5.1 清除NMI中断标志
通过设置NMISC位2为1清除中断标志,注意电平中断无法清除这个标志。
4.5.2 设置触发模式
通过设置NMISC位0设置模式,如果需要上升沿或下降沿触发中断,这个位需要设置为0;如果是高低电平触发,则设置为1。
设置NMISC位5选择触发类型
例如下降沿触发:
NMISC &= (uint8_t)~(1 << 0); //Edge trigge
NMISC &= (uint8_t)~(1 << 5); //Falling trigger
4.5.3 中断函数
通过设置NMISC位4使能端口中断
通过设置NMISC位1使能中断
NMI函数不需要通过NVIC_EnableIRQ使能中断。
NMISC |= (1 << 4);
NMISC |= (1 << 1); //Enable global int
中断处理函数是NMI_Handler,NMISC的位3判断是否是NMI中断。
void NMI_Handler(void)
{
if((NMISC & (1 << 3)) == 0x00)
return;
NMISC |= (1 << 2); //Clear NMI int
Printf("NMI Interrupt\n");
}
4.5.4 设置上拉(可选)
同4.4.4,将GPIOA7设置为上拉,否则不会进中断。
GPIO_PTPE(GPIOA) |= (1 << 7);