一、位帶的文檔介紹
STM32F407的位帶操作可以實現(xiàn)類似51單片機中寄存器的操作方法,操作GPIO口代碼簡潔方便。 關(guān)于位段的操作在Cortex-M3M4權(quán)威指南里有詳細描述:
支持位帶操作后,可以使用普通的加載/存儲指令來對單一的比特位進行讀寫。
在CM3位帶區(qū)中,有兩個區(qū)中實現(xiàn)了位帶。 其中一個是 SRAM 區(qū)的最低 1MB 范圍,第二個則是片內(nèi)外設(shè)區(qū)的最低 1MB 范圍。 這兩個區(qū)中的地址除了可以像普通的 RAM 一樣使用外,它們還都有自己的“位帶別名區(qū)”,位帶別名區(qū)把每個比特膨脹成一個 32 位的字。當你通過位帶別名區(qū)訪 問這些字時,就可以達到訪問原始比特位的目的。
二、位帶實現(xiàn)代碼
Sys.c文件增加以下代碼:
#define GPIOA_IDR (0x40020000+0x10)
#define GPIOA_ODR (0x40020000+0x14)
#define GPIOB_IDR (0x40020400+0x10)
#define GPIOB_ODR (0x40020400+0x14)
#define GPIOC_IDR (0x40020800+0x10)
#define GPIOC_ODR (0x40020800+0x14)
#define GPIOD_IDR (0x40020C00+0x10)
#define GPIOD_ODR (0x40020C00+0x14)
#define GPIOE_IDR (0x40021000+0x10)
#define GPIOE_ODR (0x40021000+0x14)
#define GPIOF_IDR (0x40021400+0x10)
#define GPIOF_ODR (0x40021400+0x14)
#define GPIOG_IDR (0x40021800+0x10)
#define GPIOG_ODR (0x40021800+0x14)
#define GPIOH_IDR (0x40021C00+0x10)
#define GPIOH_ODR (0x40021C00+0x14)
//把“位帶地址+位序號”轉(zhuǎn)換成別名地址的宏
#define BITBAND(addr,bitnum) ((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
//把該地址轉(zhuǎn)換成一個指針
#define MEM_ADDR(addr) *((volatile unsigned long *) (addr))
#define PAout(x) MEM_ADDR(BITBAND(GPIOA_ODR,x))
#define PAin(x) MEM_ADDR(BITBAND(GPIOA_IDR,x))
#define PBout(x) MEM_ADDR(BITBAND(GPIOB_ODR,x))
#define PBin(x) MEM_ADDR(BITBAND(GPIOB_IDR,x))
#define PCout(x) MEM_ADDR(BITBAND(GPIOC_ODR,x))
#define PCin(x) MEM_ADDR(BITBAND(GPIOC_IDR,x))
#define PDout(x) MEM_ADDR(BITBAND(GPIOD_ODR,x))
#define PDin(x) MEM_ADDR(BITBAND(GPIOD_IDR,x))
#define PEout(x) MEM_ADDR(BITBAND(GPIOE_ODR,x))
#define PEin(x) MEM_ADDR(BITBAND(GPIOE_IDR,x))
#define PFout(x) MEM_ADDR(BITBAND(GPIOF_ODR,x))
#define PFin(x) MEM_ADDR(BITBAND(GPIOF_IDR,x))
#define PGout(x) MEM_ADDR(BITBAND(GPIOG_ODR,x))
#define PGin(x) MEM_ADDR(BITBAND(GPIOG_IDR,x))
#define PHin(x) MEM_ADDR(BITBAND(GPIOH_IDR,x))
#define PHout(x) MEM_ADDR(BITBAND(GPIOH_ODR,x))
復(fù)制代碼
Led.h 增加位帶操作代碼
#define LED0 PFout(9)
#define LED1 PFout(10)
#define BEEP PFout(8)
復(fù)制代碼
Key.h增加位帶操作代碼
#define KEY0 PEin(4)
#define KEY1 PEin(3)
#define KEY2 PEin(2)
#define KEY_UP PAin(0)
復(fù)制代碼
Main.c示例代碼
#include "stm32f4xx.h" // Device header
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include "sys.h"
int main(void)
{
u8 i,key;
LED_Init();
KEY_Init();
USART1_Init(84,115200);
while(1)
{
key=ScanKeyVal(0);
if(key)
{
i=!i;
LED0=!LED0;
LED1=!LED1;
}
}
}
復(fù)制代碼
三、DS18B20溫度傳感器示例-位帶控制實現(xiàn)時序
#include "ds18b20.h"
/*
函數(shù)功能: 硬件初始化--IO配置
硬件連接: PB15
*/
void DS18B20_Init(void)
{
/*1. 開時鐘*/
RCC->APB2ENR|=1<<3; //PB
/*2. 配置GPIO口模式*/
GPIOB->CRH&=0x0FFFFFFF;
GPIOB->CRH|=0x30000000;
/*3. 上拉*/
GPIOB->ODR|=1<<15;
}
/*
函數(shù)功能: 發(fā)送復(fù)位脈沖檢測DS18B20硬件--建立通信過程
返 回 值: 0表示成功 1表示失敗
*/
u8 DS18B20_Check(void)
{
u8 i;
DS18B20_OUT_MODE(); //配置IO口為輸出模式
DS18B20_OUT=0; //拉低
delay_us(580);
DS18B20_OUT=1; //拉高
DS18B20_IN_MODE(); //配置IO口為輸入模式
for(i=0;i<100;i++)
{
if(DS18B20_IN==0)break;
delay_us(1);
}
if(i==100)return 1;
for(i=0;i<250;i++)
{
if(DS18B20_IN)break;
delay_us(1);
}
if(i==250)return 1;
return 0;
}
/*
函數(shù)功能: DS18B20寫一個字節(jié)數(shù)據(jù)
*/
void DS18B20_WriteOnebyte(u8 cmd)
{
u8 i;
DS18B20_OUT_MODE(); //輸出模式
for(i=0;i<8;i++)
{
if(cmd&0x01) //發(fā)送1
{
DS18B20_OUT=0;
delay_us(15);
DS18B20_OUT=1;
delay_us(45);
DS18B20_OUT=1;
delay_us(2);
}
else //發(fā)送0
{
DS18B20_OUT=0;
delay_us(15);
DS18B20_OUT=0;
delay_us(45);
DS18B20_OUT=1;
delay_us(2);
}
cmd>>=1;
}
}
/*
函數(shù)功能: DS18B20讀一個字節(jié)數(shù)據(jù)
*/
u8 DS18B20_ReadOnebyte(void)
{
u8 i;
u8 data=0;
for(i=0;i<8;i++)
{
DS18B20_OUT_MODE(); //輸出模式
DS18B20_OUT=0;
delay_us(2);
DS18B20_IN_MODE();
delay_us(8);
data>>=1; //右移1位
if(DS18B20_IN)data|=0x80;
delay_us(50);
DS18B20_OUT=1;
delay_us(2);
}
return data;
}
/*
函數(shù)功能: 讀取一次DS18B20的溫度數(shù)據(jù)
返回值: 讀取的溫度數(shù)據(jù)高低位
*/
u16 DS18B20_ReadTemp(void)
{
u16 temp;
u8 t_L,t_H;
if(DS18B20_Check())return 1;
DS18B20_WriteOnebyte(0xCC); //跳躍 ROM 指令 --不驗證身份
DS18B20_WriteOnebyte(0x44); //發(fā)送溫度轉(zhuǎn)換指令
if(DS18B20_Check())return 2;
DS18B20_WriteOnebyte(0xCC); //跳躍 ROM 指令 --不驗證身份
DS18B20_WriteOnebyte(0xBE); //讀取RAM里的數(shù)據(jù)
//讀取溫度
t_L=DS18B20_ReadOnebyte(); //低字節(jié)
t_H=DS18B20_ReadOnebyte(); //高字節(jié)
temp=t_H<<8|t_L;
return temp;
}
審核編輯:湯梓紅
-
溫度傳感器
+關(guān)注
關(guān)注
48文章
2940瀏覽量
156015 -
DS18B20
+關(guān)注
關(guān)注
10文章
779瀏覽量
80822 -
STM32F407
+關(guān)注
關(guān)注
15文章
187瀏覽量
29436
發(fā)布評論請先 登錄
相關(guān)推薦
評論