完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
IAR Guide Manual 1 Install IAR 1.1 下载安装包 1.2 安装 打开文件EWARM安装包,选择第一项进行安装: 进入安装指导,选择NEXT,不要尝试改变语言,因为只有英语和日语两个选项,要汉化自行寻找汉化包和教程。 勾选同意,点击NEXT: 由于我们使用的吊事工具是ST-LINK/V2 所以选择安装ST-LINK驱动,由于J-Link也是比较常用的一个调试工具,因此都勾选上。如果觉得有必要U-Link也可以安装。 选择安装路径,这里直接默认安装路径。 由于存在已经安装的USB Dongle驱动,会弹出下面窗口,不过不影响,直接确定。 选择Install,进行安装。 安装中。。。。。。 安装驱动中。。。。。。 安装完成。看此教程的人理论上不需要看release notes了,不用勾选。点击Finish。 继续安装被拦截的驱动等软件,选择安装即可。 继续安装中。。。。。。 选择 I Agree。 接下来会弹出的不少驱动安装窗口,操作如上进行即可。直至出现如下界面: 选择Exit,退出安装向导。 IAR 自动打开。 1.3证书安装 然后,证书安装向导弹出,若没有弹出,进入开始菜单,打开IAR License Manager。 此处进行一种非在线证书文件安装过程(安装需要在无网络环境下进行)。 选择第一个选项,填入序列号,选择先一步。 弹出提示信息,选择是进行离线安装。 保持原来的序列号,接下来选择第一项,点击下一步 不用锁dongle,选择NO,点击下一步 选择一个路径用来保存激活信息,该路径可以随意,但是要记住在哪儿,一会儿就要用。 利用激活信息,请求激活响应文件,点击Open file location 导入激活响应文件,点击下一步。 点击Finish,完成证书安装。 2 Start an IAR project for STM32F103RB 2. 1 Create and config a sample project 首先打开软件,如下所示 点击Project — > Create New Project 如下,选择空白工程,点击OK。 选择工程文件位置。 然后,为了使编程更加方便,以及使上个教程的代码可以重用,需要借助标准库文件和CMSIS核心,首先,将以下几个配置文件和主函数,在根目录下自建一个文件夹保存起来,如下,代码内容见教程尾部Appendix — > Example Code。其中stm32f10x_conf.h不在附录中,在标准库根文件夹下的的Project— > STM32F10x_StdPeriph_Template中可以找到。其实只要你自己的文件依赖关系都独立引入使用的库文件的头文件时,这个文件可以不要。 然后复制标准库根文件夹下的Library到工程文件夹。 然后将Custom文件夹和Library文件夹分组添加到工程中。如下点击Project弹出下拉菜单,也可以直接右击项目target进行添加。 添加Custom Group。 添加Custom文件夹下的文件,直接右击Custom文件夹,全选文件,直接打开。 标准库文件夹添加比较复杂(如果自己要下载官方标准函数库访问https://my.st.com/content/ccc/resource/technical/software/firmware/48/ab/e5/17/0d/79/43/74/stsw-stm32054.zip/files/stsw-stm32054.zip/jcr:content/translations/en.stsw-stm32054.zip),首先添加STM32F10x_StdPeriph_Driver Group,添加Library /STM32F10x_StdPeriph_Driver/src 文件夹的所有文件。然后添加CMSIS Group,在其下再添加 startup Group,添加 LibrariesCMSISCM3DeviceSupportSTSTM32F10xstartupiar 文件夹下的所有文件, 最后在CMSIS Group 添加文件system_stm32f10x.c ,在LibrariesCMSISCM3DeviceSupportSTSTM32F10x文件夹下。 添加完毕如下: 启动文件只需要一个startup_stm32f10x_md.s,其他的都右键 Option勾选如下选项,点击OK。实际上可以在添加文件时只添加我们要用的那个,因为这是一个模板工程,所以都添加了。 其他同样操作后如下: 这里需要说明一下,此工程中的startup_stm32f10x_md.s是经过修改的,若不修改,在该版本的IAR中编译后会出现大量警告。修改内容是将原来的SECTION .text:CODE:REORDER(1)改为SECTION .text:CODE:REORDER:NOROOT(1)。文件算是添加完了。 点击Project(或右击 template-Debug)选择Option,进入选项设置。点击左边的 General Options,再点击右边上部的Target,点击标记的按钮,选择ST— >STM32F1— > STM32F103— >STM32F103RB。 点击右边上部Library Configuration,勾选标记的选项。由于使用的IAR自带的CMSIS core,因此标准库文件夹的LibrariesCMSISCM3CoreSupport 文件不再使用,也不要将该路径加入预编译头文件包含路径。 点击左边 C/C++ Compiler, 点击右边上部 Preprocessor ,首先添加头文件路径,四个文件路径如下所示,如果嫌自己写的头文件麻烦的话,可以将Custom文件夹也添加进去,注意箭头提示的下三角,点击该下三角可以调整浏览选择的路径为绝对或相对路径。 继续添加宏定义,如下所示 再点击左边的Debugger,点击右边上部的Setup,选择调试工具ST-LINK,我们使用的就是该工具。继而点击右边上部的Download,勾选 Verify download。 继续,点击左边的ST-LINK,点击右边的Setup,在Interface 选项下勾选SWD。 最后选择Project,点击Rebuild All。 若出现如下提示框所示内容,则说明前面的步骤都没有错。可以进行程序下载了。 接下来,点击Project — > Download — > Download active application ,进行下载。 下载完毕出现如下所示信息,由于该下载直接将程序下载进入Flash,且没有软件重启,所以需要手动重启生效。 然后就可以观察到想要的结果了。 2.2 Create the sample project with CMSIS-Pack 为什么要使用CMSIS-Pack 工具? 首先,从上面的配置可以看出,配置过程比较麻烦,除此之外,还需要手动下载标准库文件。其次,包依赖方便,标准库文件有一大部分在正常工程中可能是不需要的,但是难以理清其间的依赖关系。使用该工具可以自动检测依赖,可以直接看出去掉某个库文件后影不影响工程。最后,也是最重要的,使用工具后支持包更加丰富,可以省去很多工作,另外,可以直接导入嵌入式实时操作系统RTOS。 IAR 其实也可以使用keil CMSIS-Pack,但是在作者测试过程中,建立工程中仍存在一些bug,接下来使用步骤。 首先,点击图示的按钮。 接下来,要求新建工作空间WorkSpace, 建在一个自己要创建工程的地方。 接下来,正式进入包管理界面。首先将我们需要的ARM. CMSIS进行安装。 再安装我们需要的Keil.STM32F1xx_DFP。 不要关闭该界面,回到IAR主界面,然后新建一个工程。 选择Empty CMSISPack project,然后保存工程,记住这个位置要在WorkSpace目录下新建一个目录,不能和WorkSpace同目录。这里再提一句,CMSISPack工程一定要建在CMSISPack WorkSpace下,若从新建CMSISPack工程开始,则在建工程的同时自动先添加WorkSpace,若从新建工作空间开始,不要先点击新建WorkSpace要先****点击CMSISPack Manager,进入前自动先建CMSISPack WorkSpace。然后不要关闭CMSISPack Manager,新建Empty CMSISPack project。 点击保存后会弹出(若没有马上弹出要稍等一会儿)Select Device。作者这里使用了STM32F103RB的开发板,故选择该设备。 然后开始配置Option,首先 General Options,点击Taget选择Device,按箭头提示按钮选择ST STM32F103RB。重要提示,一定是Device,不要选第三个 CMSIS-Pack。 为了使用printf函数,需要勾选如下所示的提示框。 然后调试工具配置同上 然后将我们需要的库文件添加进去。这里必须要添加的有CMSIS的CORE,以及根据依赖我们必需的STDPeripheral Driver库文件。这里的Startup实际上是没有实际内容的,可以不用添加。这里可能是个bug,之后我们还需要添加startup文件。 添加之后如下所示。 然后添加我们自己的文件进去,同上 同样的方式,添加启动文件(汇编)。直接从上文中提到的库中粘贴过来。 接着同上文一样,重建,下载,调试即可。 3 Debug 如下图标记所示,两个按钮是进入调试的按钮,点击左边的按钮会先将程序下载入flash,然后运行调试。右边的不会下载,调试完断电重启之后,程序会被原来的程序覆盖。需要说明的是flash是有写入寿命的,少则100,多则10k,一般可以使用右边的按钮来调试。 进入调试模式后,可以进行断点调试,单步调试等,同时显示汇编,也可以观察STM32F103的寄存器,RAM的值。比较明显的是,IAR调试功能不及keil强大。 Appendix Example Code
#include "stm32f10x_gpio.h" #include "stm32f10x_usart.h" #include "delay.h" #include "gpio_conf.h" #include "usart_conf.h" #include "misc.h" #include #define LED_PORT GPIOB #define LED0_PIN GPIO_Pin_0 #define LED1_PIN GPIO_Pin_1 //#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) //#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) void NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //中断分组1:1位抢占优先级,3位响应优先级 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断 NVIC_Init(&NVIC_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } int main(void){ int i = 0; GPIO_Conf(LED_PORT,LED0_PIN|LED1_PIN); USART1_Init(); USART2_Init(); NVIC_Config(); while(1){ GPIO_SetBits(LED_PORT, LED0_PIN); GPIO_ResetBits(LED_PORT, LED1_PIN); delay(20); GPIO_SetBits(LED_PORT, LED1_PIN); GPIO_ResetBits(LED_PORT, LED0_PIN); delay(100); i = USART1_RecNum(); while(i--){USART2_SendChar(USART1_ReadByte());} i = USART2_RecNum(); while(i--){USART1_SendChar(USART2_ReadByte());} //printf("nrUSART Printf Example: retarget the C library printf function to the USARTnr"); //USART1_SendChar('B'); } } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %drn", file, line) */ /* Infinite loop */ while (1) { } } #endif Filename: delay.c #include "delay.h" void delay(vu32 nCount) { vu32 index = 0; for(index = (34000 * nCount); index != 0; index--) { } } Filename: delay.h #ifndef __DELAY_H #define __DELAY_H #include "stm32f10x.h" void delay(vu32 nCount); #endif /* __DELAY_H */ Filename: gpio_conf.c #include "gpio_conf.h" #define ID_GPIOA (uint32_t)GPIOA-APB2PERIPH_BASE #define ID_GPIOB (uint32_t)GPIOB-APB2PERIPH_BASE #define ID_GPIOC (uint32_t)GPIOC-APB2PERIPH_BASE #define ID_GPIOD (uint32_t)GPIOD-APB2PERIPH_BASE #define ID_GPIOE (uint32_t)GPIOE-APB2PERIPH_BASE #define ID_GPIOF (uint32_t)GPIOF-APB2PERIPH_BASE #define ID_GPIOG (uint32_t)GPIOG-APB2PERIPH_BASE void GPIO_Conf(GPIO_TypeDef * port,uint16_t pin){ GPIO_InitTypeDef GPIO_InitStructure; uint32_t GPIO_CLK = RCC_APB2Periph_GPIOB; /* Enable the GPIO Clock */ switch((uint32_t)port-APB2PERIPH_BASE){ case ID_GPIOA:GPIO_CLK = RCC_APB2Periph_GPIOA;break; case ID_GPIOB:GPIO_CLK = RCC_APB2Periph_GPIOB;break; case ID_GPIOC:GPIO_CLK = RCC_APB2Periph_GPIOC;break; case ID_GPIOD:GPIO_CLK = RCC_APB2Periph_GPIOD;break; case ID_GPIOE:GPIO_CLK = RCC_APB2Periph_GPIOE;break; case ID_GPIOF:GPIO_CLK = RCC_APB2Periph_GPIOF;break; case ID_GPIOG:GPIO_CLK = RCC_APB2Periph_GPIOG;break; default: break; } RCC_APB2PeriphClockCmd(GPIO_CLK, ENABLE); /* Configure the GPIO pin */ GPIO_InitStructure.GPIO_Pin = pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } Filename: gpio_conf.h #ifndef __GPIO_CONF_H #define __GPIO_CONF_H #include "stm32f10x.h" void GPIO_Conf(GPIO_TypeDef * port,uint16_t pin); #endif /*__GPIO_CONF_H*/ Filename: usart_conf.c #include "usart_conf.h" #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */ char RxUBuf1[RXBUF1_MAX]; static uint8_t Num_U1RxByte = 0; static uint8_t U1RxF = 0; static uint8_t U1RxL = 0; char RxUBuf2[RXBUF2_MAX]; static uint8_t Num_U2RxByte = 0; static uint8_t U2RxF = 0; static uint8_t U2RxL = 0; struct __FILE { int a; }; FILE __stdout; void _sys_exit(int x) { } void USART1_Init(void){ USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIO clock */ RCC_APB2PeriphClockCmd(USART1_GPIO_CLK, ENABLE); /* Configure USART Tx as alternate function push-pull */ //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = USART1_TX; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(USART1_GPIO, &GPIO_InitStructure); /* Configure USART Rx as input floating */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = USART1_RX; GPIO_Init(USART1_GPIO, &GPIO_InitStructure); /* Enable UART clock */ RCC_APB2PeriphClockCmd(USART1_PORT_CLK, ENABLE); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* USART configuration */ USART_Init(USART1, &USART_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断 //USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); /* Enable USART */ USART_Cmd(USART1, ENABLE); } void USART2_Init(void){ USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIO clock */ RCC_APB2PeriphClockCmd(USART2_GPIO_CLK, ENABLE); /* Configure USART Tx as alternate function push-pull */ //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = USART2_TX; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(USART2_GPIO, &GPIO_InitStructure); /* Configure USART Rx as input floating */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = USART2_RX; GPIO_Init(USART2_GPIO, &GPIO_InitStructure); /* Enable UART clock */ RCC_APB1PeriphClockCmd(USART2_PORT_CLK, ENABLE); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* USART configuration */ USART_Init(USART2, &USART_InitStructure); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启接收中断 //USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); /* Enable USART */ USART_Cmd(USART2, ENABLE); } char USART1_ReadByte(void){ if(Num_U1RxByte == 0) return ' |