请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: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)
{
}时切换