STM32单片机的重映射与地址映射的使用方法及步骤
- 格式:doc
- 大小:17.00 KB
- 文档页数:3
关于STM32 中断向量表的位置、重定向问题首先我们需要跳到main 函数,这个就不多说了。
那么,中断发生后,又是怎么跑到中断入口地址的呢?从stm32f10x.s 可以看到,已经定义好了一大堆的中断响应函数,这就是中断向量表,标号__Vectors,表示中断向量表入口地址,例如:AREA RESET, DATA, READONLY ; 定义只读数据段,实际上是在CODE 区(假设STM32 从FLASH 启动,则此中断向量表起始地址即为0x8000000)EXPORT __Vectors IMPORT OS_CPU_SysTickHandler IMPORT OS_CPU_PendSVHandler__Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler 这个向量表的编写是有讲究的,跟硬件一一对应不能乱写的,CPU 找入口地址就靠它了,bin 文件开头就是他们的地址,参考手册RM0008 的10.1.2 节可以看到排列。
我们再结合CORTEX-M3的特性,他上电后根据boot 引脚来决定PC 位置,比如boot 设置为flash 启动,则启动后PC 跳到0x08000000。
此时CPU 会先取2 个地址,第一个是栈顶地址,第二个是复位异常地址,故有了上面的写法,这样就跳到reset_handler。
那么这个reset_handler 的实际地址是多少.?下面的一堆例如Nmi_handler 地址又是多少呢?发生中断是怎么跑到这个地址的呢?下面挨个讲解。
STM32的功能引脚重映射和复用功能STM32中有很多内置外设的输入输出引脚都具有重映射(remap)的功能,本文对一些在使用引脚重映射时所遇到的有关问题加以说明。
我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出脚位都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在STM32中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的脚位外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的脚位。
下面是STM32F103xC中有关USART3引脚的摘要片段;从这里可以看出,USART3_TX的默认引出脚是PB10,USART3_RX的默认引出脚是PB11;但经过重映射后,可以变更USART3_TX的引出脚为PD8,变更USART3_RX的引出脚为PD9。
STM32中的很多内置外设都具有重映射的功能,比如USART、定时器、CAN、SPI、I2C等,详细请看STM32参考手册(RM0008)和STM32数据手册。
有些模块(内置外设)的重映射功能还可以有多种选择,下面是RM0008上有关USART3输入输出引脚的重映射功能表:从这个表中可以看出,USART3的TX和RX引脚默认的引出脚位是PB10和PB11,根据配置位的设置,可以重映射到PC10和PC11,还可以重映射到PD8和PD9。
一个模块的功能引脚不管是从默认的脚位引出还是从重映射的脚位引出,都要通过GPIO端口模块实现,相应的GPIO端口必须配置为输入(对应模块的输入功能,如USART的RX)或复用输出(对应模块的输出功能,如USART的TX),对于输出引脚,可以按照需要配置为推挽复用输出或开漏复用输出。
上图是STM32的GPIO端口模块,使用复用功能时的配置。
从图中可以看出,配置为复用输出时,该端口对应的GPIO输出功能将不起作用。
例如当配置PB10对应的引脚为复用输出功能时,操作PB10对应的输出寄存器将不影响引脚上的信号。
STM32端口复用和端口重映射?什么是端口复用重映射?对于(单片机)而言,GPIO引脚配置是最基本的,也是最重要的,因为所有的((信号))输入和(控制)输出都是通过这些配置起作用的。
这里就不得不提到单片机的复用功能AF(Al(te)rnate Func(ti)on),这篇文章我们说一说复用功能。
(STM32)Fxx系列单片机的GPIO可以配置为浮空输入(input floating)、上拉输入(input pull-up)、下拉输入(input pull-down)、(模拟)输入((analog))、开漏输出(output open-drain)、推挽输出(ouput push-pull)、复用开漏输出(alternate function open-drain)、复用推挽输出(alternate function push-pull)等8种模式。
先说明一下开漏输出和推挽输出的区别。
STM32Fxx系列单片机的输出电路由两个MOS管,分别是P-MOS 和N-MOS。
在开漏输出模式下,P-MOS管不工作,只有N-MOS管工作。
若输入数据(寄存器)的值为0,则N-MOS导通,IO口输出低电平;若输出数据寄存器的值为1,则N-MOS截止;由于P-MOS不工作,此时IO口既不是高电平,也不是低电平,这种状态被称为高阻态。
STM32F1xx IO口基本结构在推挽输出模式下,若输出数据寄存器的值为0,则N-MOS导通,P-MOS截止,IO口输出低电平;若输出数据寄存器的值为1,则N-MOS截止,P-MOS导通,IO口输出高电平。
上面提到了STM32Fxx系列单片机还有复用开漏输出和复用推挽输出,它们和上面讲到的(通用)开漏输出和(普通)推挽输出有什么区别?这就涉及到引脚复用的功能。
使用过单片机的(工程师)都了解,STM32Fxx内部集成了很多的外设(控制器),比如USART、SPI、(CAN)等,这些外设控制器,也需要通过引脚与外设连接。
STM32引脚列表中主功能,默认复用功能和重定义功能的区别STM32F103RCT6引脚功能及使用1 主功能就是STM32基本IO口,与外设没有连接的,我们可以直接输出或读入高低电平使用时采用要初始化GPIO结构体参数,并打开端口的时钟2 默认复用功能是与外设连接的IO口,单片机通过控制IO口控制外设。
使用时采用要初始化GPIO结构体参数,IO口的工作模式要更具STM32中文参考手册中,IO口复用功能的设置工作模式,设置时,与主功能的唯一区别就是IO口的工作模式的不同。
3 当我想把外设不连接到默认引脚上,那就根据“重定义功能”这一列来重新定义外设连接的IO口。
一般情况我们不会用到。
注意:一旦需要对AFIO寄存器配置时,一定要打开AFIO的时钟(一般在使用外部中断EXTI或外设引脚重定义时)--------------------- 转载----------------------------STM32F103RCT6引脚功能及使用说明:1) VBAT:VBAT给RTC和备份区域供电,目的是在VDD断电时保证相关区域的数据内容有效,一般连接到外部电池。
若不用此功能,可直接连接到VDD。
2) 供电方案:Ø每个VDD各接一个0.1uF陶瓷电容,VDD3需要再接一个4.7~10uF的钽电容;Ø VDDA:10nF陶瓷电容+1nF钽电容;ØVREF+:可接VDDA,也可接外部参考源,此时,需要接10nF陶瓷电容+1nF钽电容;3) PC13/PC14/PC15:内部连接了模拟开关,只能通过少量的电流,驱动能力不够(不能用于点亮LED),且不能同时使用,尽量不用。
4) 进入待机模式之后,PA0-WKUP引脚上的上升沿,作为待机模式唤醒条件。
5) USART:CTS/RTS/CK/TX/RX,一般只使用TX/RX引脚实现异步通信,加上CK可以实现同步通信,CTS/RTS是硬件流控引脚,一般不用。
STM32部分重映射和完全重映射(查看数据⼿册)
数据⼿册如何查找对应的映射:
打开官⽹直接搜索STM32F可以看到数据⼿册,⾥⾯有关于,输⼊第6页的页码,点击9.3中的9.3x可打开对应的链接。
举例说明:
STM32中拥有重映射功能,可以使硬件电路的设计更加简洁⽅便,在配置GPIO_PinRemapConfig()函数时,发现⼊⼝参数有两种重映射,分为部分重映射(Partial Remap)和完全重映射(Full Remap),那么这两个有什么区别呢?
标题以TIM3为例
根据图⽚可以看到,TIM3的部分重映射和完全重映射对应的引脚是不同的,所以在配置选择部分重映射和完全重映射的时候要考虑⼀下。
重映射引脚分配图在哪
这⼀部分其实并不在STM32的数据⼿册中,⽽在STM32的官⽅⼿册的8.3节,⾥⾯有所有功能的引脚分配情况。
如何配置STM32F103的重映射USART分类:学习笔记2012-12-26 10:18 136人阅读评论(0) 收藏举报STM32stm32USART重映射这两天用STM32F103操作MC39i,其中用到STM32的重映射串口3,部分重映射到PC10、PC11上。
经参考了正点原子的《STM32不完全手册》并查看手册,调试成功讲解如下,如有不足欢迎指正。
经查找手册见下图:此时配置串口步骤如下:1.开启辅助时钟:RCC->APB2ENR|=1<<0;2.配置重映射寄存器,请串口3部分映射到PC口上:AFIO->MAPR|=1<<4;//USART3_REMAP[1:0]=0B01;3.使能PC口和串口:RCC->APB2ENR|=1<<4; //使能PORTC口时钟RCC->APB1ENR|=1<<18; //使能串口时钟4.配置IO口的状态:GPIOC->CRH=0X44444B44;//IO状态设置PC10/PC115.复位串口:RCC->APB1RSTR|=1<<18; //复位串口1RCC->APB1RSTR&=~(1<<18);//停止复位6.设置波特率和传输方式:USART3->BRR、USART3->CR1。
7.配置接受中断和中的优先级:USART3->CR1|=1<<8; //PE中断使能USART3->CR1|=1<<5; //接收缓冲区非空中断使能MY_NVIC_Init(2,3,USART1_IRQChannel,2);//组2,最低优先级至此配置完成。
备注:串口管脚配置见下图。
STM32的SPI1引脚重映射初次使用STM32有些不太明白,此次调试经验奉献出来与大家分享!系统:STM32 + SD + FA TFSSTM32与SD卡的连接如下定义,PB口#define SD_SCK GPIO_Pin_3#define SD_MISO GPIO_Pin_4#define SD_MOSI GPIO_Pin_5#define SD_CS GPIO_Pin_7我想使用SPI1并重映射引脚使用时注意的事项如下:1.使能PB0时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);2.使能AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);3.使能SPI1时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 , ENABLE);4.禁用JTAG时钟复用 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);5.SPI1引脚重映射 GPIO_PinRemapConfig(GPIO_Remap_SPI1,ENABLE);接着初始化GPIO和SPI1即可,如:void SpiOpen(void){GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;/* Configure SPI1 pins: SCKand MOSI */GPIO_InitStructure.GPIO_Pin = SD_MOSI|SD_SCK|SD_MISO;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);/* Configure PB7 pin: CS pin */GPIO_InitStructure.GPIO_Pin = SD_CS;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,SD_CS);/* SPI1 Config */SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(SPI1, &SPI_InitStructure);/* SPI1 enable */SPI_Cmd(SPI1, ENABLE);}可是这一切完成的时候结果却与想象的不同,无法在SD卡内创建文件,找一个晚上没有结果不得已采用另一种方法:软件模拟SPI测试了一下,结果另人出呼意料,一次搞定,没有任何问题,但为了效率还是希望使用硬SPI口,于是从引脚重映射上寻找原因又费了一晚上无果第三个晚上:经过无数次的改动 + 测试终于OK了,问题出在哪里了呢?原来SD卡的初始时钟不一定是<400KHz就行ST标准库初始化系统时APB2时钟为72MHz,经过256分频波特率约等于280KHz(SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;)对于我测试用的SD卡这个速度仍太快,于是降APB2时钟进行测试,OK!RCC_PCLK2Config(RCC_HCLK_Div4); //72/4=18MHz仅仅是一行代码,这就是初学代价!,哈哈.另外要说明的是,在MISO引脚上加了一个22k上接电阻.代码://#define USE_SOFT_SPI#ifdef USE_SOFT_SPIBYTE g_SPISpeedFlag=0;static void delay_bus(void){unsigned int i=100;if(g_SPISpeedFlag) //高速模式 < 25MHzi=10;while(--i) //低速模式 < 400KHz__nop();}void SpiOpen(void){//IO初始化用结构体GPIO_InitTypeDef GPIO_InitStructure;//输出引脚初始化GPIO_InitStructure.GPIO_Pin=SD_SCK|SD_CS|SD_MOSI;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);//输入引脚配置GPIO_InitStructure.GPIO_Pin=SD_MISO;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING ; GPIO_Init(GPIOB, &GPIO_InitStructure);//设置端口初始电平GPIO_SetBits(GPIOB,SD_CS);GPIO_SetBits(GPIOB,SD_SCK);g_SPISpeedFlag=0;}void SpiClose(void){GPIO_SetBits(GPIOB,SD_CS);GPIO_SetBits(GPIOB,SD_SCK);Stat &= ~STA_NOINIT;}void SPI_SetHeighSpeed(void){g_SPISpeedFlag=1;}BYTE SPI_ReadWriteByte(BYTE outgoing){uint32_t i;uint8_t ret=0;delay_bus();for(i=0;i<8;i++){ret<<=1;if(outgoing &0x80) //主设备锁存数据GPIO_SetBits(GPIOB,SD_MOSI);elseGPIO_ResetBits(GPIOB,SD_MOSI);GPIO_ResetBits(GPIOB,SD_SCK); //产生第一个时钟沿,让从设备也在此时锁存数据 delay_bus();if(GPIO_ReadInputDataBit(GPIOB,SD_MISO)) //主设备采样ret|=1;GPIO_SetBits(GPIOB,SD_SCK); //产生第二个时钟沿,让从设备也在此时采样delay_bus();outgoing<<=1;}return ret;}#else //硬件SPI 使用SPI1引脚重映射void SpiOpen(void){GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;GPIO_PinRemapConfig(GPIO_Remap_SPI1,ENABLE);/* Configure SPI1 pins: SCKand MOSI */GPIO_InitStructure.GPIO_Pin = SD_MOSI|SD_SCK|SD_MISO;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);/* Configure PB7 pin: CS pin */GPIO_InitStructure.GPIO_Pin = SD_CS;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,SD_CS);/* SPI1 Config */SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(SPI1, &SPI_InitStructure);/* SPI1 enable */SPI_Cmd(SPI1, ENABLE);}void SpiClose(void){SPI_Cmd(SPI1, DISABLE);Stat &= ~STA_NOINIT;}void SPI_SetHeighSpeed(void){SPI_InitTypeDef SPI_InitStructure;/* SPI1 Config */SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);}BYTE SPI_ReadWriteByte(BYTE outgoing){/* Loop while DR register in not emplty */while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);/* Send byte through the SPI1 peripheral */SPI_I2S_SendData(SPI1, outgoing);/* Wait to receive a byte */while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);/* Return the byte read from the SPI bus */return SPI_I2S_ReceiveData(SPI1);}#endif。
STM32 IAP 调试经验一、基本方法描述:将flash划分成3个扇区(可以单存用单片机内部flash,对于中大型容量MCU,且用户较小的案例,可以外挂片外flash应用于程序较大的工程),引导区、用户app区和程序存储备份区。
程序启动时先从引导区启动,查询备份区是否有升级程序标志,如果有,则将备份区的程序填充到用户app区,覆盖掉原先的程序,然后跳转到app区执行应用程序;如果没有升级标志,则直接跳转到用户app区地址,执行应用程序。
二、从引导区跳转到app区的函数定义需要添加以下两个函数1、void JumpToSpecifiedAddress(u32 EntranceAddress){u32 JumpAddress;pFunction Jump_To_Application;JumpAddress = *(vu32*) (EntranceAddress + 4);Jump_To_Application = (pFunction) JumpAddress;__set_MSP(*(vu32*) EntranceAddress); //Initialize Stack PointerJump_To_Application();}入口参数即是用户划分的app区地址,调用该函数后便可跳转执行app程序,例如分配app 区地址从0x8002000(引导区从0x8000000开始,8k空间)则,入口参数即0x8002000 2、void NVIC_Configuration(void){#ifdef VECT_TAB_RAMNVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);#elseNVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000);#endif}此处使用NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000);重新定义程序的中断向量链表,因为引导区8k,所以长度0x2000,从起始地址开始外呼0x2000地址的就是用户app 的中断向量链表,这里需根据实际分配的引导区长度填充,本例用用8k,填入0x2000. 注:#define NVIC_VectTab_FLASH ((uint32_t)0x08000000)三、引导区-用户应用区启动跳转简易实例引导区程序:int main(void){RCC_Configuration(); //系统时钟配置NVIC_Configuration(); //中断向量映射配置JumpToSpecifiedAddress(0x8002000)//跳转至用户app区}用户应用程序:int main(){//根据用户需要编写自己的程序}编译器设置:1、引导区程序工程设置其实地址0x8000000 长度8k(0x2000)2、用户应用程序其实地址0x8002000 长度60K(0x1E000)程序下载过程:需要烧写两个程序,才能运行,下载时先烧写引导程序,然后烧写应用程序。
STM32F0系列MCU中断向量表的重映射最近使⽤了⼀款Cortex-M0内核的芯⽚STM32F030CC,发现它中断向量表的重映射⽅法与STM32F10x系列的有所区别,在这⾥记录与分享⼀下。
由于需要通过IAP进⾏固件升级,所以芯⽚的FLASH⾥⾯要烧录两份代码:⼀个Boot loader, ⼀个⽤户应⽤程序。
理所当然的,在⽤户应⽤程序中,必须得重新映射中断向量表。
可是在ST提供的固件库⾥,我却没有发现类似于stm32f10x固件库中的void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)接⼝。
浏览了⼀下,原来M0并没有SCB->VTOR这个寄存器,难怪ST的库⾥没有提供NVIC_SetVectorTable这个接⼝。
这下要怎么办?在⽹络上搜索了⼀下,受到⽹友的启发,我在中找到以下说明:Physical remap Once the boot mode is selected, the application software can modify the memory accessible in the code area.This modification is performed by programming the MEM_MODE bits in the SYSCFG configuration register 1 (SYSCFG_CFGR1). Unlike Cortex® M3 and M4, the M0 CPU does not support the vector table relocation. For application code which is located in a different address than 0x0800 0000, some additional code must be added in order to be able to serve the application interrupts. A solution will be to relocate by software the vector table to the internal SRAM: • Copy the vector table from the Flash (mapped at the base of the application load address) to the base address of the SRAM at0x2000 0000. • Remap SRAM at address 0x0000 0000, using SYSCFG configuration register 1. • Then once an interrupt occurs, the Cortex®-M0 processor will fetch the interrupt handler start address from the relocated vector table in SRAM, then it will jump to execute the interrupt handler located in the Flash. This operation should be done at the initialization phase of the application. Please refer to and attached IAP code from for more details. OK,解决⽅法找到了! 在⽤户应⽤程序中,按照以上⽅法,添加以下两⾏代码:memcpy((void*)0x20000000, (void*)0x08004000, VECTOR_SIZE);SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM); 其中,0x2000 0000是SRAM的起始地址,这个不需要改动。
stm32位操作详解stm32位操作详解STM32位操作原理思想:把⼀个⽐特分成32位,每位都分配⼀个地址,这样就有32个地址,通过地址直接访问。
位操作基础位运算位运算的运算分量只能是整型或字符型数据,位运算把运算对象看作是由⼆进位组成的位串信息,按位完成指定的运算,得到位串信息的结果。
位运算&(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。
其中,按位取反运算符是单⽬运算符,其余均为双⽬运算符。
位运算符的优先级从⾼到低,依次为~、&、^、|,其中~的结合⽅向⾃右⾄左,且优先级⾼于算术运算符,其余运算符的结合⽅向都是⾃左⾄右,且优先级低于关系运算符。
(1)按位与运算符(&)按位与运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1。
即同为1的位,结果为1,否则结果为0。
例如,设3的内部表⽰为000000115的内部表⽰为00000101则3&5的结果为00000001按位与运算有两种典型⽤法,⼀是取⼀个位串信息的某⼏位,如以下代码截取x的最低7位:x & 0177。
⼆是让某变量保留某⼏位,其余位置0,如以下代码让x只保留最低6位:x = x & 077。
以上⽤法都先要设计好⼀个常数,该常数只有需要的位是 (2)按位或运算符(|)按位或运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 | 0 = 0, 0 | 1 = 1, 1 | 0 = 1, 1 | 1 = 1即只要有1个是1的位,结果为1,否则为0。
例如,023 | 035结果为037。
按位或运算的典型⽤法是将⼀个位串信息的某⼏位置成1。
如将要获得最右4为1,其他位与变量j的其他位相同,可⽤逻辑或运算017|j。
若要把这结果赋给变量j,可写成:j = 017|j(3)按位异或运算符(^)按位异或运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0即相应位的值相同的,结果为0,不相同的结果为1。
STM32单片机的重映射与地址映射的使用方法及步骤
重映射
STM32中对于一些端口的外设已经被其他引脚所使用,这是就需要用端口重映射来解决了,很方便。
以USART1为例
重映射的步骤为:
打开重映射时钟和USART重映射后的I/O口引脚时钟,
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);
I/O口重映射开启。
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
配制重映射引脚,这里只需配置重映射后的I/O,原来的不需要去配置。
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_A F_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_I N_FLOATING;GPIO_Init(GPIOB,12345678
这样就可以了,很简单。
地址映射
对于地址映射是在查重映射时发现的,感觉ST的库很机智,就记录下来。
首先看一下M3 存储器映射
我们的操作就在这512MB的地址进行。
在LED灯的程序中,存在宏定义:
#defineGPIOC_BASE(APB2PERIPH_BASE+0x1000)#defineAPB2PERIPH_BASE (PERIPH_BASE+0x10000)#definePERIPH_BASE((uint32_t)0x40000000)123。