查看: 644  |  回复: 12
求助,利用梁山派EXMC模拟8位并口8080时序数据之间不连续出现杂乱信号
靠谱的成年人
1
主题
7
回复
发表于2024-01-09 19:07:58 | ip属地:黑龙江 | 只看该作者
1# 电梯直达

最近在使用梁山派驱动一块LCD屏幕,同时也准备学习一下EXMC外设,使用的屏幕是8080驱动。于是从立创开发板提供的例程里面找到了关于16位并口的LCD驱动代码,下面是移植来的初始化代码:


void exmc_gpio_init(void)

{

    rcu_periph_clock_enable(RCU_GPIOD);

    rcu_periph_clock_enable(RCU_GPIOE);

   rcu_periph_clock_enable(RCU_GPIOG);

   gpio_af_set(GPIOD, GPIO_AF_12, GPIO_PIN_0|GPIO_PIN_1

   |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15); // EXMC功能

   gpio_af_set(GPIOE, GPIO_AF_12, GPIO_PIN_7|GPIO_PIN_8

       |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15); // EXMC功能

   gpio_af_set(GPIOG, GPIO_AF_12, GPIO_PIN_0|GPIO_PIN_12); // EXMC功能

   gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_0|GPIO_PIN_1

       |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15);

   gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_0|GPIO_PIN_1

       |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15);

   gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7|GPIO_PIN_8

       |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);

   gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7|GPIO_PIN_8

       |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);

   gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_0|GPIO_PIN_12);

   gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_0|GPIO_PIN_12);

}

void exmc_init(void)

{

    exmc_gpio_init();


    rcu_periph_clock_enable(RCU_EXMC);


    exmc_norsram_parameter_struct nor_init_struct; // EXMC参数结构体

   exmc_norsram_timing_parameter_struct readWriteTiming; // EXMC时间参数结构体

   exmc_norsram_timing_parameter_struct writeTiming; // EXMC时间参数结构体


    /* 读写时间 */

   readWriteTiming.asyn_access_mode = EXMC_ACCESS_MODE_A; //模式A    

   readWriteTiming.syn_data_latency = EXMC_DATALAT_2_CLK;

   readWriteTiming.syn_clk_division = EXMC_SYN_CLOCK_RATIO_2_CLK;

   readWriteTiming.bus_latency = 0;

   readWriteTiming.asyn_data_setuptime = 72; //需要360ns数据保存时间为72个HCLK =5*72=360ns

   readWriteTiming.asyn_address_holdtime = 0x00; //地址保持时间(ADDHLD)模式A未用到

   readWriteTiming.asyn_address_setuptime = 18; //需要96ns  地址建立时间(ADDSET)为19个HCLK 1/200M=5ns*19=96ns

   /* 读写时间 */

   writeTiming.asyn_access_mode = EXMC_ACCESS_MODE_A; //模式A    

   writeTiming.syn_data_latency = EXMC_DATALAT_2_CLK;

   writeTiming.syn_clk_division = EXMC_SYN_CLOCK_RATIO_2_CLK;

   writeTiming.bus_latency = 0;

   writeTiming.asyn_data_setuptime = 4; //需要18ns数据保存时间为11个HCLK =5*4=18ns

   writeTiming.asyn_address_holdtime = 0x00; //地址保持时间(ADDHLD)模式A未用到

   writeTiming.asyn_address_setuptime = 3; //需要18ns  地址建立时间(ADDSET)为11个HCLK 1/200M=5ns*4=18ns

   /* configure EXMC bus parameters */

   nor_init_struct.norsram_region = EXMC_BANK0_NORSRAM_REGION3;

   // FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;// FSMC_Bank1_NORSRAM4;//  这里使用NE1 ,也就对应BTCR[6],[7]。

   nor_init_struct.address_data_mux = DISABLE; // 不复用数据地址

   nor_init_struct.memory_type = EXMC_MEMORY_TYPE_SRAM;  // FSMC_MemoryType_SRAM;  //SRAM

   nor_init_struct.databus_width = EXMC_NOR_DATABUS_WIDTH_8B;

   nor_init_struct.burst_mode = DISABLE;

   nor_init_struct.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;

   nor_init_struct.asyn_wait = DISABLE;

   nor_init_struct.wrap_burst_mode = DISABLE;

   nor_init_struct.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;

   nor_init_struct.memory_write = ENABLE;//  存储器写使能

   nor_init_struct.nwait_signal = DISABLE;

   nor_init_struct.extended_mode = ENABLE;  // 读写使用不同的时序

   nor_init_struct.write_mode = EXMC_ASYN_WRITE;

   nor_init_struct.read_write_timing = &readWriteTiming;//读写时序

   nor_init_struct.write_timing = &writeTiming;//写时序

   exmc_norsram_init(&nor_init_struct); //初始化FSMC配置

   /* enable the EXMC bank0 NORSRAM */

   exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION3);   // 使能BANK1

}


对例程里面的16位数据格式改成了8位数据格式,其他没变;

  

  

  

以上是编写的三个写入函数。并尝试发送以下数据测试波形情况发现发送的两个数据之间出现一段不规律的杂乱信号:

 

 

可以发现每一个正确数据之后总会发送一些0数据,然而运行梁山派提供的16位8080并口例程则可以正确发送,一下是梁山派例程运行结果,只抓取低8位数据验证:

 

 



向各位大佬求助,我的代码问题出在了哪里呀


老怪鸽但不鸽
6
主题
22
回复
发表于2024-01-11 16:32:45   |  ip属地:广东  |  只看该作者
2#
你是怎么接线的呢?使用8位的数据地址线不会偏移,而梁山派上的扩展接口是地址线是EXMC_A10,所以写地址应该是3FE,读地址是400
靠谱的成年人
1
主题
7
回复
发表于2024-01-11 16:41:16   |  ip属地:黑龙江  |  只看该作者
3#
老怪鸽但不鸽 发表于2024-01-11 16:32:45  2# 你是怎么接线的呢?使用8位的数据地址线不会偏移,而梁山派上的扩展接口是地址线是EXMC_A10,所以写地址应该是3FE,...
0x6C000400和0x6C000000我也试过了结果一样
老怪鸽但不鸽
6
主题
22
回复
发表于2024-01-11 16:45:49   |  ip属地:广东  |  只看该作者
4#

那修改初始化代码中的读写时间,根据屏幕的读写时序来计算

 

例如 writeTiming.asyn_data_setuptime = 4; //需要18ns数据保存时间为11个HCLK =5*4=18ns

示例中的 5 表示的是执行一句语句的时间,是使用 1/主频 得来。
主频设置为 200MHz,那么 1/200 000 000 = 0.000000005 = 5ns

靠谱的成年人
1
主题
7
回复
发表于2024-01-11 16:46:03   |  ip属地:黑龙江  |  只看该作者
5#
老怪鸽但不鸽 发表于2024-01-11 16:32:45  2# 你是怎么接线的呢?使用8位的数据地址线不会偏移,而梁山派上的扩展接口是地址线是EXMC_A10,所以写地址应该是3FE,...
修改成3FE和400之后的 
靠谱的成年人
1
主题
7
回复
发表于2024-01-11 16:49:29   |  ip属地:黑龙江  |  只看该作者
6#
老怪鸽但不鸽 发表于2024-01-11 16:45:49  4# 那修改初始化代码中的读写时间,根据屏幕的读写时序来计算例如writeTiming.asyn_data_setuptime...

我没用到读命令

  

这是屏幕时序的时间约束,最小10ns我设置的18ns应该是可以的呀

靠谱的成年人
1
主题
7
回复
发表于2024-01-11 16:51:41   |  ip属地:黑龙江  |  只看该作者
7#
老怪鸽但不鸽 发表于2024-01-11 16:45:49  4# 那修改初始化代码中的读写时间,根据屏幕的读写时序来计算例如writeTiming.asyn_data_setuptime...
主要是现在不看屏幕的话单独看配置好后的数据位输出,每个数据的波形也不正确呀
老怪鸽但不鸽
6
主题
22
回复
发表于2024-01-11 16:56:59   |  ip属地:广东  |  只看该作者
8#
靠谱的成年人 发表于2024-01-11 16:51:41  7# 主要是现在不看屏幕的话单独看配置好后的数据位输出,每个数据的波形也不正确呀
现在越看越像是被开发板上的SDRAM干扰了
靠谱的成年人
1
主题
7
回复
发表于2024-01-11 16:59:52   |  ip属地:黑龙江  |  只看该作者
9#
老怪鸽但不鸽 发表于2024-01-11 16:56:59  8# 现在越看越像是被开发板上的SDRAM干扰了
我这里为了排除其他可能原因尽可能和历程代码一模一样啦,算是只改了例程里面16位数据位那里。如果说SDRAM的影响的话例程里面不也应该是这样不正确的数据嘛
老怪鸽但不鸽
6
主题
22
回复
发表于2024-01-11 17:05:19   |  ip属地:广东  |  只看该作者
10#
靠谱的成年人 发表于2024-01-11 16:59:52  9# 我这里为了排除其他可能原因尽可能和历程代码一模一样啦,算是只改了例程里面16位数据位那里。如果说SDRAM的影响的话例程...
确定是只修改了16位数据位那里,修改为8位吗? 我这边飞线测测
靠谱的成年人
1
主题
7
回复
发表于2024-01-11 17:13:01   |  ip属地:黑龙江  |  只看该作者
11#
老怪鸽但不鸽 发表于2024-01-11 17:05:19  10# 确定是只修改了16位数据位那里,修改为8位吗?我这边飞线测测
对呀,我直接复制过来的初始化
老怪鸽但不鸽
6
主题
22
回复
发表于2024-01-12 10:35:21   |  ip属地:广东  |  只看该作者
12#
1. 实测,当处于8位数据宽度时,写命令地址0X000003FE,写数据地址0X00000400,A10引脚才可以实现电平变化;
2. 关于两个数据之间出现一段不规律的杂乱信号,我使用梦源逻辑分析仪在 10MHz 下抓取数据确实有这个现象,但当使用 20MHz 时,没有出现杂波。
3. 使用IO模拟8080时序可以控制8位并口LCD;
时序源码:
 
时序:从上到下的时序线分别为 CS DC WR RD D0~D7
  
使用8位EXMC模拟8080无法控制8位并口LCD;
源码:
 

时序图:时序图的线序同上,但是发现数据线的时序过早拉低;

  

使用16位EXMC模拟8080驱动8位并口LCD,将高位省略只使用低位即可驱动;
源码与时序:抓取数据0X22

 
总结:使用16位EXMC驱动8位并口即可;

靠谱的成年人
1
主题
7
回复
发表于2024-01-12 18:24:33   |  ip属地:黑龙江  |  只看该作者
13#

解决啦,将发送函数改成这样就好啦

   



主题

回复
  • 温馨提示: 标题不合格、重复发帖、发布广告贴,将会被删除帖子或禁止发言。 详情请参考: 社区发帖规则
  • 您当前输入了 0 个文字。还可以输入 8000 个文字。 已添加复制上传图片功能,该功能目前仅支持chrome和火狐

禁言/删除

X
请选择禁言时长:
是否清除头像:
禁言/删除备注:
昵 称:
 
温馨提示:昵称只能设置一次,设置后无法修改。
只支持中文、英文和数字。

举报

X
请选择举报类型:
请输入详细内容:

顶部