01、【正点原子】sys.c、sys.h位带操作的简单应用
生活随笔
收集整理的這篇文章主要介紹了
01、【正点原子】sys.c、sys.h位带操作的简单应用
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
目錄
- 一、前言
- 二、個人理解
- 三、代碼呈現(xiàn)
一、前言
由于本人跟著江科大自化協(xié)學習stm32c8t6最小系統(tǒng)板,在瀏覽其他人代碼的時候,發(fā)現(xiàn)大佬都喜歡使用位帶操作,通過正點原子官方視頻學習之后,發(fā)現(xiàn)這就是庫函數(shù)的一種使用。
二、個人理解
位帶操作主要是對GPIO口的操作,是將一些寄存器地址通過封裝、映射,使之形成與51單片機類似的寄存器操作,但之前也同樣需要對IO進行初始化。
三、代碼呈現(xiàn)
本代碼截取于正點原子的戰(zhàn)艦v3(也是精英版的)第十五講-手把手編寫跑馬燈實驗-位操作
sys.c 這個可以先不研究
#include "sys.h"// //本程序只供學習使用,未經(jīng)作者許可,不得用于其它任何用途 //ALIENTEK Mini STM32開發(fā)板 //系統(tǒng)中斷分組設置化 //正點原子@ALIENTEK //技術論壇:www.openedv.com //修改日期:2012/9/10 //版本:V1.4 //版權所有,盜版必究。 //Copyright(C) 正點原子 2009-2019 //All rights reserved //******************************************************************************** //THUMB指令不支持匯編內(nèi)聯(lián) //采用如下方法實現(xiàn)執(zhí)行匯編指令WFI void WFI_SET(void) {__ASM volatile("wfi"); } //關閉所有中斷 void INTX_DISABLE(void) { __ASM volatile("cpsid i"); } //開啟所有中斷 void INTX_ENABLE(void) {__ASM volatile("cpsie i"); } //設置棧頂?shù)刂?/span> //addr:棧頂?shù)刂?/span> __asm void MSR_MSP(u32 addr) {MSR MSP, r0 //set Main Stack valueBX r14 }sys.h 這個就重要了
#ifndef __SYS_H #define __SYS_H #include "stm32f10x.h" // //本程序只供學習使用,未經(jīng)作者許可,不得用于其它任何用途 //ALIENTEK STM32開發(fā)板 //正點原子@ALIENTEK //技術論壇:www.openedv.com //修改日期:2012/8/18 //版本:V1.7 //版權所有,盜版必究。 //Copyright(C) 廣州市星翼電子科技有限公司 2009-2019 //All rights reserved // //0,不支持ucos //1,支持ucos #define SYSTEM_SUPPORT_OS 0 //定義系統(tǒng)文件夾是否支持UCOS//位帶操作,實現(xiàn)51類似的GPIO控制功能 //具體實現(xiàn)思想,參考<<CM3權威指南>>第五章(87頁~92頁). //IO口操作宏定義 #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) //addr 地址 bit 比特 #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //IO口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //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) //輸入//以下為匯編函數(shù) void WFI_SET(void); //執(zhí)行WFI指令 void INTX_DISABLE(void);//關閉所有中斷 void INTX_ENABLE(void); //開啟所有中斷 void MSR_MSP(u32 addr); //設置堆棧地址#endif即使是位操作,也少不了IO口調(diào)用時鐘和初始化,說白了,就是講庫函數(shù)里面的GPIO_SetBits、GPIO_ResetBits分別用0、1替換
下面獻上代碼:
main.c
這是在led.c里面的初始化
#include "led.h"// //本程序只供學習使用,未經(jīng)作者許可,不得用于其它任何用途 //ALIENTEK戰(zhàn)艦STM32開發(fā)板 //LED驅(qū)動代碼 //正點原子@ALIENTEK //技術論壇:www.openedv.com //修改日期:2012/9/2 //版本:V1.0 //版權所有,盜版必究。 //Copyright(C) 廣州市星翼電子科技有限公司 2009-2019 //All rights reserved // //初始化PB5和PE5為輸出口.并使能這兩個口的時鐘 //LED IO初始化 void LED_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口時鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); //根據(jù)設定參數(shù)初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 輸出高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 端口配置, 推挽輸出GPIO_Init(GPIOE, &GPIO_InitStructure); //推挽輸出 ,IO口速度為50MHzGPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 輸出高 }總結(jié)
以上是生活随笔為你收集整理的01、【正点原子】sys.c、sys.h位带操作的简单应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Antd DatePicker之旬查询(
- 下一篇: 【2022/01/21】thinkphp