亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
怎么給STM32 GPIO多個操作不影響其他的?
[打印本頁]
作者:
豬腳
時間:
2019-3-8 12:20
標題:
怎么給STM32 GPIO多個操作不影響其他的?
怎么給GPIO多個操作位不影響其他的;像GPIOE->ODR = dat<<5;
這樣會影響低五位。
請問有什么好的方法?
作者:
lfc315
時間:
2019-3-8 12:20
是不是應該還有屏的頭文件*.h之類的,在里面定義了顯示方向
作者:
zhanghyg
時間:
2019-3-9 11:30
一位一位賦值
作者:
的花朵
時間:
2019-3-10 17:38
GPIOE->ODR| = (uint32_t)1<<5;應該是這樣的吧
作者:
yfpc2006
時間:
2019-3-11 15:52
STM32的16位端口輸出8位數據方法
u16 temp;
u8 yourdata;
temp=GPIOA->ODR&0xff00;
temp+=yourdata;
GPIOA->ODR=temp;
或者:GPIOA->ODR=GPIOA->ODR&0xff00+(u16)yourdata;
=======================================================
先定義宏:
#define GPIO_SETLOWBITS(GPIOA,UINT8) GPIOA->ODR = ((GPIOA->ODR)&0xFF00) + UINT8
調用:
GPIO_SETLOWBITS(GPIOA,0xaa);
GPIO_SETLOWBITS(GPIOA,0x55);
=====================================================
最通用的方法是讀-修改-寫
因為對于STM32,IO操作比寄存器操作慢得多,所以我常用這樣的寫法:
GPIOA->BSRR=data|((data^0xff)<<16);
作者:
yfpc2006
時間:
2019-3-11 15:53
用GPIOx_BSRR寄存器
BRy位寫0無影響寫1復位相應bit位
BSy位寫0無影響寫1置位相應bit位
例如要對PORTA口低8位送出D0-D7數據,而不觸及高8位的數據:
假定要送出D0-D7的數據變量為ldata,
unsigned char ldata;
GPIOA_BSRR = ((unsigned int)~ldata << 16) | ldata;
如果ldata=0x34,這相當于設置:
GPIOA_BSRR=0x00CB0034;
作者:
yfpc2006
時間:
2019-3-11 15:54
據官方數據手冊上面說, 這兩個寄存器用于專門對ODR進行原子操作的位操作, 都是在置1的時候對某位有影響.
舉例說下怎么對IO端口賦值:
1.對高8位/低8位/全部清零
很明顯, 這個只需要操作BRR寄存器即可:
對高8位清零:GPIOA->BRR = 0xFF00
對低8位清零:GPIOA->BRR = 0x00FF
全部清零: GPIOA->BRR = 0xFFFF 或 GPIOA->ODR = 0x0000
當然了, 使用下面2,3的兩個宏也可以完全該清零操作~ stm32固件庫是不是應該加上這兩個宏/函數?
2.對低8位置數
涉及到置數, 這個就是操作BSRR寄存器了
比如要使端口A的低8位為 0x55 (01010101B), 那么對于BSRR這個32位寄存器來說:
低16位應該置為 0000 0000 0101 0101, 這個就等于 0x55, 置1使某位為1, 置0的位不影響原來的值
高16位應該置為 0000 0000 1010 1010, 這個就等于 ~0x55(即取反)的結果, 置1使某位為0, 置0不影響原來的值
這樣, BSRR寄存器的值就是 0000 0000 1010 1010 0000 0000 0101 0101, 兩部分的高8位均為0, 所以不會影響到IO口的高8位
總結, 以下的宏實現對某端口的低8位置數, 不影響高8位:
#define GPIO_WriteLow(GPIOx,a) GPIOx->BSRR=(((uint32_t)(uint8_t)~(a))<<16)|((uint32_t)(uint8_t)(a))
3.對高8位置數
這個和單獨對低8位置數其實是一樣的, 只是設置的位不一樣罷了
同樣, 要使高8位為0x55, 那么:
低16位應該置為 0101 0101 0000 0000
高16位應該置為 1010 1010 0000 0000, 同樣是取反的結果; 不影響低8位的數據
這樣, BSRR寄存器的值就是 1010 1010 0000 0000 0101 0101 0000 0000, 可以看出, 其實它就是上面那個結果左移8位
總結, 以下的宏實現對某端口的高8位置數, 不影響低8位:
#define GPIO_WriteHigh(GPIOx,a) GPIOx->BSRR=(((uint8_t)(uint8_t)~(a))<<24)|(((uint32_t)(uint8_t)(a))<<8)
大家不用擔心效率問題, 上面那兩個宏最終的結果就是 GPIOx->BSRR=value 的形式, 所以擔心是多余的
作者:
yfpc2006
時間:
2019-3-11 15:55
怎么對高八位或低八位寫值而不影響其它位,還有怎樣單獨讀取高八位或低八位的值?
((u8*)(&GPIOB->ODR))[0] = 0xaa;寫低八位
g_io_tempvalue = ((u8*)(&GPIOB->ODR))[1];讀高八位
=============================================
寫高八位
GPIOB->CRH &= 0X00000000;
GPIOB->CRH |= 0X33333333;
GPIOB->ODR |= 0XFF00;
低八位也一樣,做與或者或運算的時候就可以避免影響不想改變的位。
讀高八位:
u8 temp;
temp = ((GPIOB->IDR>>8)&0xff)
讀低八位
temp = ((GPIOB->IDR&0xff)
====
使用BSRR和BRR寄存器直接操作STM32的I/O端口 發布時間:2009-11-12 12:39:27
技術類別:單片機
STM32的每個GPIO端口都有兩個特別的寄存器,GPIOx_BSRR和GPIOx_BRR寄存器,通過這兩個寄存器可以直接對對應的GPIOx端口置'1'或置'0'。
GPIOx_BSRR的高16位中每一位對應端口x的每個位,對高16位中的某位置'1'則端口x的對應位被清'0';寄存器中的位置'0',則對它對應的位不起作用。
GPIOx_BSRR的低16位中每一位也對應端口x的每個位,對低16位中的某位置'1'則它對應的端口位被置'1';寄存器中的位置'0',則對它對應的端口不起作用。
簡單地說GPIOx_BSRR的高16位稱作清除寄存器,而GPIOx_BSRR的低16位稱作設置寄存器。另一個寄存器GPIOx_BRR只有低16位有效,與GPIOx_BSRR的高16位具有相同功能。
舉個例子說明如何使用這兩個寄存器和所體現的優勢。例如GPIOE的16個IO都被設置成輸出,而每次操作僅需要改變低8位的數據而保持高8位不變,假設新的8位數據在變量Newdata中,
這個要求可以通過操作這兩個寄存器實現,STM32的固件庫中有兩個函數GPIO_SetBits()和GPIO_ResetBits()使用了這兩個寄存器操作端口。
上述要求可以這樣實現:
GPIO_SetBits(GPIOE, Newdata & 0xff);
GPIO_ResetBits(GPIOE, (~Newdata & 0xff));
也可以直接操作這兩個寄存器:
GPIOE->BSRR = Newdata & 0xff;
GPIOE->BRR = ~Newdata & 0xff;
當然還可以一次完成對8位的操作:
GPIOE->BSRR = (Newdata & 0xff) | (~Newdata & 0xff)<<16;
從最后這個操作可以看出使用BSRR寄存器,可以實現8個端口位的同時修改操作。
//==============================================================================================
如果不是用BRR和BSRR寄存器,則上述要求就需要這樣實現:
GPIOE->ODR = GPIOE->ODR & 0xff00 | Newdata; 低8位 ; //更新低8位,高8位不變
GPIOE->ODR = ((GPIOE->ODR & 0xff00) | (uint16_t)(Newdata<<8)); 高8位//更新高8位,低8位不變
平時用的比較多.
//===================================================================================================
使用BRR和BSRR寄存器可以方便地快速地實現對端口某些特定位的操作,而不影響其它位的狀態。
比如希望快速地對GPIOE的位7進行翻轉,則可以:
GPIOE->BSRR = 0x80; // 置'1'
GPIOE->BRR = 0x80; // 置'0'
如果使用常規'讀-改-寫'的方法:
GPIOE->ODR = GPIOE->ODR | 0x80; // 置'1'
GPIOE->ODR = GPIOE->ODR & 0xFF7F; // 置'0'
有人問是否BSRR的高16位是多余的,請看下面這個例子:
假如你想在一個操作中對GPIOE的位7置'1',位6置'0',則使用BSRR非常方便:
GPIOE->BSRR = 0x400080;
如果沒有BSRR的高16位,則要分2次操作,結果造成位7和位6的變化不同步!
GPIOE->BSRR = 0x80;
GPIOE->BRR = 0x40;
=========================================
例如要對PORTA口低8位送出D0-D7數據,而不觸及高8位的數據:
假定要送出D0-D7的數據變量為ldata,
unsigned char ldata;
GPIOA_BSRR = ((unsigned int)~ldata << 16) | ldata;
如果ldata=0x34,這相當于設置:
GPIOA_BSRR=0x00CB0034;
===================================
先定義宏:
#define GPIO_SETLOWBITS(GPIOA,UINT8) GPIOA->ODR = ((GPIOA->ODR)&0xFF00) + UINT8
調用:
GPIO_SETLOWBITS(GPIOA,0xaa);
GPIO_SETLOWBITS(GPIOA,0x55);
=================================================
STM32 GPIO寄存器ODR BSRR BRR
使用BRR和BSRR寄存器可以方便地快速地實現對端口某些特定位的操作,而不影響其它位的狀態。
比如希望快速地對GPIOE的位7進行翻轉,則可以:
GPIOE->BSRR = 0x80; // 置'1'
GPIOE->BRR = 0x80; // 置'0'
如果使用常規'讀-改-寫'的方法:
GPIOE->ODR = GPIOE->ODR | 0x80; // 置'1'
GPIOE->ODR = GPIOE->ODR & 0xFF7F; // 置'0'
有人問是否BSRR的高16位是多余的,請看下面這個例子:
假如你想在一個操作中對GPIOE的位7置'1',位6置'0',則使用BSRR非常方便:
GPIOE->BSRR = 0x00400080;
如果沒有BSRR的高16位,則要分2次操作,結果造成位7和位6的變化不同步!
GPIOE->BSRR = 0x80;
GPIOE->BRR = 0x40;
規則:
一、置GPIOD->BSRR低16位的某位為'1',則對應的I/O端口置'1';而置GPIOD->BSRR低16位
的某位為'0',則對應的I/O端口不變。
二、置GPIOD->BSRR高16位的某位為'1',則對應的I/O端口置'0';而置GPIOD->BSRR高16位
的某位為'0',則對應的I/O端口不變。
三、置GPIOD->BRR低16位的某位為'1',則對應的I/O端口置'0';而置GPIOD->BRR低16位的
某位為'0',則對應的I/O端口不變。
例如:
1)要設置D0、D5、D10、D11為高,而保持其它I/O口不變,只需一行語句:
GPIOD->BSRR = 0x0C21;// 使用規則一
2)要設置D1、D3、D14、D15為低,而保持其它I/O口不變,只需一行語句:
GPIOD->BRR = 0xC00A;// 使用規則三
3)要同時設置D0、D5、D10、D11為高,設置D1、D3、D14、D15為低,而保持其它I/O口不變
,也只需一行語句:
GPIOD->BSRR = 0xC00A0C21;// 使用規則一和規則二
如果中斷中要對IO口設置,最好使用BSRR和BRR操作,而不要用ODR .
作者:
Angle145
時間:
2019-3-11 20:41
位或|了解一下
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1