你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103 IO口设置为输入状态问题??

[复制链接]
qazplm3218 提问时间:2019-4-12 17:29 /
硬件连接:主控板采用AVR单片机,单片机的IO口PA0-PA7直接连接在显示模块LCD12864(STM32F103驱动)的IO口PB8-PB15,STM32F103的PB8-PB15设置为输入口(上拉输入/浮空输入),主控板通过这8根数据线向STM32F103传输数据。数据包括交流电压、电流电流、故障等数据。问题: 显示模块LCD12864(STM32F103驱动)效果应该是实时更新这个数据的,不会产生迟缓或者停顿。但是现在显示这些数据非常迟缓,3-5秒才更新这些数据。而且程序主要就是LCD12864的驱动程序和对STM32F103的PB8-PB15数据接收处理程序,出现这样现象有没有可能是STM32F103对PB8-PB15的IO口检测速度太慢造成的?用其他单片机的显示模块显示这些数据都非常快的,很流畅,不会出现迟缓更新和停顿现象,而且对数据的接收处理程序也是一样的方法。我是真搞不懂了????
收藏 评论18 发布时间:2019-4-12 17:29

举报

18个回答
qazplm3218 回答时间:2019-4-12 17:35:48
程序如下:
void signal_io_init(void)                //IO口设置                                                                                                                                                                               
{
        GPIO_InitTypeDef my_gpioa;                                                                                                                                                                               
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                                                                                       
        my_gpioa.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
        //my_gpioa.GPIO_Mode=GPIO_Mode_IPU;                                                                                                                                                               
        my_gpioa.GPIO_Mode=GPIO_Mode_IN_FLOATING;                                                                                                                                       
        //my_gpioa.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&my_gpioa);                                                                                                                                                                                       
}


void rec_port(void)                                                                        //接收IO口数据
{
        uint32_t temp0,temp1,i;
        for(i=0;i<16;i++)
        {        
                temp0=data_input();
                temp1=temp0;
                //__NOP();__NOP();
                systick_delay_us(1);
                temp0=data_input();
                if(temp0==temp1) continue;
                data_buf[i]=temp1>>8;
        }
}


void rec_data(void)                                                                        //处理IO口数据
{
  uint8_t j,temp0,temp1;
  for(j=0;j<16;j++)
  {
    temp0=data_buf[j];
    temp1=temp0;       
    temp0&=0xf0;
    temp1&=0x0f;               
    switch(temp0)
    {
                        case 0x00: ERR1[0]=temp1;break;                                                                                               
                        case 0x10: ERR1[1]=temp1;break;
                        case 0x20: ERR1[2]=temp1;break;
                        case 0x30: ERR1[3]=temp1;break;

                        case 0x40: DC_V[0]=temp1;send_buf[4]=temp1;break;                       
                        case 0x50: DC_V[1]=temp1;send_buf[5]=temp1;break;
                        case 0x60: DC_V[2]=temp1;send_buf[6]=temp1;break;
                                                                                                                //     
                        case 0x70: AC_V[0]=temp1;send_buf[7]=temp1;break;                       
                        case 0x80: AC_V[1]=temp1;send_buf[8]=temp1;break;
                        case 0x90: AC_V[2]=temp1;send_buf[9]=temp1;break;
                                                                                                                //     
                        case 0xa0: YJ_V[0]=temp1;break;                                                                                               
                        case 0xb0: YJ_V[1]=temp1;break;
                        case 0xc0: YJ_V[2]=temp1;break;

                        case 0xd0: YJ_I[0]=temp1;send_buf[13]=temp1;break;               
                        case 0xe0: YJ_I[1]=temp1;send_buf[14]=temp1;break;
                        case 0xf0: if(temp1>9){temp1=0;}YJ_I[2]=temp1;send_buf[15]=temp1;break;                   
         
                        default:
                                                                 break;

    }  
                       
  }
}



qazplm3218 回答时间:2019-4-13 08:47:22
五哥1 发表于 2019-4-13 05:56
你的硬件部分是不是无字库12864的屏,忙检测程序在哪?用030芯片都能驱动展示数据,建议你再优化下程序。 ...

是不带字库的LCD12864屏
没有Check Busy函数,直接用延时函数代替

void lcd_write_com(uint32_t data)        //LCD12864写指令函数
{   
  //systick_delay_us(10);
        Delay(0x60);
  lcd_rs_clr();
        __NOP();__NOP();__NOP();__NOP();__NOP();
        lcd_data(data);
  lcd_e_set();
        __NOP();__NOP();__NOP();__NOP();__NOP();
  lcd_e_clr();
        __NOP();__NOP();__NOP();__NOP();__NOP();
}

void lcd_write_com(uint32_t data)        //LCD12864写数据函数
{
  //systick_delay_us(10);
        Delay(0x60);
  lcd_rs_clr();
        __NOP();__NOP();__NOP();__NOP();__NOP();
        lcd_data(data);
  lcd_e_set();
        __NOP();__NOP();__NOP();__NOP();__NOP();
  lcd_e_clr();
        __NOP();__NOP();__NOP();__NOP();__NOP();
}
qazplm3218 回答时间:2019-4-13 08:46:05
stm1024 发表于 2019-4-12 21:52
你的代码中对LCD12864做了Check Busy吗?否则过高频率的写数据会导致12864更新缓慢。
我们之前的做法是,例 ...


没有Check Busy函数,直接用延时函数代替

void lcd_write_com(uint32_t data)        //LCD12864写指令函数
{   
  //systick_delay_us(10);
        Delay(0x60);
  lcd_rs_clr();
        __NOP();__NOP();__NOP();__NOP();__NOP();
        lcd_data(data);
  lcd_e_set();
        __NOP();__NOP();__NOP();__NOP();__NOP();
  lcd_e_clr();
        __NOP();__NOP();__NOP();__NOP();__NOP();
}

void lcd_write_com(uint32_t data)        //LCD12864写数据函数
{
  //systick_delay_us(10);
        Delay(0x60);
  lcd_rs_clr();
        __NOP();__NOP();__NOP();__NOP();__NOP();
        lcd_data(data);
  lcd_e_set();
        __NOP();__NOP();__NOP();__NOP();__NOP();
  lcd_e_clr();
        __NOP();__NOP();__NOP();__NOP();__NOP();
}




TLLED 回答时间:2019-4-12 17:50:10
是不是程序在数据处理部分延时比较长

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

qazplm3218 回答时间:2019-4-12 18:18:29
TLLED 发表于 2019-4-12 17:50
是不是程序在数据处理部分延时比较长

数据处理部分就一条systick_delay_us(1);
把这条延时取消掉也是一样的效果!!
CC4 回答时间:2019-4-12 20:51:41
抓个波形看看。

不过,没看到data_input 函数。。

尝试分开测试。先把接收数据 单独测试下,看看速度如何。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

STM1024 回答时间:2019-4-12 21:52:22
你的代码中对LCD12864做了Check Busy吗?否则过高频率的写数据会导致12864更新缓慢。
我们之前的做法是,例如一些模拟量采集,采样频率非常高,在每个MCU执行周期的时候,如果Check Busy了,则累积,然后等到不忙的时候,把忙的这段时间求平均再显示,这样就解决了刷新和采样波动较大的问题

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

七哥 回答时间:2019-4-13 00:28:56
不想说啥了,程序问题。
有问题的没列出来,列出来的没问题。
好好排查吧。
你的通信机制可能有问题,AVR准备好数据后,要通过一根线告诉STM32,可以读了。
STM32用IO中断触发读数据。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

五哥1 回答时间:2019-4-13 05:56:58
你的硬件部分是不是无字库12864的屏,忙检测程序在哪?用030芯片都能驱动展示数据,建议你再优化下程序。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

qazplm3218 回答时间:2019-4-13 08:42:08
select326 发表于 2019-4-12 20:51
抓个波形看看。

不过,没看到data_input 函数。。

#define data_input()                GPIOB->IDR&0xFF00          //主板给显示模块传输数据入口
qazplm3218 回答时间:2019-4-13 09:50:59
我又重新测试了下,接收数据处理后,不送LCD12864屏,直接送到74HC595,驱动8个指示灯显示,更新速度也是要好几秒,迟缓,卡顿。难道说明STM32F103对输入引脚的检测速度不够快吗?之前用PIC16系列和AVR系列没出现过这种现象,实时显示数据很流畅的
STM1024 回答时间:2019-4-13 10:14:22
qazplm3218 发表于 2019-4-13 08:46
没有Check Busy函数,直接用延时函数代替

void lcd_write_com(uint32_t data)        //LC ...

10us估计不够吧?
qazplm3218 回答时间:2019-4-13 10:30:10
stm1024 发表于 2019-4-13 10:14
10us估计不够吧?

我把这个时间加长也是一样的现象。
我又重新测试了下,接收数据处理后,不送LCD12864屏,直接送到74HC595,驱动8个指示灯显示,更新速度也是要好几秒,迟缓,卡顿,程序里就只有数据处理程序和74HC595驱动
CC4 回答时间:2019-4-13 11:34:11
我觉得你可以做一个转发实验,这边接收,然后再转发出去。这样,然后抓个波形,测量下速度。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

12下一页

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版