主题中讨论的其他器件: TM4C123
工具/软件:Code Composer Studio
大家好、
本周、我将稳步学习 C/IDE/固件编程、并率先尝试合并此 Tiva 芯片的两个示例:single_end.c 和 dead_band.c、以构建使用5V 电源分压器中的 POT 的随机 PWM 相移电路。 请参阅以下代码:
#include
#include
#include "inc/hw_types.h"
#include "deg/hw_memmap.h"
#include "inc/tm4c1294ncppdt.h"
#include "driverlib/adc.h"
#include "driverlib/pio.h"
#include "driverlib/pin_map.h"
#define "driverlib/mctrateg/sym_delt/sym_delt count
#包含"40960.40960"
浮空周期1;
浮子死区1;
浮子循环1;
浮点周期2;
浮子死区2;
float cycle2;
};
int
main (void)
{
浮点 PS;
结构 PWM_PAIR 占空比;
//该数组用于存储从 ADC FIFO 读取的数据。 它
//必须与正在使用的序列发生器的 FIFO 一样大。 此示例
//使用 FIFO 深度为1的序列3。 如果是另一个序列
//与更深的 FIFO 一起使用,则必须更改数组大小。
//
uint32_t pui32ADC0Value[1];
//
//使用 PLL 将时钟设置为以16MHz 运行。 时间
//使用 ADC,您必须使用 PLL 或提供16 MHz 时钟
//源。
SysCtlClockFreqSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz、16000000);// ADC 对此感到满意、PWM 不满意!
//启用系统时钟并将晶振频率设置为16MHz
//SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHz | SYSCTL_OSC_MAIN);//PWM 对此感到满意、但 ADC 不满意!
//必须启用 ADC0外设才能使用。
SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);
//
//对于此示例、ADC0与端口 E7上的 AIN0一起使用。
//您使用的实际端口和引脚可能有所不同,请参阅
//数据表以了解更多信息。 需要启用 GPIO 端口 E
//因此可以使用这些引脚。
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
//
//为这些引脚选择模拟 ADC 功能。
//请查阅数据表以查看每个引脚分配的函数。
GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);
//
//使用处理器信号触发器启用采样序列3。 序列3
//将在处理器发送信号启动时执行单次采样
//转换。 每个 ADC 模块有4个可编程序列、序列0
//至序列3。 此示例任意使用序列3。
//
ADCSequenceConfigure (ADC0_BASE、3、ADC_TRIGGER_PROCESSOR、0);
//
//在序列3上配置步骤0。 对中的通道0 (ADC_CTL_CH0)进行采样
//单端模式(默认)并配置中断标志
//(ADC_CTL_IE)将在采样完成时置1。 告诉 ADC 逻辑
//这是序列3上的最后一次转换(ADC_CTL_END)。 序列
// 3只有一个可编程步骤。 序列1和2有4个步骤、和
//序列0有8个可编程步骤。 因为我们只做一个
//使用序列3进行转换,我们将仅配置步骤0。 了解详情
//有关 ADC 序列和步骤的信息、请参考数据表。
//
ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH0 | ADC_CTL_IE |
ADC_CTL_END);
//
//由于采样序列3现在已配置,因此必须将其启用。
//
ADCSequenceEnable (ADC0_BASE、3);
//
//清除中断状态标志。 这样做是为了确保
//中断标志在我们进行采样之前被清除。
//
ADCIntClear (ADC0_BASE、3);
//
//将 PWM 时钟设置为与系统时钟相同的频率
SysCtlPWMClockSet (SYSCTL_PWMDIV_1);
占空比1 = 800;//开关频率= 20kHz
duty.deadband1 = Duty.period1 * 0/100;//1%死区= 500ns
Duty.Cycl1 = Duty.period1 * 0.5;//50%占空比
Duty.period2 = Duty.period1;//在两个开关频率下的第二个 PWM 模块
duty.deadband2 = Duty.period2 * 0/100;//1%死区
Duty.cycle2 = Duty.Cycle1;
//PS = 0.5;
SysCtlPeripheralEnable (SYSCTL_Periph_PWM0);//启用 PWM 模块0的控制
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);//启用 GPIO B 的控制
GPIOPinConfigure (GPIO_PF0_M0PWM0);//将 PF0映射到 PWM0 Gen0、OP 0
GPIOPinConfigure (GPIO_PF1_M0PWM1);//将 PF1映射到 PWM0 Gen0、OP 1
GPIOPinConfigure (GPIO_PF2_M0PWM2);//将 PWM1、P1 OP2映射到 PF2
GPIOPinConfigure (GPIO_PF3_M0PWM3);//将 PWM1、P1 OP3映射到 PF3
GPIOPinTypePWM (GPIO_PORTF_BASE、GPIO_PIN_0);//将 PF0配置为 PWM
GPIOPinTypePWM (GPIO_PORTF_BASE、GPIO_PIN_1);//将 PF1配置为 PWM
GPIOPinTypePWM (GPIO_PORTF_BASE、GPIO_PIN_2);//将 PF2配置为 PWM
GPIOPinTypePWM (GPIO_PORTF_BASE、GPIO_PIN_3);//将 PF3配置为 PWM
PWMGenConfigure (PWM0_BASE、PWM_GEN_0、PWM_GEN_MODE_DOWN |
PWM_GEN_MODE_NO_SYNC);//将 PWM0 Gen0配置为递减计数器、不同步更新
PWMGenConfigure (PWM0_BASE、PWM_GEN_1、PWM_GEN_MODE_DOWN |
PWM_GEN_MODE_NO_SYNC);//将 PWM1、Gen1配置为递减计数器、不同步更新
PWMGenPeriodSet (PWM0_BASE、PWM_GEN_0、Duty.period1);//设置 PWM0 Gen0的周期
PWMGenPeriodSet (PWM0_BASE、PWM_GEN_1、Duty.period2);//设置 PWM0、Gen1的周期
PWMPulseWidthSet (PWM0_BASE、PWM_OUT_0、Duty.Cycl1);//设置 PWM0 Gen0的占空比
//PWMPulseWidthSet (PWM0_BASE、PWM_OUT_1、Duty.Cycl1);//设置 PWM0 Gen0的占空比
PWMPulseWidthSet (PWM0_BASE、PWM_OUT_2、Duty.cycle2);//设置 PWM0 Gen1的占空比
//PWMPulseWidthSet (PWM0_BASE、PWM_OUT_3、Duty.cycle2);//设置 PWM0 Gen1的占空比
PWMDeadBandEnable (PWM0_BASE、PWM_GEN_0、duty.deadband1 / 2、duty.deadband1 / 2);//在 PWM0 Gen0上配置死区
PWMDeadBandEnable (PWM0_BASE、PWM_GEN_1、duty.deadband2 / 2、duty.deadband2 / 2);//设置死区
PWMOutputState (PWM0_BASE、PWM_OUT_0_BIT | PWM_OUT_1_BIT、TRUE);//在 PWM0 Gen0上启用 OP 0、1
PWMOutputState (PWM0_BASE、PWM_OUT_2_BIT | PWM_OUT_3_BIT、TRUE);//启用运算2、3.
PWMGenEnable (PWM0_BASE、PWM_GEN_0);//启用 PWM0、Gen0
PWMGenEnable (PWM0_BASE、PWM_GEN_1);//启用 PWM0、Gen1
//永久采样 AIN0。 显示控制台上的值。
while (1)
{
//
//触发 ADC 转换。
//
ADCProcessorTrigger (ADC0_BASE、3);
//
//等待转换完成。
//
while (!ADCIntStatus (ADC0_BASE、3、false)//使用 OSC 设置 SysClock 时、这永远不会退出!!!
{
}
//
//清除 ADC 中断标志。
//
ADCIntClear (ADC0_BASE、3);
//
//读取 ADC 值。
//
ADCSequenceDataGet (ADC0_BASE、3、pui32ADC0Value);
//
//在控制台上显示 AIN0 (PE3)数字值。
//
//此函数提供了生成恒定长度的方法
//延迟。 函数延迟(以周期为单位)= 3 *参数。 延迟
//任意地250ms。
SysCtlDelay (SysCtlClockGet ()/12);
PS = pui32ADC0Value[0]* DEG_PER_COUNT;
//PWM0_1_CMPA_R = pui32ADC0Value[0]* DEG_PER_COUNT * Duty.period2; //相对于 Gen0比较器 A 的比例移动 Gen1比较器 A
PWM0_1_CMPA_R = PS *占空比2 / 2; //相对于 Gen0比较器 A 的比例移动 Gen1比较器 A
PWM0_1_CMPB_R = PWM0_1_CMPA_R + Duty.period2 / 2;
PWM0_1_GENA_R = 0x0C80;
}
}
第41行和第44行似乎会引起很多问题、因为 ADC 仅在我使用 PLL 时流动、但 PWM 就在这里。 然后、正如我所说的、如果我尝试使用 OSC、它会在第152行挂起而不返回、这也不是很好... 寻找一个解决方案、让它能够实时地将 PWM1相对于 PWM0移位、乍一看、这个代码是否应该能够避免时钟问题...?
提前感谢、
B