qazplm3218 发表于 2019-4-12 17:29:06

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

硬件连接:主控板采用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口检测速度太慢造成的?用其他单片机的显示模块显示这些数据都非常快的,很流畅,不会出现迟缓更新和停顿现象,而且对数据的接收处理程序也是一样的方法。我是真搞不懂了????

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=temp1>>8;
        }
}


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

                        case 0x40: DC_V=temp1;send_buf=temp1;break;                       
                        case 0x50: DC_V=temp1;send_buf=temp1;break;
                        case 0x60: DC_V=temp1;send_buf=temp1;break;
                                                                                                                //   
                        case 0x70: AC_V=temp1;send_buf=temp1;break;                       
                        case 0x80: AC_V=temp1;send_buf=temp1;break;
                        case 0x90: AC_V=temp1;send_buf=temp1;break;
                                                                                                                //   
                        case 0xa0: YJ_V=temp1;break;                                                                                               
                        case 0xb0: YJ_V=temp1;break;
                        case 0xc0: YJ_V=temp1;break;

                        case 0xd0: YJ_I=temp1;send_buf=temp1;break;               
                        case 0xe0: YJ_I=temp1;send_buf=temp1;break;
                        case 0xf0: if(temp1>9){temp1=0;}YJ_I=temp1;send_buf=temp1;break;               
       
                        default:
                                                               break;

    }
                       
}
}



TLLED 发表于 2019-4-12 17:50:10

是不是程序在数据处理部分延时比较长

qazplm3218 发表于 2019-4-12 18:18:29

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

数据处理部分就一条systick_delay_us(1);
把这条延时取消掉也是一样的效果!!

select326 发表于 2019-4-12 20:51:41

抓个波形看看。

不过,没看到data_input 函数。。

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

stm1024 发表于 2019-4-12 21:52:22

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

toofree 发表于 2019-4-13 00:28:56

不想说啥了,程序问题。
有问题的没列出来,列出来的没问题。
好好排查吧。
你的通信机制可能有问题,AVR准备好数据后,要通过一根线告诉STM32,可以读了。
STM32用IO中断触发读数据。

五哥1 发表于 2019-4-13 05:56:58

你的硬件部分是不是无字库12864的屏,忙检测程序在哪?用030芯片都能驱动展示数据,建议你再优化下程序。

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 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();
}




页: [1] 2
查看完整版本: STM32F103 IO口设置为输入状态问题??