以梦为舟 发表于 2022-4-12 16:42 所以, 你既然 确定了, CLK_DIV |= 0x10 的中继输出 可以满足你的输出需要,(如果输出高电平的驱动力不够,开推挽输出) 你现在唯一需要的就是: 理清楚,前面放弃数据的“过滤条件”, 达到这个条件后, 打开 中继输出 通道,然后达到什么条件以后 再次关闭中继输出, 就是那么简单的一个工作而已。 |
你这个需要的mcu要支持双边沿触发中断,并且时钟够快。 现在所有的mcu都能做到。 引脚变化中断了解下。 |
以梦为舟 发表于 2022-4-8 17:00 把你的代码改了下,应该能做到前20*24bit不接收。
|
其实不太确定你的意图, 你的计数到底计数的什么, 如果是 计数480个下降沿的话, 是不是应该这样? void int4_Routine(void) interrupt 16 { if(++count==480) { CLK_DIV |= 0x10; } if(++count>=9600) { count = 0; CLK_DIV &= 0xEF; } } 这只是一个建议, 因为我没理解你希望的 效果,CLK_DIV 你应该理解为一个 开关,在你认为适当的时候,打开开关 让 P3.1 输出 P3.0 不需要的时候关闭。这个开关只是一个动作,你在某一个中断中 设置 开/关 即可,不需要再while里面反复去操作这个开关。你要知道,STC15系列 即便你 频率定为 35MHz, 1us 可以有35个机器时钟,处理一个if 判断 一个双字节16位数字 需要20个时钟 已经超过 0.5us了,所以,按你的需要你必须把不必要的步骤精简再精简。 |
以梦为舟 发表于 2022-4-6 15:30 设置 CLK_DIV |= 0x10; 之后, P3.1 是 无缝输出 P3.0 电平的,这个过程类似于中继功能是不会有任何差错的(硬件电路问题除外)。检查一下你的外部电路,比如,下载电路是否有断开等等。 作为你的问题“怎么最快将DI口数据赋给DO口?” 就你这个单片机而言,这个方法应该是最快的了,没有之一。 至于,你说的“输入数据的电平被拉低且会使数据码混乱” 我不太理解, 粗看你贴的代码, 也没看出你程序的运行原理, 比如: 1)你 外部中断设定的是 下降沿触发,换句话说只能 DI == 0 的瞬间才触发,你中断里却判断 DI == 1 还是0。 个人认为这是毫无意义的行为。 2)虽然你写了定时期中断, 但是只看到 TR0 = 0 没看到 TR0 =1, 感觉 count = 0 这个操作,对 外部中断没有任何实际作用, 分析不出你贴着两段代码的目的。 最后,你解码必定要有一个接收解析过程吧? 按你说的时序要求,这个解码,或者解析需要严格时间控制的吧? 也没看你在定时器里面解码,所以,诸多不解,看你有什么补充说明再说吧。 |
188610329 发表于 2022-4-4 00:31 把DI定在p3.0口后发现输入数据的电平被拉低且会使数据码混乱,导致整体不受控,这是什么原因.... |
把 DI 定在 P3.0 DO定在 P3.1, 通过: CLK_DIV |= 0x10; 可以直接在 DO 输出 DI 的电平,无需中断,无需任何其他代码,几乎没有延时。 至于你之前说的计数,可以通过 外部中断 EX4 进行计数 来控制打开DO输出:CLK_DIV |= 0x10; 还是关闭DO输出: CLK_DIV &= 0xEF; |
这个是做WS2812的驱动的吧。单片机指令周期都一两百ns了,用程序来处理肯定来不及了。数据400个一组也就是1.2kb,先存下来再转发内存也不够用。不借助外部硬件恐怕是难。你程序直接中转都达到600ns的原因是因为循环跳转和中断出入的代码。单单MOVE bit指令也要3个周期,就算跑到33MHZ也要100ns所以纯软件是不够的。 其实外部借助两颗二极管就可以了,做个简易的与门。收到前期bit后开通这个与门,这样信号就能通过这个与门向后传递。也就没有速度上的问题了,4148处理1MHz这样的信号问题还是不大的。 |