依旧从点灯开始先看原理图C_ELC0和C_ELC1是连接在M2和B12继电器是常开1、2号脚就是低压侧3、4号脚就是开关继电器是一种低压控制高压的元器件。低压侧是一个电磁铁高压侧是一个开关开关上面有弹簧默认是断开的。低压侧电磁铁通电就会吸引高压侧的永磁铁使开关闭合。也就是当ELC_0为高电平时螺旋管的电流导致磁铁通电使开关闭合当ELC_0为低电平时没有电流电磁铁不通电法一可以更好了解寄存器我现在要写实现引脚的函数要知道引脚的地址就得查数据手册我需要B引脚组和M引脚组我查我写//GPIO寄存器基地址 #define Addr_GPIOB_Base (0x40012000) #define Addr_GPIOM_Base (0x40015000) //DATA寄存器 #define Offset_GPIO_DATA (0X00) #define Offset_GPIO_DIR (0X04)和B引脚组与M引脚组有关的我都先写上//PORT寄存器基地址 #define Addr_PORT_Base (0x40010000)先不管后面会不会用得着我先写上//SEL寄存器 #define Offset_PORTB_SEL (0X04) #define Offset_PORTM_SEL0 (0X20) #define Offset_PORTM_SEL1 (0X24)//MUX寄存器 #define Offset_PORTB_MUX0 (0X110) #define Offset_PORTB_MUX1 (0X114) #define Offset_PORTM_MUX0 (0X160) #define Offset_PORTM_MUX1 (0X164) #define Offset_PORTM_MUX2 (0X168) #define Offset_PORTM_MUX3 (0X16C)//INEN寄存器 #define Offset_PORTB_INEN (0X610) #define Offset_PORTM_INEN (0X640)以上都是基地址和偏移量分开写现在该加到一块了直接得出引脚B组和引脚M组#define rPORTB_SEL (*(volatile unsigned int*) (Addr_PORT_Base Offset_PORTB_SEL) ) #define rPORTM_SEL0 (*(volatile unsigned int*) (Addr_PORT_Base Offset_PORTM_SEL0) ) #define rPORTM_SEL1 (*(volatile unsigned int*) (Addr_PORT_Base Offset_PORTM_SEL1) ) #define rGPIOB_DATA (*(volatile unsigned int*) (Addr_GPIOB_Base Offset_GPIO_DATA) ) #define rGPIOB_DIR (*(volatile unsigned int*) (Addr_GPIOB_Base Offset_GPIO_DIR) ) #define rGPIOM_DATA (*(volatile unsigned int*) (Addr_GPIOM_Base Offset_GPIO_DATA) ) #define rGPIOM_DIR (*(volatile unsigned int*) (Addr_GPIOM_Base Offset_GPIO_DIR) )(*(volatile unsigned int*) (Addr_PORT_Base Offset_PORTB_SEL))^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^│ │ ││ │ └─ 1. 计算地址│ └─ 2. 强制类型转换└─ 3. 解引用有了这些宏之后就可以编程初始化引脚为GPIO输出功能了我要写一个gpio_init_out函数配置好PM2和PB12两个引脚配置PB12:rPORTB_SEL ~(324);配置PM2rPORTM_SEL0 ~(34);设置引脚为输出置1为输出rGPIOB_DIR | (112);rGPIOM_DIR | (12 );关闭输入使能rPORTB_INEN ~(112);rPORTM_INEN ~(12);给PB12和PM2高电平写1rGPIOB_DATA | (112); //GPIO B12输出高电平rGPIOM_DATA | (12 ); //GPIO M2 输出高电平此函数完整版void gpio_init_out(void) { //1将引脚的基本属性设置为GPIO:B12和M2 设置功能为00 rPORTB_SEL ~(324); rPORTM_SEL0 ~(34); //2接通端口数据输出开关 rGPIOB_DIR | (112); rGPIOM_DIR | (12 ); //3关闭端口数据输入开关 rPORTB_INEN ~(112); rPORTM_INEN ~(12); //4往端口引脚写数据实现输出指定电平值 rGPIOB_DATA | (112); //GPIO B12输出高电平 rGPIOM_DATA | (12 ); //GPIO M2 输出高电平 }发现不起作用我们用到了PORTB外设和PORTM外设所有外设在使用前都要先给外设提供时钟修改gpio_init_out()函数先使能外设时钟再初始化查系统时钟基地址和使能偏移量#define Addr_SYSCON_Base 0x40000000 #define Offset_SYS_CLKEN (0x08) #define rSYS_CLKEN ( *(volatile unsigned int*)( Addr_SYSCON_Base Offset_SYS_CLKEN ) )使能B组和M组//使能外设时钟 B M rSYS_CLKEN | (11); rSYS_CLKEN | (14);所以完整版应该是#define Addr_SYSCON_Base 0x40000000 #define Offset_SYS_CLKEN (0x08) #define rSYS_CLKEN ( *(volatile unsigned int*)( Addr_SYSCON_Base Offset_SYS_CLKEN ) ) void gpio_init_out(void) { //使能外设时钟 B M rSYS_CLKEN | (11); rSYS_CLKEN | (14); //1将引脚的基本属性设置为GPIO:B12和M2 设置功能为00 rPORTB_SEL ~(324); rPORTM_SEL0 ~(34); //2接通端口数据输出开关 rGPIOB_DIR | (112); rGPIOM_DIR | (12 ); //3关闭端口数据输入开关 rPORTB_INEN ~(112); rPORTM_INEN ~(12); //4往端口引脚写数据实现输出指定电平值 rGPIOB_DATA | (112); //GPIO B12输出高电平 rGPIOM_DATA | (12 ); //GPIO M2 输出高电平 }也可以加上延时void delay_some_time(void) { volatile uint32_t d 0; d 10000000; while(d--); }和led_ctrl函数void led_ctrl( int pwr ) { if( 0 pwr ) { rGPIOB_DATA ~(112); //B12输出低电平 rGPIOM_DATA ~(12 ); //M2 输出低电平 } else { rGPIOB_DATA | (112); //B12输出高电平 rGPIOM_DATA | (12 ); //M2 输出高电平 } }main函数就为int main(void) { uint32_t chr; uint32_t err; SystemInit(); SerialInit(); printf(hello swm320\r\n); printf(cpu:%d\r\n,SystemCoreClock); //编程让某些引脚输出高电平 ELC0 M2 / ELC1 B12 gpio_init_out( 0 ); while(11) { led_ctrl( 1 ); delay_some_time(); led_ctrl( 0 ); delay_some_time(); } }法二使用官方SDK编程void led_ctrl( int pwr ) { if( 0 pwr ) { GPIO_ClrBit(GPIOB, PIN12); //设置输出0 GPIO_ClrBit(GPIOM, PIN2 ); //设置输出0 } else { GPIO_SetBit(GPIOB, PIN12); //设置输出1 GPIO_SetBit(GPIOM, PIN2 ); //设置输出1 } } void delay_some_time(void) { volatile uint32_t d 0; d 10000000; while(d--); } int main(void) { SystemInit(); //初始化B12 M2为输出功能 GPIO_Init(GPIOB, PIN12, 1, 0, 0); //输出 接LED GPIO_Init(GPIOM, PIN2 , 1, 0, 0); //输出 接LED while(11) { led_ctrl( 1 ); delay_some_time(); led_ctrl( 0 ); delay_some_time(); } }
【SWM320】学习使用GPIO
依旧从点灯开始先看原理图C_ELC0和C_ELC1是连接在M2和B12继电器是常开1、2号脚就是低压侧3、4号脚就是开关继电器是一种低压控制高压的元器件。低压侧是一个电磁铁高压侧是一个开关开关上面有弹簧默认是断开的。低压侧电磁铁通电就会吸引高压侧的永磁铁使开关闭合。也就是当ELC_0为高电平时螺旋管的电流导致磁铁通电使开关闭合当ELC_0为低电平时没有电流电磁铁不通电法一可以更好了解寄存器我现在要写实现引脚的函数要知道引脚的地址就得查数据手册我需要B引脚组和M引脚组我查我写//GPIO寄存器基地址 #define Addr_GPIOB_Base (0x40012000) #define Addr_GPIOM_Base (0x40015000) //DATA寄存器 #define Offset_GPIO_DATA (0X00) #define Offset_GPIO_DIR (0X04)和B引脚组与M引脚组有关的我都先写上//PORT寄存器基地址 #define Addr_PORT_Base (0x40010000)先不管后面会不会用得着我先写上//SEL寄存器 #define Offset_PORTB_SEL (0X04) #define Offset_PORTM_SEL0 (0X20) #define Offset_PORTM_SEL1 (0X24)//MUX寄存器 #define Offset_PORTB_MUX0 (0X110) #define Offset_PORTB_MUX1 (0X114) #define Offset_PORTM_MUX0 (0X160) #define Offset_PORTM_MUX1 (0X164) #define Offset_PORTM_MUX2 (0X168) #define Offset_PORTM_MUX3 (0X16C)//INEN寄存器 #define Offset_PORTB_INEN (0X610) #define Offset_PORTM_INEN (0X640)以上都是基地址和偏移量分开写现在该加到一块了直接得出引脚B组和引脚M组#define rPORTB_SEL (*(volatile unsigned int*) (Addr_PORT_Base Offset_PORTB_SEL) ) #define rPORTM_SEL0 (*(volatile unsigned int*) (Addr_PORT_Base Offset_PORTM_SEL0) ) #define rPORTM_SEL1 (*(volatile unsigned int*) (Addr_PORT_Base Offset_PORTM_SEL1) ) #define rGPIOB_DATA (*(volatile unsigned int*) (Addr_GPIOB_Base Offset_GPIO_DATA) ) #define rGPIOB_DIR (*(volatile unsigned int*) (Addr_GPIOB_Base Offset_GPIO_DIR) ) #define rGPIOM_DATA (*(volatile unsigned int*) (Addr_GPIOM_Base Offset_GPIO_DATA) ) #define rGPIOM_DIR (*(volatile unsigned int*) (Addr_GPIOM_Base Offset_GPIO_DIR) )(*(volatile unsigned int*) (Addr_PORT_Base Offset_PORTB_SEL))^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^│ │ ││ │ └─ 1. 计算地址│ └─ 2. 强制类型转换└─ 3. 解引用有了这些宏之后就可以编程初始化引脚为GPIO输出功能了我要写一个gpio_init_out函数配置好PM2和PB12两个引脚配置PB12:rPORTB_SEL ~(324);配置PM2rPORTM_SEL0 ~(34);设置引脚为输出置1为输出rGPIOB_DIR | (112);rGPIOM_DIR | (12 );关闭输入使能rPORTB_INEN ~(112);rPORTM_INEN ~(12);给PB12和PM2高电平写1rGPIOB_DATA | (112); //GPIO B12输出高电平rGPIOM_DATA | (12 ); //GPIO M2 输出高电平此函数完整版void gpio_init_out(void) { //1将引脚的基本属性设置为GPIO:B12和M2 设置功能为00 rPORTB_SEL ~(324); rPORTM_SEL0 ~(34); //2接通端口数据输出开关 rGPIOB_DIR | (112); rGPIOM_DIR | (12 ); //3关闭端口数据输入开关 rPORTB_INEN ~(112); rPORTM_INEN ~(12); //4往端口引脚写数据实现输出指定电平值 rGPIOB_DATA | (112); //GPIO B12输出高电平 rGPIOM_DATA | (12 ); //GPIO M2 输出高电平 }发现不起作用我们用到了PORTB外设和PORTM外设所有外设在使用前都要先给外设提供时钟修改gpio_init_out()函数先使能外设时钟再初始化查系统时钟基地址和使能偏移量#define Addr_SYSCON_Base 0x40000000 #define Offset_SYS_CLKEN (0x08) #define rSYS_CLKEN ( *(volatile unsigned int*)( Addr_SYSCON_Base Offset_SYS_CLKEN ) )使能B组和M组//使能外设时钟 B M rSYS_CLKEN | (11); rSYS_CLKEN | (14);所以完整版应该是#define Addr_SYSCON_Base 0x40000000 #define Offset_SYS_CLKEN (0x08) #define rSYS_CLKEN ( *(volatile unsigned int*)( Addr_SYSCON_Base Offset_SYS_CLKEN ) ) void gpio_init_out(void) { //使能外设时钟 B M rSYS_CLKEN | (11); rSYS_CLKEN | (14); //1将引脚的基本属性设置为GPIO:B12和M2 设置功能为00 rPORTB_SEL ~(324); rPORTM_SEL0 ~(34); //2接通端口数据输出开关 rGPIOB_DIR | (112); rGPIOM_DIR | (12 ); //3关闭端口数据输入开关 rPORTB_INEN ~(112); rPORTM_INEN ~(12); //4往端口引脚写数据实现输出指定电平值 rGPIOB_DATA | (112); //GPIO B12输出高电平 rGPIOM_DATA | (12 ); //GPIO M2 输出高电平 }也可以加上延时void delay_some_time(void) { volatile uint32_t d 0; d 10000000; while(d--); }和led_ctrl函数void led_ctrl( int pwr ) { if( 0 pwr ) { rGPIOB_DATA ~(112); //B12输出低电平 rGPIOM_DATA ~(12 ); //M2 输出低电平 } else { rGPIOB_DATA | (112); //B12输出高电平 rGPIOM_DATA | (12 ); //M2 输出高电平 } }main函数就为int main(void) { uint32_t chr; uint32_t err; SystemInit(); SerialInit(); printf(hello swm320\r\n); printf(cpu:%d\r\n,SystemCoreClock); //编程让某些引脚输出高电平 ELC0 M2 / ELC1 B12 gpio_init_out( 0 ); while(11) { led_ctrl( 1 ); delay_some_time(); led_ctrl( 0 ); delay_some_time(); } }法二使用官方SDK编程void led_ctrl( int pwr ) { if( 0 pwr ) { GPIO_ClrBit(GPIOB, PIN12); //设置输出0 GPIO_ClrBit(GPIOM, PIN2 ); //设置输出0 } else { GPIO_SetBit(GPIOB, PIN12); //设置输出1 GPIO_SetBit(GPIOM, PIN2 ); //设置输出1 } } void delay_some_time(void) { volatile uint32_t d 0; d 10000000; while(d--); } int main(void) { SystemInit(); //初始化B12 M2为输出功能 GPIO_Init(GPIOB, PIN12, 1, 0, 0); //输出 接LED GPIO_Init(GPIOM, PIN2 , 1, 0, 0); //输出 接LED while(11) { led_ctrl( 1 ); delay_some_time(); led_ctrl( 0 ); delay_some_time(); } }