那是因为你有同样地址的源已经存在了(可能名字不一样而已)。 回到上一步 在“work with“下面有一个“Available software sides“点击后在列表下面去找这个相同地址的那一项,要么使用找到的这一项安装ADT,要么把这项删除后重新新建一个。 android ADT是抽象数据类型(ADT)是一个实现包括储存数据元素的存储结构以及实现基本操作的算法。在这个数据抽象思想中,数据类型的定义和它的实现是分开的,这在软件设计中是一个重要的概念。这使得只研究和使用它的结构而不用考虑它的实现细节成为可能。 运用: 在面向对象编程语言中,像C++、Java都能较好的支持ADT,如类的机制。而在C语言中缺少了对相关方法的支持。 在C语言中,有些数据结构类型是C语言程序员不可或缺的工具,这是由于它们的属性决定的。这类ADT有链表,堆栈,队列和树等,它们在实现上极具灵活性。 抽象数据类型需要通过固有数据类型(高级编程语言中已实现的数据类型)来实现。抽象数据类型是与表示无关的数据类型,是一个数据模型及定义在该模型上的一组运算。对一个抽象数据类型进行定义时,必须给出它的名字及各运算的运算符名,即函数名,并且规定这些函数的参数性质。一旦定义了一个抽象数据类型及具体实现,程序设计中就可以像使用基本数据类型那样,十分方便地使用抽象数据类型。
方法1. 在"开始"-->"运行"---->"cmd"进入命令提示行后,再进入myeclipse安装目录的eclipse文件夹,然后输入myeclipse -clean即可 方法2. 找到myeclipse安装目录的configuration文件夹删除除config.ini以外的所有文件(记得备份),重启myeclipse。 方法3. 找到myeclipse安装目录的configuration文件夹,除config.ini、.settings两个文件夹保留,其他文件都删除掉(记得备份)。 方法4.关闭myeclipse的jsp文件语法验证,Project>Properties>MyEclipse>Validation>Configure Workspace Settings...>找到JSP把勾选去掉。 方法5.关闭myeclipse的jsp设计视图,window -> perferences -> General -> editors -> file associations 找到jsp -> 把myeclispe jsp editor 设为 default(默认是:myeclispe visual jsp editor) MyEclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java、Java EE以及移动应用的开发。MyEclipse的功能非常强大,支持也十分广泛,尤其是对各种开源产品的支持相当不错。
方法1. 在"开始"-->"运行"---->"cmd"进入命令提示行后,再进入myeclipse安装目录的eclipse文件夹,然后输入myeclipse -clean即可 方法2. 找到myeclipse安装目录的configuration文件夹删除除config.ini以外的所有文件(记得备份),重启myeclipse。 方法3. 找到myeclipse安装目录的configuration文件夹,除config.ini、.settings两个文件夹保留,其他文件都删除掉(记得备份)。 方法4.关闭myeclipse的jsp文件语法验证,Project>Properties>MyEclipse>Validation>Configure Workspace Settings...>找到JSP把勾选去掉。 方法5.关闭myeclipse的jsp设计视图,window -> perferences -> General -> editors -> file associations 找到jsp -> 把myeclispe jsp editor 设为 default(默认是:myeclispe visual jsp editor) MyEclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java、Java EE以及移动应用的开发。MyEclipse的功能非常强大,支持也十分广泛,尤其是对各种开源产品的支持相当不错。
用clean解决。 如图MyEclipse10中弹出problem occurred: 方法一在"开始"-->"运行"---->"cmd"进入命令提示行后,再进入myeclipse安装目录的eclipse文件夹,然后输入eclipse -clean即可 方法二 找到myeclipse安装目录的configuration文件夹删除除config.ini以外的所有文件,重启myeclipse。 方法三跟方法二一样,找到myeclipse安装目录的configuration文件夹,config.ini、settings两个文件夹保留,其他文件都删除掉。 弹出这个错误框,里面有一个以日期之类的.log的日志文件,其实删除org.eclipse.core.runtime相似的那几个文件夹,是直接删除那个日期格式.log的日志文件。
“A problem has occured in BitDefender Threat Scanner。A file containing error information has been created at c:\windows\TEMP\ BitDefender Threat Scanner.dmp。You are strongly encouraged to send the file to the developers of the application for further investigation of the error。”
(大意是:一个问题已经发生在BitDefender威胁Scanner。文件中含有错误信息已经被记在c:\windows\TEMP\ BitDefender Threat Scanner.dmp这个位置。建议你把文件寄出以备进一步的调查云云)
将这一对话框关闭后,机子只启动了部分应用程序,随即先后出现这俩对话框:“Initialization failure:ox0000000c。”“Error initiating the windows sockets。”
比特凡得杀毒软件在扫描病毒的时候出错了,比特凡得把出错信息写进了C:\WINDOWS\TEMP\BitDefender Threat Scanner.dmp这个文件里,并且强烈建议你把这个文件发送给程序开发者去研究下出错的情况。
就是一般的程序出错后要求您给程序开发者发个反馈。您可以选择无视这个消息的。
360杀毒软件就是用的比特凡得的内核,所以会有这样的信息提示也正常的。
处理方法:
(D:\Program Files\360\360Safe\WinSockLSP.reg)
双击360安装目录下的winsocklsp.reg,注册完成后重启就OK了。
P.s. BitDefender Threat Scanner.dmp 是在C盘文件下的Temp文件夹之下
这里是系统放临时文件的地方,
也就是说BitDefender Threat Scanner.dmp是杀毒软件内核自己创建的一个出错记录
你收到的错误窗口只是杀软内核给你的提示, 建议你把这个出错记录发送给开发团队.
我和你的情况一样!但是后来还是让我给搞掂了,我的是XP SP3系统
因为我装了360,所以我把360全删了,跟着把注册表所有有关360的都删掉后,还有跑跑的注册表的所有都删掉,再用优化大师清理注册表,跟着重启电脑,再安装跑跑,注意:在安装跑跑的过程中,什么杀毒防火QQ啥都关了~
装好之后就OK了,我试过只是把360关闭是不行的,一定要把360全删了!要连根拔了!
我开着卡巴玩都没事,如果这样还不行,就得考虑是否有其他软件和跑跑的反外挂程序冲突,导致不能够在C盘的windows文件的那个drivers的文件哪里生成eaglexnt.sys这个反外挂驱动文件!
NOD32我不知道,但是我上网查过有人是NOD32在阻止了反外挂文件
PS:就在我上去跑完几圈之后出来,我就下载了一个安全辅助的软件,叫做Zemana AntiLogger,就在我装好这个软件之后,跑跑的问题又出现了,我那个郁闷了,查了下,发现这个软件只是扫描了下跑跑的eaglexnt.sys这个反挂驱动文件,而且已经允许这个文件产生,但还是不行!
无奈之下,我只好把这个软件删除,重启过后就可以上跑跑了!
哎,跑跑的反外挂文件太脆弱也太敏感了,就算白名单也没用!郁闷
这段话的意思是BitDefender Threat Scanner出现了一个问题。一个包含错误信息的文件被创建在C:/WINDOWS/TEMP/BitDefender Threat SCanner.dmp。建议你发送这个文件到软件开发商以对错误进行更深入的调查。
大概是楼主你的电脑中毒了,建议杀毒后重启。
估计是360。
双击360安装目录下的winsocklsp.reg,注册完成后重启就OK了。
对话框提示“你的Bitdefender Threat Scanner有个错误,系统把错误记录到一个dmp文件,你可以把他发给软件开发者”
如果你没装过它,按对话框上的路径C:\windows\temp\去把BitDefender Threat Scanner.dmp删了。
然后检查你的“添加删除程序”里面有没有这个软件,到C:\programfiles里找找,注册表也找找,相关的删除。
如果还不行就重装系统。
对话框提示“你的Bitdefender Threat Scanner有个错误,系统把错误记录到一个dmp文件,你可以把他发给软件开发者”
如果你没装过它,按对话框上的路径C:\windows\temp\去把BitDefender Threat Scanner.dmp删了。
然后检查你的“添加删除程序”里面有没有这个软件,到C:\programfiles里找找,注册表也找找,相关的删除。
一、生成一个新项目
要使用IAR进行STM32嵌入式系统开发,必须从建立一个项目(project)开始,下面以在E:\下建立一个名为Example的项目为例介绍。
1. 创建项目目录、复制公共文件
(1)在E盘下创建名为的Example文件夹,即项目根目录为E:\Example。
(2)在项目根目录下建立一个EWARMv5文件夹用于存放项目文件、工作空间文件和项目配置相关文件。
(3)解压标准外设驱动文件库(stm32f10x_stdperiph_lib_V3.1.2.zip),将其中的“Libraries”文件夹复制到Example目录下。
(4)复制标准外设驱动库目录Project\Template下的stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h三个文件到Example文件夹下。main.c可以不用复制,自己写。
复制标准外设驱动库目录Project\Template\EWARMv5下的stm32f10x_flash.icf、stm32f10x_flash_extsram.icf、stm32f10x_nor.icf和stm32f10x_ram.icf到Example\EWARMv5文件夹下。
复制好的目录。
2. 创建新的工作空间
嵌入式系统开发大都是面向项目(Project)的,需要建立Project来管理项目开发。IAR EWRAM又是基于工作空间(Workspace)的集成开发环境,Project必须放在工作空间里面,所以我们首先应该建立工作空间。一个工作空间里面可以放多个项目。
开始?程序?IAR Systems?IAR Embedded Workbench,进入IDE环境。File ?New?Workspace。
这样工作空间就建好了,但是这个工作空间里面还没有项目,所以还不能保存,下面将在这个工作空间里面建立新项目。
3. 创建新项目
在上面第2步已经建立好的工作空间里创建新项目。
Project?Create New Project。弹出“Create New Project”对话框,“Tool Chain”选择ARM,“Project Template”选择Empty project模板,这样所有的文件都由用户自己来写。点击OK,弹出“另存为…”对话框,选择我们刚刚建好的Example目录下的EWARMv5文件夹下,然后输入工程名 ,这里我输入Template,然后点击保存。这样一个名为Template的IAR EWARM项目就建好了,下面我们添加一些文件,然后再修改一些参数,使得这个项目真正地能够使用。
4. 添加文件到项目
(1)文件分组
按说现在就可以往项目里面添加文件了,但是由于ARM系统开发涉及文件较多,类型繁杂,加上我们使用ST公司的标准固件库驱动文件,这样就要添加很多文件到项目里,随着项目的复杂程度加大,文件的数量是很多的。为了便于管理,将这些文件在项目里分组保存,IAR EWARM支持文件分组。
在IDE左侧的Workspace里面,在刚刚建立的Template项目上点右键,选择Add? Add Group…。在弹出的对话框里面输入组名(Group Name),点OK即可。将添加如下几个组。
项目名字后面有个星号(*),这是说明项目或工作空间已经修
改,但是还没有保存,现在点File?Save All,这时弹出对话框让保存工作空间。还记得工作空间吗?第2步新建的工作空间,但是当时没有保存,因为当时工作空间里面没有项目,不能保存。输入工作空间名Template,然后点保存,这时候项目后面的星号*消失。
注:工作空间扩展名.eww,项目扩展名
cubeMX的主要优点:
1.直观地进行STM32选择2.图形化配置3.C代码项目产生,涵盖STM32初始化部分。兼容IAR, KEIL和GCC编译器4.支持Eclips
工具/原料
CubeMX软件,CUBE库
电脑
kEIL5.15软件
方法/步骤
1
到ST官网下载软件包和cube库,并安装好。安装过程比较简单,不多赘述
2
点击NEW Project,新建工程,或者file-->new project也可
3
下面是选择器件板子,可以根据MCU进行选择,也可以根据board型号选择
4
我用的板子是STM32F411RE,所以产商选择STMicroelectric,版本选择Nucleo,型号选择F4系列,便可看到列表中有F411选项了
5
双击F411R
1.解压stm32f10x_stdperiph_lib.zip 可以从ST官方网站免费下载。
2.创建一个Demo文件夹
2.1 新建子文件夹User,用于存放用户源程序
2.2 新建子文件夹Project,用户KEIL工程文件
2.3 在Project下依次创建Obj和List子文件夹,存放编译过程中产生的中间文件。
3. 复制源代码到Demo文件夹
3.1 将stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.1.2Libraries文件整体复制到Demo文件夹下。这就是ST的标准库,是以源代码形式提供的。
3.2 将库中的演示代码IOToggle中的文件复制到Demo\User文件夹.
4. 新建一个Keil MDK工程
4.1 启动Keil MDK,点击菜单 New uVision Project,然后按向导进行操作
4.2 选择CPU类型为 STM32F103ZE (这是安富莱STM32开发板采用CPU类型)
4.3 当提示是否复制启动代码时,请选择否。(我们用最新的库中的启动代码,不用Keil软件自带的旧版本启动文件)
4.4 根据自己的需要修改Target名字。(名字任意)
4.5 为了便于代码管理,在这个Project下创建几个Group (名字可以任意)
User : 存放用户自己写的源代码
RVMDK : 存放启动文件(汇编文件)
StdPeriph_Driver : 存放ST标准库文件
CMSIS : 存放CMSIS接口文件(这也是库的一部分)
4.6 创建好Group后,我们开始依次添加文件。
5. 修改源代码。我们将修改main.c 文件,换成我们自己跑马灯程序。
6. 配置工程, 点击“Options”按钮
6.1 切换到Output。
选择Object文件夹。
在Create Hex File 前打钩。
6.2 切换带Listing。
选择Listings文件夹
6.3 切换到C/C++
添加两个预编译宏 STM32F10X_HD, USE_STDPERIPH_DRIVER (这是ST库用到了这两个宏)
修改Includes路径
6.4 切换到Debug
选择硬件调试器(缺省是软件仿真),我们选择Cortex-M3 J-Link调试器
再 Run to main前打钩
6.4 切换到Utilities
选额调试器类型,我们选择Cortex-M3 J-Link
点settings按钮,添加Flash编程算法,我们选择STM32高密度器件,Flash容量512K字节
7. 配置工程完毕。下面开始编译。
8. 编译OK,开始调试。
9. 教程结束。
STM32产生PWM是非常的方便的,要需要简单的设置定时器,即刻产生!当然,简单的设置对于新手来讲,也是麻烦的,主要包括:
(1)使能定时器时钟:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
复制代码
(2)定义相应的GPIO:
/* PA2,3,4,5,6输出->Key_Up,Key_Down,Key_Left,Key_Right,Key_Ctrl */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //下拉接地,检测输入的高电平
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* PA7用于发出PWM波,即无线数据传送 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIOA, &GPIO_InitStructure);
复制代码
(3)如果是产生PWM(频率不变,占空比可变),记得打开PWM控制,在TIM_Configuration()中。
TIM_Cmd(TIM3,ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1,ENABLE);
复制代码
利用定时器产生不同频率的PWM
有时候,需要产生不同频率的PWM,这个时候,设置与产生相同PWM的程序,有关键的不一样。
(一) 设置的原理
利用改变定时器输出比较通道的捕获值,当输出通道捕获值产生中断时,在中断中将捕获值改变,这时, 输出的I/O会产生一个电平翻转,利用这种办法,实现不同频率的PWM输出。
(二)关键设置
在定时器设置中:
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
复制代码
在中断函数中:
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + Key_Value);
}
复制代码
一个定时器四个通道,分别产生不同频率(这个例子网上也有)
vu16 CCR1_Val = 32768;
vu16 CCR2_Val = 16384;
vu16 CCR3_Val = 8192;
vu16 CCR4_Val = 4096;void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* ---------------------------------------------------------------
TIM2 Configuration: Output Compare Toggle Mode:
TIM2CLK = 36 MHz, Prescaler = 0x2, TIM2 counter clock = 12 MHz
CC1 update rate = TIM2 counter clock / CCR1_Val = 366.2 Hz
CC2 update rate = TIM2 counter clock / CCR2_Val = 732.4 Hz
CC3 update rate = TIM2 counter clock / CCR3_Val = 1464.8 Hz
CC4 update rate = TIM2 counter clock / CCR4_Val = 2929.6 Hz
--------------------------------------------------------------- *//* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 2;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //PWM模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //正向通道有效
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//反向通道无效
TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //占空时间
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补端的极性
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;TIM_OC1Init(TIM2,&TIM_OCInitStructure); //通道1
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);TIM_OCInitStructure.TIM_Pulse = CCR2_Val; //占空时间
TIM_OC2Init(TIM2,&TIM_OCInitStructure); //通道2
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);TIM_OCInitStructure.TIM_Pulse = CCR3_Val; //占空时间
TIM_OC3Init(TIM2,&TIM_OCInitStructure); //通道3
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);TIM_OCInitStructure.TIM_Pulse = CCR4_Val; //占空时间
TIM_OC4Init(TIM2,&TIM_OCInitStructure); //通道4
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* TIM2 counter enable */
TIM_Cmd(TIM2,ENABLE);
/* TIM2 Main Output Enable */
//TIM_CtrlPWMOutputs(TIM2,ENABLE);/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);}void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;/*允许总线CLOCK,在使用GPIO之前必须允许相应端的时钟.
从STM32的设计角度上说,没被允许的端将不接入时钟,也就不会耗能,
这是STM32节能的一种技巧,*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
/* PA2,3,4,5,6,7输出->LED1,LED2,LED3,LED4,LED5,LED6 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* PB0,1输出->LED7,LED8*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* PA0,1->KEY_LEFT,KEY_RIGHT*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);/* PC13->KEY_UP*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOC, &GPIO_InitStructure);/* PB5->KEY_DOWN*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure);/* GPIOA Configuration:TIM2 Channel1, 2, 3 and 4 in Output */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
}void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}u16 capture = 0;
extern vu16 CCR1_Val;
extern vu16 CCR2_Val;
extern vu16 CCR3_Val;
extern vu16 CCR4_Val;void TIM2_IRQHandler(void)
{/* TIM2_CH1 toggling with frequency = 183.1 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );
capture = TIM_GetCapture1(TIM2);
TIM_SetCompare1(TIM2, capture + CCR1_Val );
}
/* TIM2_CH2 toggling with frequency = 366.2 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM2);
TIM_SetCompare2(TIM2, capture + CCR2_Val);
}/* TIM2_CH3 toggling with frequency = 732.4 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
capture = TIM_GetCapture3(TIM2);
TIM_SetCompare3(TIM2, capture + CCR3_Val);
}/* TIM2_CH4 toggling with frequency = 1464.8 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);
capture = TIM_GetCapture4(TIM2);
TIM_SetCompare4(TIM2, capture + CCR4_Val);
}}
复制代码
一个定时器一个通道,产生不同频率
其它的设置都一样,就是在主函数中修改一个参数,然后在定时器中断中,根据这个参数,改变频率。
#include "stm32lib\\stm32f10x.h"
#include "hal.h"volatile u16 Key_Value=1000; //用于保存按键相应的PWM波占空比值
int main(void)
{
ChipHalInit();
ChipOutHalInit();while(1)
{
if( (!Get_Key_Up)&(!Get_Key_Down)&(!Get_Key_Left)&(!Get_Key_Right)&(!Get_Key_Ctrl) )
{
Key_Value=12000;
}
else
{
if(Get_Key_Up) //按键前进按下 ,对应1kHz
{
Key_Value=6000;
}
else if(Get_Key_Down) //按键后退按下 ,对应2kHz
{
Key_Value=3000;
}
Delay_Ms(20); //10ms延时if(Get_Key_Left) //按键左转按下,对应3kHz
{
Key_Value=2000;
}
else if(Get_Key_Right) //按键右转按下,对应4kHz
{
Key_Value=1500;
}
Delay_Ms(20); //10ms延时if(Get_Key_Ctrl) //按键控制按下,对应5kHz
{
Key_Value=1200;
}
Delay_Ms(20); //10ms延时
}
}
}extern volatile u16 Key_Value;
u16 capture=0;
void TIM3_IRQHandler(void)
{
/* TIM2_CH2 toggling with frequency = 366.2 Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + Key_Value);
}
}void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);/*TIM1时钟配置*/
TIM_TimeBaseStructure.TIM_Prescaler = 5; //预分频(时钟分频)72M/6=12M
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseStructure.TIM_Period = 65535; //装载值选择最大
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //PWM模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //正向通道有效
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//反向通道无效
TIM_OCInitStructure.TIM_Pulse = Key_Value; //占空时间
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补端的极性
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;TIM_OC2Init(TIM3,&TIM_OCInitStructure); //通道2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* TIM1 counter enable */
TIM_Cmd(TIM3,ENABLE);
/* TIM1 Main Output Enable */
//TIM_CtrlPWMOutputs(TIM1,ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC2 , ENABLE);
}
复制代码
注意:在计算PWM频率的时候,TIMx的时钟都是72Mhz,分频后,因为翻转两次才能形成一个PWM波,因为,PWM的频率是捕获改变频率的1/2。
不知道你是怎么想的,STM32不支持LINUX!
我觉得ARM+LINUX门槛高,做出来的东西不容易被山寨。
现在很多东西都可以用51、STM32来做,但是你的好想法,好创意都容易被其他公司给山寨去。
当然ARM+LINUX也会被山寨,但是要考虑山寨的成本。
我之前的对手公司,准备山寨我公司LINUX创意的产品,但是开发难度大,周期长。不能有效抢占市场,他们来挖人也挖不到,后来它们用UCOS来做。LINUX的强大是它的网络,用UCOS来山寨,再怎么厉害,其他的外设还好说,但是网络那关永远过不去。这就是一个槛。
现在驱动转做软件的大有人在,做好一个驱动基本就不用怎么大改了,而应用就不同了,不同的客户不同的应用。应用的需求大,所以很多做驱动/硬件的转软件。
但是,一般牛B的软件工程师大多是驱动/硬件工程师转过去的。因为他们知道如何将应用程序很好的控制硬件。