This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C123GH6PM:TM4C123G DMA+PWM

Guru**** 2535750 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/936568/tm4c123gh6pm-tm4c123g-dma-pwm

器件型号:TM4C123GH6PM

我需要使用计时器生成 PWM 信号并通过我的信号进行调制、因此我决定使用 DMA。 遗憾的是、我发现 DMA 事务不是由 PWM 事件发生的。 我制作了一个显示问题的示例项目。 在此项目中、DMA 控制 GPIO 引脚(例如)、它仅在我使用计时器的 TIMER_CFG_PERIODICRACIOD 模式时有效。 如果我选择 TIMER_CFG_A_PWM、则 DMA 事务永远不会发生(永远不会发生中断)。 您能告诉我我我代码中有什么问题、还是它只是处理器的一个功能?

#include 
#include 
include "stdlib.h"
#include "UART/HW_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_uart.h"
#include "inc/hw_ints.h"

#include "driverlib/interrupt.h"
#include "driverlib/driver.h"#include "driverlib/driver.h"#driverlib.driverlib"#driverlib.driver.h"#include "driverlib.driverlib"#driverlib.driver.h"#include "driverlib.driverlib.driver.h"#include "driverlib"#driverlib.driverlib.driverlib.driver.h"


#include "driverlib"#driver.h"#include "driverlib"#driverlib.driverlib.driver.h"#include "driverlib.driverlib.driver







#define GPIO_base_Output1 GPIO_PORTF_BASE
#define GPIO_Periph_Output1 SYSCTL_Periph_GPIOF

void InitDMA (void);
void InitGPIO (void);
void InitTimer (void);
void setup (void);void
loop (void);
void TimerInt (void);


//保存系统时钟 clk volatile
uint32_t g_ui32SysClock;

//保存 GPIO 状态
的数组 static uint32_t OutputState[4]={0x00000002、0x00000000、0x00000000、0x00000002};
static uint32_t OutputState2[4]、0x00000002



、0x00000000 /
//
// uDMA 控制器使用的控制表。 此表必须与
1024字节边界对齐//。
////
*****************

#pragma DATA_ALIGNing=1024
uint8_t DMACONTROL1 [1024];

//
4次传输后 DMA 完成并调用此中断
,这是为了复位 DMA 并重新启用它
*/
void TimerInt (void)
{
TimerIntClear (TIMER3_base、TIMER_TINA_DMA);

if (uDMAChannelModeGet (UDMA_CH2_TIMER3A | UDMA_PRI_SELECT)= UDMA_MODE_STOP)
{
//再次设置相同的源地址和目标
uDMAChannelTransferSet (UDMA_CH2_TIMER3A | UDMA_PRI_SELECT、
UDMA_OPT_MODE1
)、UDMA_OUTMP_OUTPUT3 (UDMA_DE_OUTPUTDOUT_4






)+ UDMA_OUTDOUDMA_DPUT_TOP_TOP_TOP_032_UDMA_DREST_UDMA_1 (UDMA_ST_OUTPUTDOUT_UDMA_1、UDMA_POST_UDMA_POST_032_UDMA_DREST_UDMA_DR_UDMA_1 (UDMA_POUT_OUTPUT_OUTPUT_UDMA_POUT_4)+(UDMA_OUTPUT_OUTPUT_OUTPUT_OUTPUTDOUTDOUT_4)+(UDMA_POUT_OUTPUT_OU



//始终需要、因为完成后 DMA 被禁用
uDMAChannelEnable (UDMA_CH2_TIMER3A);
}

//
设置 DMA 的函数
*/
void InitDMA ()
{

//仅禁用以能够复位外设状态
SysCtlDisable (SYSCTL_Periph_USysCtl);
SysCtl(USYSCHET_SysCtl)
;启用 DMA (USYSCHET_SysCtl)PeripheralDisable (UST_SysCtl);





uDMAControlBaseSet (DMAcontroltable);

//
*这用于使用 CH2 TimerA 设置 GPIO_base_Output1
*/

//将通道触发器设置为 Timer3A
uDMAChannelAssign (UDMA_CH2_TIMER3A);

//在设置了任何属性的情况下禁用所有属性
uDMAChannelDisable (UDMA_CH2_TIMER3A、
//UDMA_ATECT_ALTSELtr | UDMA_ATURST_USEBTR_USTR_URST
|
UDMA_ATTR_HIGH_PRIOR|
uDMA_attr_REQMASK);

/*
这会将项目大小设置为8位、源增量设置为8位
将目的增量设为 none、将仲裁大小设为1
*/
uDMAChannelControlSet (UDMA_CH2_TIMER3A | UDMA_PRI_SELECT、
UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE |
UDMA_ARB_1);

uDMAChannelControlSet (UDMA_CH2_TIMER3A | UDMA_ALT_SELECT、
UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE |
UDMA_ARB_1);

/*
这会将传输模式设置为我们所需数组的基本源地址
将目标地址转换为我们所处的 GPIO 状态。 它还设置总传输
尺寸更改为2.
//
uDMAChannelTransferSet (UDMA_CH2_TIMER3A | UDMA_PRI_SELECT、
UDMA_MODE_PINGONG、
OutputState、(void *)(GPIO_base_Output1 + 0x03FC)、
4);

uDMAChannelTransferSet (UDMA_CH2_TIMER3A | UDMA_ALT_SELECT、
UDMA_MODE_PINGONG、
OutputStat2、(void *)(GPIO_base_Output1 + 0x03FC)、
4);


//启用 DMA 通道
uDMAChannelEnable (UDMA_CH2_TIMER3A);
}

//
这是为了将所选 GPIO 的所有引脚设置为输出
*/
void InitGPIO()
{
SysCtlPeripheralDisable (GPIO_Periph_Output1);
SysCtlPeripheralReset (GPIO_Periph_Output1);
SysCtlPeripheralEnable (GPIO_Periph_Output1);
SysCtlDelay (10);

GPIOPinTypeGPIOOutput (GPIO_base_Output1、GPIO_PIN_1);
GPIOPinWrite (GPIO_base_Output1、GPIO_PIN_1、0);
}

/*
函数,用于设置计时器以减少周期计数,周期为1秒。
它还使 DMA 触发器和事件超时(计数器到达0)
*/
void InitTimer()
{
SysCtlPeripheralDisable (SYSCTL_Periph_TIMER3);
SysCtlPeripheralReset (SYSCTL_Periph_TIMER3);
SysCtlPeripheralEnable (SYSCTL_Periph_TIMER3



);SysCtlPeripheralEnable (SysCtlTimer3)(SysCtlTimer3);Configure Timer3 (TIMDelay_TIMER3) TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);//TIMER_CFG_PERIODICRACRACASE);//周期工作精细
TimerLoadSet (TIMER3_base、TIMER_A、2499);
TimerMatchSet (TIMER3_base、TIMER_A、 800);

TimerIntClear (TIMER3_base、TIMER_TINA_DMA);
TimerIntRegister (TIMER3_base、TIMER_A、 TimerInt);
TimerIntEnable (TIMER3_base、TIMER_TINA_DMA);

TimerDMAEventSet (TIMER3_base、TIMER_DMA_TIMEOUT_A);
}

void main ()
{
//将 CLK 设置为~80MHz
g_ui32SysClock = map_SysCtlClockFreqSet ((SYSCTL_XTAL_20MHz |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480)、8000000);

InitTimer();
InitGPIO ();
InitDMA ();

//启用计时器以开始计数
TimerEnable (TIMER3_base、timer_A);

//无限循环并仅观察引脚在
while (true)
{

}时切换

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我想让大家知道、我看到了这个问题、今天已经在寻找一个答案了几个小时。 很抱歉,我还没有找到一个。 我看到原始中断状态寄存器设置为0x4、但没有 UDMA 请求。 明天我将寻求一些额外的帮助、并在明天一天结束前为您提供最新信息。 (我在 GMT-5中)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的支持。 我期待您的建议。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    到目前为止还不幸运。 深入了解器件 VHDL 可能需要一些时间。 同时、如果您有额外的可用定时器、您可以使用定时器的 B 部分来生成 UDMA 请求。

    另一种可能是使用 PWM 引脚更改来生成 DMA 请求。 我将在明天尝试研究这种可能性。