OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3482|回复: 4

奇怪的I/O问题

[复制链接]

4

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2013-5-21
在线时间
8 小时
发表于 2018-4-5 11:13:19 | 显示全部楼层 |阅读模式
1金钱
本人用PB11作为一根半双工通讯, 程序流程如下:
1- 开启外部中断时钟, I/O口时钟,  定时器时钟等等。
2- 开启外部中断——下降沿触发.
3- 当外部中断触发后, 设置PB11为输入状态,  并开启定时器。
4- 在定时器中接收8位数据位后, 接收校验位时,  如果校验错, 则设置PB11为输出状态,  并输出低电平。 【****此时PB11口会出现一段时间的方波,  并非稳定的低电平*****】

以下从程序中摘取的关键部分,  请各位大侠指教!!!!!

//PB11  输出低电平
void Icc_UserCard_IO_Low(void)
{
    GPIO_ResetBits (GPIOB, GPIO_Pin_11);        
}
//PB11  输出高电平
void Icc_UserCard_IO_High(void)
{
    GPIO_SetBits (GPIOB, GPIO_Pin_11);   
}
//置为输入状态
void Icc_UserCardPin_IO_Input(void)//PB11
{   
    //输入
    DWORD dwCRH = GPIOB->CRH;
   
    dwCRH &= ~((DWORD)(0x03 << 12));  //输入状态
    dwCRH &= ~((DWORD)(0x03 << 14));  //清0
    dwCRH |= (DWORD) (0x01 << 14);    //00:模拟输入, 01:浮空输入, 10:上拉/下拉输入,11保留
    GPIOB->CRH = dwCRH;
}
//置为输出状态
void Icc_UserCardPin_IO_Output(void)  //PB11
{

    DWORD dwCRH = GPIOB->CRH;
   
    dwCRH &= ~((DWORD)(0x03 << 12));  //清0, 输入状态
    dwCRH |= (DWORD) (0x01 << 12);    //00:输入,01:10M输出,10:2M输出,11:50M输出
    dwCRH &= ~((DWORD)(0x03 << 14));  //清0
    dwCRH |= (DWORD) (0x01 << 14);  //00:推挽输出, 01:开漏输出, 10:复用推挽输出,11:复用开漏输出, 测试
    GPIOB->CRH = dwCRH;
}
//进入定时器中断
void TIM1_UP_TIM16_IRQHandler(void)  
{   
    BOOL blParityVal = 0;
    int nTest = 0;
   
    if (SET == TIM_GetITStatus (TIM1, TIM_IT_Update))
  {
    TIM_ClearITPendingBit (TIM1, TIM_IT_Update);
        switch (g_ScmIccCom.byRecvDataPtr)
        {      //接收数据位
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                    g_ScmIccCom.byRecvDataPtr++;
                    break;
                    
            case 8: //奇偶校验位
          /**********************************奇偶校验错误****************************************/
          Icc_UserCard_IO_Low();     //拉低I/O口
          Icc_UserCardPin_IO_Output();    //设为输出
校验错误.png
放大图
校验错误_拉低IO_错误部分放大.png
           /**********************************奇偶校验错误****************************************/
                    break;
            
            case 9: //1位停止位
                break;
               
            default:
                   //未知错误
                    
                    break;
        }
        
    }
}
//外部中断配置
void Icc_UserCardPin_Io_Exti_Enable(void) //开启外部中断
{
   
    NVIC_InitTypeDef NVIC_InitStructure;  
    EXTI_InitTypeDef EXTI_InitStructure;  
    GPIO_InitTypeDef GPIO_InitStructure;   
      

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
    GPIO_Init (GPIOB, &GPIO_InitStructure);   
         
    EXTI_ClearITPendingBit (EXTI_Line11);  
    GPIO_EXTILineConfig (GPIO_PortSourceGPIOB, GPIO_PinSource11);   
    EXTI_InitStructure.EXTI_Line = EXTI_Line11;               
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;   
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;   //下降沿  
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;  
    EXTI_Init (&EXTI_InitStructure);  
         
    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     
    NVIC_Init (&NVIC_InitStructure);   
}
//禁止外部中断
void Icc_UserCardPin_IO_Exti_Disable(void)
{
    EXTI->IMR &= ~(1 << 11);
}
//进入外部中断
void EXTI15_10_IRQHandler(void)         
{         
    if (EXTI_GetITStatus (EXTI_Line11) != RESET)
    {  
        EXTI_ClearITPendingBit (EXTI_Line11);
        EXTI->IMR &= ~(1 << 11);    /**********************************禁止外部中断****************************************/
        
        Icc_UserCardPin_IO_Input ();    /**********************************切换为输入状态****************************************/
        TIM1_Config(9600);        //开启定时器,  接收数据,      
    }      
}  

最佳答案

查看完整内容[请看2#楼]

方便出现的时候,肯定是你有设置IO状态,单步跟踪看代码,就知道了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-4-5 11:13:20 | 显示全部楼层
xinyang 发表于 2018-4-7 10:58
case 8: //奇偶校验位
          /**********************************奇偶校验错误******************* ...

方便出现的时候,肯定是你有设置IO状态,单步跟踪看代码,就知道了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-4-7 02:36:57 | 显示全部楼层
仿真找问题
回复

使用道具 举报

4

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2013-5-21
在线时间
8 小时
 楼主| 发表于 2018-4-7 10:58:43 | 显示全部楼层

case 8: //奇偶校验位
          /**********************************奇偶校验错误****************************************/
          Icc_UserCard_IO_Low();               //拉低I/O口
          Icc_UserCardPin_IO_Output();    //设为输出

原子哥就是这步输出低电平的时候,  会有一段时间的方波。   
回复

使用道具 举报

4

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2013-5-21
在线时间
8 小时
 楼主| 发表于 2018-4-10 08:58:14 | 显示全部楼层
感谢原子哥的回复,  已找到原因, 只要再清一次中断标记就好了,TIM_ClearITPendingBit (TIM1, TIM_IT_Update);  非常感谢!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 13:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表