本帖最后由 gjianw217 于 2016-10-5 12:32 编辑
本帖子要实现的是控制MM32F103开发板上的两个 LED 实现一个类似跑马灯的效果, 该实验的关键在于如何控制MM32F103的 IO口输出。
1 MM32F103的GPIO认识
查看MM32F103的用户手册可知,其GPIO端口的每个位可以由软件分别配置成8种模式:
(1)输入浮空
(2)输入上拉
(3)输入下拉
(4)模拟输入
(5)开漏输出
(6)推挽输出
(7)推挽式复用功能
(8)开漏复用功能
每个I/O端口可以自由编程,然而必须按照32位字访问I/O端口寄存器(不允许半字或字节访问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器进行读/更改的独立访问;这样,在读更改访问之间产生IRQ是不会发生危险。MM32F103的每个IO 端口都有7个寄存器来控制。他们分别是:配置模式的 2个 32 位的端口配置寄存器 CRL 和 CRH ;2个 32 位的数据寄存器IDR 和 ODR ;1个 32 位 的置/复位寄存器 BSRR ;一个 16 位的复寄存器BRR ;1个 32 位的锁存寄存器 LCKR。常用的 IO 端口寄存器只有 4个: CRL 、CRHCRH 、IDR 、ODR。
MM32F103的 CRL 控制着每组 IO 端口(A~E)的低 8位的模式。每个 IO 端口的位占用 CRL 的 4个位,高两位为CNF,低两位为MODE 。
CRH 的作用和CRL 完全一样,只是 CRL 控制的是低 8位输出口,而CRH 控制的是高 8位输出口。
IDR 是一个端口输入数据寄存器,只用了低 16 位。该寄存器为只读寄存器,并且只能以 16 位的形式读出。该寄存器各位的描述如下图所示:
ODR 是一个端口输出数据寄存器,也只用了低 16 位。该寄存器为可读写,从该寄存器读出来的数据可以用于判断当前 IO 口的输出状态。而向该寄存器写数据,则可以控制某个 IO 口的输出电平。该寄存器各位描述如下图所示:
2 硬件电路
LED与MM32的连接电路如下图所示,即可以通过配置PA8和PD2两个GPIO,来控制LED的状态。
3 软件实现
(1)初始化函数
void LED_Init(void)
{
RCC->APB2ENR|=RCC_APB2RSTR_IOPARST; //RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB2ENR|=RCC_APB2RSTR_IOPDRST; //RCC->APB2ENR|=1<<5; //使能PORTC时钟
GPIOA->CRH|=GPIO_CRH_MODE8; //GPIOA->CRH|=0X00000003;//PA8推挽输出
GPIOA->ODR|=GPIO_ODR_ODR8; // GPIOA->ODR|=1<<8; //PA8 输出高
GPIOD->CRL|=GPIO_CRL_MODE2; //GPIOD->CRL|=0X00000300; //PD.2推挽输出
GPIOD->ODR|=GPIO_ODR_ODR2; //GPIOD->ODR|=1<<2; //PD.2输出高
}
(2)宏定义
这个有点和STM32战舰V3的代码相似
//IO口操作,只对单一的IO口,确保n的值小于16
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n)
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n)
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n)
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n)
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n)
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n)
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n)
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n)
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n)
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n)
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n)
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n)
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n)
(3)主函数
int main(void)
{
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
LED0=0;
LED1=1;
delay_ms(1000);
LED0=1;
LED1=0;
delay_ms(1000);
}
}
4 实验效果
本帖最后由 gjianw217 于 2016-10-5 12:32 编辑
本帖子要实现的是控制MM32F103开发板上的两个 LED 实现一个类似跑马灯的效果, 该实验的关键在于如何控制MM32F103的 IO口输出。
1 MM32F103的GPIO认识
查看MM32F103的用户手册可知,其GPIO端口的每个位可以由软件分别配置成8种模式:
(1)输入浮空
(2)输入上拉
(3)输入下拉
(4)模拟输入
(5)开漏输出
(6)推挽输出
(7)推挽式复用功能
(8)开漏复用功能
每个I/O端口可以自由编程,然而必须按照32位字访问I/O端口寄存器(不允许半字或字节访问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器进行读/更改的独立访问;这样,在读更改访问之间产生IRQ是不会发生危险。MM32F103的每个IO 端口都有7个寄存器来控制。他们分别是:配置模式的 2个 32 位的端口配置寄存器 CRL 和 CRH ;2个 32 位的数据寄存器IDR 和 ODR ;1个 32 位 的置/复位寄存器 BSRR ;一个 16 位的复寄存器BRR ;1个 32 位的锁存寄存器 LCKR。常用的 IO 端口寄存器只有 4个: CRL 、CRHCRH 、IDR 、ODR。
MM32F103的 CRL 控制着每组 IO 端口(A~E)的低 8位的模式。每个 IO 端口的位占用 CRL 的 4个位,高两位为CNF,低两位为MODE 。
CRH 的作用和CRL 完全一样,只是 CRL 控制的是低 8位输出口,而CRH 控制的是高 8位输出口。
IDR 是一个端口输入数据寄存器,只用了低 16 位。该寄存器为只读寄存器,并且只能以 16 位的形式读出。该寄存器各位的描述如下图所示:
ODR 是一个端口输出数据寄存器,也只用了低 16 位。该寄存器为可读写,从该寄存器读出来的数据可以用于判断当前 IO 口的输出状态。而向该寄存器写数据,则可以控制某个 IO 口的输出电平。该寄存器各位描述如下图所示:
2 硬件电路
LED与MM32的连接电路如下图所示,即可以通过配置PA8和PD2两个GPIO,来控制LED的状态。
3 软件实现
(1)初始化函数
void LED_Init(void)
{
RCC->APB2ENR|=RCC_APB2RSTR_IOPARST; //RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB2ENR|=RCC_APB2RSTR_IOPDRST; //RCC->APB2ENR|=1<<5; //使能PORTC时钟
GPIOA->CRH|=GPIO_CRH_MODE8; //GPIOA->CRH|=0X00000003;//PA8推挽输出
GPIOA->ODR|=GPIO_ODR_ODR8; // GPIOA->ODR|=1<<8; //PA8 输出高
GPIOD->CRL|=GPIO_CRL_MODE2; //GPIOD->CRL|=0X00000300; //PD.2推挽输出
GPIOD->ODR|=GPIO_ODR_ODR2; //GPIOD->ODR|=1<<2; //PD.2输出高
}
(2)宏定义
这个有点和STM32战舰V3的代码相似
//IO口操作,只对单一的IO口,确保n的值小于16
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n)
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n)
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n)
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n)
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n)
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n)
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n)
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n)
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n)
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n)
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n)
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n)
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n)
(3)主函数
int main(void)
{
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
LED0=0;
LED1=1;
delay_ms(1000);
LED0=1;
LED1=0;
delay_ms(1000);
}
}
4 实验效果