打印

STM32101的PC14和PC15怎么设置为I/O口,可以做为EXTI输入脚么?

[复制链接]
6486|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jessemok|  楼主 | 2008-1-29 17:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
《STM321F10x参考手册第二版》72页说到:
当LSE 振荡器关闭时,LSE 振荡器引脚OSC32_IN/OSC32_OUT 可以分别用做
GPIO 的PC14/PC15,LSE 功能始终优先于通用I/O 口的功能。

试来试去都不行。有没有人详细说明下(给个步骤)。谢谢!
沙发
香水城| | 2008-1-29 18:01 | 只看该作者

关于PC14和PC15设置为I/O口的问题

估计你说的是中文版的《STM321F10x参考手册第二版》,请看24页的第3.1.2节有关于使用PC14和PC15的一些限制。

能否介绍一下你是如何试验的?

关闭LSE只需对备份域控制寄存器(RCC_BDCR)的LSEON写零即可,但请注意LSEON位在复位后处于写保护状态,必须先解除写保护才能操作LSEON;请看56页第4.3.9节的说明。

使用特权

评论回复
板凳
jessemok|  楼主 | 2008-1-29 19:37 | 只看该作者

试验

把PC14 PC15分别接脉冲输入,
(1)RCC_LSEConfig(RCC_LSE_OFF);
(2)设置IO口类型
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);     
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);    
(3)NVIC_Configuration()
{
      ....
      NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQChannel;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);  
}
(4)EXTI_Configuration()
{
    .....
    EXTI_InitStructure.EXTI_Line =  EXTI_Line14;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);    

    EXTI_InitStructure.EXTI_Line =  EXTI_Line15;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);  
}
(5)中断服务程序
void EXTI15_10_IRQHandler(void)
{
    if(EXTI_GetFlagStatus(EXTI_Line14) != RESET)   
    {  
        //Clear the IT flag
        EXTI_ClearFlag(EXTI_Line14);  

    }  
    if(EXTI_GetFlagStatus(EXTI_Line15) != RESET)   
    {  
        if(GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5)!= Bit_RESET)
            GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_RESET); 
        else
            GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET);            
        //Clear the IT flag
        EXTI_ClearFlag(EXTI_Line15);   
     
    }      
}


刚开始Debug,一看,有中断,挺高兴的,以为可以了。谁知道一看PB5波形,
300ms不定时才有一次高低电平切换,我的中断脉冲输入为20ms一次。
用别的IO口试,PB5波形和中断脉冲波形一致。应该是PC14和PC15没有设置好。
并且,不管我中断脉冲有没有给PC14和PC15,都会进入EXTI15_10_IRQHandler()
中的两个if语句中,也就是说EXTI_Line14和EXTI_Line15都有中断。

对于:
关闭LSE只需对备份域控制寄存器(RCC_BDCR)的LSEON写零即可,但请注意LSEON位在复位后处于写保护状态,必须先解除写保护才能操作LSEON;请看56页第4.3.9节的说明。

这个我没有注意,上班的时候试下。

使用特权

评论回复
地板
jessemok|  楼主 | 2008-1-30 13:58 | 只看该作者

再次试验

设置如下:
    PWR_BackupAccessCmd(ENABLE);
    RCC_LSEConfig(RCC_LSE_OFF);

其它和普通I/O口设置相同。做EXTI输入引脚仍不行;作为I/O读写也不成功。

使用特权

评论回复
5
lut1lut| | 2008-1-30 16:25 | 只看该作者

刚刚试了一下作为GPIO output是可以的

(1).使能GPIOC时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  
(2).配置GPIOC
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

(3).然后写高写低
  GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET); 
  GPIO_WriteBit(GPIOC, GPIO_Pin_15, Bit_SET); 
  GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET); 
  GPIO_WriteBit(GPIOC, GPIO_Pin_15, Bit_RESET); 

以上代码跑在两个板子上,一个是backup区域里的RCC_DBCR的LSEON为0,即LSE关闭,以上(3)的操作从示波器上看到了电平相应变换;另外一个板子,backup区域里的RCC_DBCR的LSEON为1,即LSE打开,则以上(3)的操作从示波器上看到无效。

作为输入和外部中断,还没有试~~~

使用特权

评论回复
6
lut1lut| | 2008-1-30 16:44 | 只看该作者

又试了一下GPIO input也是可以的

只是把以上的(2)稍微改一下,(3)就不用了
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

外部连接为:在PC14引脚焊了一个电阻,电阻另一端通过跳线在上拉到3.3V和下拉到地的两种情况下,读出GPIOC_IDR.14分别为"1"和"0"。

接着我再找一个按键来试一下外部中断~~~

使用特权

评论回复
7
lut1lut| | 2008-1-30 17:31 | 只看该作者

外部中断也是好使的阿

1.时钟使能
// + osc32_in/out --> pc14/15
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_AFIO, ENABLE);
注意要使能AFIO的时钟哦

2.中断配置 
  // + for EXTI on PC.14 at falling edge
  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

3. GPIO配置同上
4. EXTI配置
// + for PC14 EXTI @ falling edge
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource14);
  EXTI_InitStructure.EXTI_Line = EXTI_Line14;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

5. 中断处理ISR
void EXTI15_10_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line14) != RESET)
  {
    /* Clear the EXTI line 9 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line14);
  }
}

在中断处设置断点,
只要按下key,就进入中断,跑出中断,再按key,再次进入,屡试不爽,试验完成~~~


使用特权

评论回复
8
jessemok|  楼主 | 2008-1-30 19:53 | 只看该作者

整明白咋回事了

整明白咋回事了!谢谢lut1lut的实验。

原因是没有使能AFIO的时钟!打开AFIO,上述实验全部OK!
其实系统复位时,LSE是关闭的,也就是说,可以不用设置LSE了,只要把AFIO时钟打开就可以!

但另一个问题又出来了,之前使用了两个外部中断,一直没有打开AFIO,使用
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
把EXTI中断4映射到PA4上,这个外部中断也用得好好的....

使用特权

评论回复
9
香水城| | 2008-1-30 21:06 | 只看该作者

嗯,PC14和PC15属于AFIO,所以要使能AFIO的时钟

而你之前用的PA4是普通IO,所以不必使能AFIO的时钟。

使用特权

评论回复
10
jessemok|  楼主 | 2008-2-1 16:15 | 只看该作者

使能AFIO

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
里面有对AFIO寄存器的操作也不用使能AFIO么?

使用特权

评论回复
11
wzz225| | 2008-6-27 15:06 | 只看该作者

jessemok

jessemok    3Q

使用特权

评论回复
12
edwinsong| | 2010-3-10 20:08 | 只看该作者
兄弟,我在pc14和pc15上也出现了问题,程序如下:   
   RCC_LSEConfig(RCC_LSE_OFF);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC
         | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG
         | RCC_APB2Periph_AFIO, ENABLE);
   
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET);
  GPIO_WriteBit(GPIOC, GPIO_Pin_15, Bit_SET);
  GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET);
  GPIO_WriteBit(GPIOC, GPIO_Pin_15, Bit_RESET);
但是PC14和PC15还是没有变化,依然是低电平,希望你能帮我解答一下,谢谢~~
3# jessemok

使用特权

评论回复
13
rtgchym| | 2013-8-23 19:06 | 只看该作者
edwinsong 发表于 2010-3-10 20:08
兄弟,我在pc14和pc15上也出现了问题,程序如下:   
   RCC_LSEConfig(RCC_LSE_OFF);

我也遇到这个问题了,请问您当时怎么解决的?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

91

帖子

2

粉丝