# DMA_PWM **Repository Path**: coding-migration-project/DMA_PWM ## Basic Information - **Project Name**: DMA_PWM - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-08-03 - **Last Updated**: 2024-08-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 方案一 ## 运行机制 + 通过软中断触发脉冲数据装载和发送 + 软中断触发的机制是如果脉冲数组不为0并且时间已经超过了30ms,自动触发软中断,用于机械臂启动时候,脉冲数从0变为非零的过程 + 软中断一旦启动,便会自动在脉冲数发送过半的时候自动触发软中断去装载和计算下一个周期要发送的脉冲数 + 如果运动停止,脉冲变量全部变为0,则软中断也会随即停止触发 + 通过上位机计算了一个频率参数表,由于一个频率的产生可以通过PSC寄存器和ARR寄存器去共同控制,并且有多组解,那么选择一组频率误差最小的PSC和ARR就有必要了 + PSC和ARR的范围都是0-65535,如果只是变化一个无法产生0-160k全范围的频率,只改变一个寄存器频率粒度大约是1k(72000000/65535) ## 频率装载和计算的过程 + 第一次进入的时候,dma_len需要增加1,否则会少一个脉冲,可能是DMA的bug + 如果进入的时候发现该通道的脉冲数为0,则dma_len直接为0 + 装载的时候也会根据dma_len是否为0来决定是否要开启dma,如果所有通道都为0了, 也就不会触发装载发送过程 + 设置了最小的ARR value为2, 方便计算占空比的时候至少可以为1 + 如果是超时触发的频率装载(从停止到启动的第一次),则会清除半完成和完成标志 + 如果不是超时触发的计算,则是所有通道半完成触发的计算,会将频率缓存到fifo,以便这一次全部完成后载入数据发送 + 计算由timeout标志第一次触发,调用 execute_dma_channel ,完成过程中会分别触发半完成和完成中断 + 半完成中断处理函数里面检查是否所有通道都已经半完成,触发软中断,从而调用装载函数,将通道下一次要发送的结果存入到fifo + 完成中断处理函数函数里面会检查是否所有通道都已经完成,然后触发调用 execute_dma_channel来继续下一次循环 ## execute_dma_channel + 如果脉冲个数大于等于2,则会使能dma发送 + 如果脉冲个数为1,则不会触发dma发送,设置半完成标志 + 如果脉冲个数为0,也不会触发dma发送,设置半完成和完成标志 + 如果三个通道都是1或者0,则实际不会触发dma发送,也不会触发软中断,数据发送也就停止了,下一次触发就需要超时条件来触发了 # 方案二 + 通过生产者消费者模型来加载要发送的数据 + 解耦生产者和消费者二者之间的耦合同步关系,生产者只管生产不用担心什么时候消费完 + 消费者只管消费,不用管生产者什么时候生产 + 需要禁止之前的半完成中断,否则会一直在中断里面无法退出 # 问题点 + 一个周期至少要三个脉冲才能准确输出 + 只有1个或者2个脉冲的时候不能准确输出 + 设定走3个脉冲的时候,有时候会走4个脉冲 + 一个周期最多50个脉冲 # 方案三 + 修改DMA的方式,通过缓存存储脉冲个数 +