您当前的位置:五五电子网电子知识电子学习基础知识电脑-单片机-自动控制STM32单片机基础学习:从勉强看懂一行程序到IO口研究 正文
STM32单片机基础学习:从勉强看懂一行程序到IO口研究

STM32单片机基础学习:从勉强看懂一行程序到IO口研究

点击数:7210 次   录入时间:03-04 11:37:43   整理:http://www.55dianzi.com   电脑-单片机-自动控制
  最后用一段电子荧火虫(也就是呼吸灯)的简单程序作为结束。
  int main(void)
  { uint8_t Count;
  uint32_t DelayTim=“0x1000”; //基数
  uint32_t ChangTim=“0x2000”; //每次变化的量
  Init_All_Periph();
  while(1)
  {
  for(Count=0;Count《16;Count++) //渐亮
  {
  GPIO_SetBits(GPIOD, GPIO_PIN_8); //点亮灯
  Delay(DelayTim+Count*ChangTim);
  GPIO_ResetBits(GPIOD, GPIO_Pin_8); //熄灭灯
  Delay(DelayTim+(16-Count)*ChangTim);
  }
  for(Count=16;Count》0;Count--) //渐暗
  {
  GPIO_SetBits(GPIOD, GPIO_Pin_8); //点亮灯
  Delay(DelayTim+Count*ChangTim);
  GPIO_ResetBits(GPIOD, GPIO_Pin_8); //熄灭灯
  Delay(DelayTim+(16-Count)*ChangTim);
  }
  }
  }
  定时器初步
  接下来研究定时器。为什么开始研究定时器了呢?那个I/O还是刚刚开了头啊,还有很多很多知识没有掌握!不怕,方法论告诉我们:对事物的认识是螺旋式上升的,所以不要一杆子打到底,想着把I/O口的所有情况都掌握了再学下面的,那会是很困难的
  STM32的定时器是什么样子的,心里一点底也没有,还是找个现成的例子来吧。在ST提供的库里,有很多的例子
  第一个就是它了。
  
  把整个文件夹复制一份到自己的实验文件夹中
  
  在Source文件夹中再建立名为APP的文件夹,将上图中所有源程序文件全部复制到APP文件夹中。然后将库所提供的CMSIS文件夹和 STM32F10x_StdPeriph_Driver文件夹复制到Source文件夹中。然后按照前面的方法建立项目。
  
  这是建好的项目的结构。
  下面开始研究,首先看附带的readme.txt文件,了解到该例子的大体用途是验证Tim2的Output Compare Timing mode的。于是打开PDF文件,直接翻到下面的位置:
  -----------------------------------------------------------------------------------------

 13.3.8 输出比较模式
  此项功能是用来控制一个输出波形或者指示何时一段给定的的时间已经到时。
  当计数器与捕获/比较寄存器的内容相同时,输出比较功能做如下操作:
  ● 将输出比较模式(TIMx_CCMRx寄存器中的OCxM位)和输出极性(TIMx_CCER寄存器中的CCxP位)定义的值输出到对应的管脚上。在比较匹配时,输出管脚可以保持它的电平
  (OCxM=000)、被设置成有效电平(OCxM=001)、被设置成无有效电平(OCxM=010)或进行翻转(OCxM=011)。
  ● 设置中断状态寄存器中的标志位(TIMx_SR寄存器中的CCxIF位)。
  ● 若设置了相应的中断屏蔽(TIMx_DIER寄存器中的CCXIE位),则产生一个中断。
  ● 若设置了相应的使能位(TIMx_DIER寄存器中的CCxDE位,TIMx_CR2寄存器中的CCDS位选择DMA请求功能),则产生一个DMA请求。
  TIMx_CCMRx中的OCxPE位选择TIMx_CCRx寄存器是否需要使用预装载寄存器。
  在输出比较模式下,更新事件UEV对OCxREF和OCx输出没有影响。
  同步的精度可以达到计数器的一个计数周期。输出比较模式(在单脉冲模式下)也能用来输出一个单脉冲。
  输出比较模式的配置步骤:
  1. 选择计数器时钟(内部,外部,预分频器)
  2. 将相应的数据写入TIMx_ARR和TIMx_CCRx寄存器中
  3. 如果要产生一个中断请求和/或一个DMA请求,设置CCxIE位和/或CCxDE位。
  4. 选择输出模式,例如:必须设置OCxM=’011’、OCxPE=’0’、CCxP=’0’和CCxE=’1’,当计数器CNT与CCRx匹配时翻转OCx的输出管脚,CCRx预装载未用,开启OCx输出且高电平有效。
  5. 设置TIMx_CR1寄存器的CEN位启动计数器--------------------------------------------------------------------------------
  说得并不复杂,但是要弄清楚也绝非易事,况且main.c中一系列的符号究竟是什么意思也不是那么容易搞清楚的。这些东西搞不清,将来自己编程时,就算想要依葫芦画瓢都难。怎么办呢?可能并没有多少偷巧的办法,只能是一步一步地摸索吧。
  进入调试,打开Peripherals-》Timers-》Tim2,出现下面的窗口。
  
  然后单步执行程序,并观察界面的变化,并将这些符号作为线索,在PDF文件,stmf10x_tim.c等文件中搜索,了解相关符号的含义。
  如下图是执行到:while(1)前,也就是所有设置完成后的图。
  

沿着这些线索一路追踪,边看源程序,边找数据手册,边找相关的头文件,其他源程序,总算大体有了个明白,下面将main.c中的部分代码作为注释,也算是做点记录。
  /* Includes ------------------------------------------------------------------*/
  #include “stm32f10x.h”
  //这个头文件需要根据所选择的芯片进行更改
  /* Private variables ---------------------------------------------------------*/
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure; //定义两个结构型变量
  __IO uint16_t CCR1_Val = 49152;
  __IO uint16_t CCR2_Val = 32768;
  __IO uint16_t CCR3_Val = 16384;
  __IO uint16_t CCR4_Val = 8192; //
  ErrorStatus HSEStartUpStatus;
  /* Private function prototypes -----------------------------------------------*/
  void RCC_Configuration(void);
  void GPIO_Configuration(void);
  void NVIC_Configuration(void);
  int main(void)
  {
  /* System CLOCks Configuration */
  RCC_Configuration();
  /* NVIC Configuration */
  NVIC_Configuration();
  /* GPIO Configuration */
  GPIO_Configuration();
  /* ---------------------------------------------------------------
  TIM2 Configuration: Output Compare Timing Mode:
  TIM2CLK = 36 MHz, Prescaler = 4, TIM2 counter clock = 7.2 MHz
  CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz
  CC2 update rate = TIM2 counter clock / CCR2_Val = 219.7 Hz
  CC3 update rate = TIM2 counter clock / CCR3_Val = 439.4 Hz
  CC4 update rate = TIM2 counter clock / CCR4_Val = 878.9 Hz
  --------------------------------------------------------------- */
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 65535; //它对应TIM2_ARR
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  /* 它对应TIM2_PSC,相关代码如下(stm32f10x_tim.c中):
  TIMx-》PSC = TIM_TimeBaseInitStruct-》TIM_Prescaler;
  但很奇怪,这里令其为0,然后再在下面设置为4??为何??
  */
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0200;
  //ClockDivision是对CKD位进行设置的,但是这个必须要自己给其赋正确的值
  /*在stm32f10_tim.c文件中是这样操作的
  TIMx-》CR1 |= (uint32_t)TIM_TimeBaseInitStruct-》TIM_ClockDivision |
  TIM_TimeBaseInitStruct-》TIM_CounterMode;
  */
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  /*计数模式,st32f10x_tim.h中定义,其他可用的符号还有:
  TIM_CounterMode_Up,TIM_CounterMode_Down,TIM_CounterMode_CenterAligned1
  TIM_CounterMode_CenterAligned2,TIM_CounterMode_CenterAligned3
  */
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  /* Prescaler configuration */
  TIM_PrescalerConfig(TIM2, 4, TIM_PSCReloadMode_Immediate);
  /*stm32f10x_tim.c中相关代码:
  TIMx-》PSC = Prescaler;

上一页  [1] [2] [3] [4]  下一页


本文关键字:单片机  程序  电脑-单片机-自动控制电子学习 - 基础知识 - 电脑-单片机-自动控制