请选择 进入手机版 | 继续访问电脑版

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

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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版