TM4C123G学习记录--PWM输出
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TM4C123G学习记录--PWM输出相关的知识,希望对你有一定的参考价值。
- 为了准备电赛临时学一下TM4C123G,简单记录学习内容
- 大家可以在这里下载我收集的资源,非常全面,花了很大功夫收集来的,还有书籍、例程代码等
- 还可以在TI官网下载相关文档TI官网
一、实验简介
GPIO输出pwm信号,控制板载LED实现呼吸灯效果
二、硬件连接
检查板载LED部分原理图
可见PF1/PF2/PF3对应三个LED,LED由三极管开关电路控制,IO输出高电平点亮,IO输出pwm波可以控制亮度
三、TM4C单片机的PWM介绍
(1)pwm资源
TM4C123GH6PM控制器包含两个pwm模块,每个模块由4个pwm发生器和一个控制模块组成,每个发生器可以产生2个pwm信号,一共可以输出16个pwm信号(同一发生器产生的两个信号的周期是一致的,但占空比可以设为不同的)
(2)pwm发生器特点
(3)结构图
- pwm模块结构图
- 其中一个发生器的细节
(4)pwm信号引脚映射情况
这个表格十分重要,它记录了在硬件层面上,哪些pwm信号输出连接到哪些引脚,编程时需要对照查看
如图可见,PF2连接到M1PWM6,PF3连接到M1PWM7,我们只需控制M1PWM6/M1PWM7在PF2/PF3上输出pwm波,即可控制引脚上连接的LED
(5)pwm模块时钟来源
查看原理图,可见pwm模块时钟来源于经过USEPWMDIV
分频的系统时钟,所有pwm信号的时钟频率都是这个。
(6)pwm信号产生过程
(1)类似stm32,TM4C的pwm利用定时器实现(不过TM4C的pwm模块中有自带的定时器,不需要想stm32那样使用timer外设),可以选择三种计数模式
- 向上计数(pwm信号右对齐)
- 向下计数(pwm信号左对齐)
- 上下计数(pwm信号中间对齐)
(2)每个pwm信号发生器,可以配置两个pwm比较器(类似stm32中的ccrx),比较器根据设定的比较值和当前计数值输出高电平脉冲
(3)所有计数器、比较器的信息会被pwm信号发生器检测,并生成对应的pwm波
(7)其它
关于pwm中断、死区配置、信号同步、故障等内容,因为本人没有深入研究,在此不提了,不好意思
四、TM4C单片机的PWM配置过程- 配置一个PWM发生器,频率25KHz,信号0(MnPWM0)占空比25%,信号1(MnPWM1)占空比75%,假定系统时钟频率为20M
使能PWM时钟
SysCtlPeripheralEnable()
使能被复用引脚的时钟
SysCtlPeripheralEnable()
使能引脚复用PWM功能
GPIOPinTypePWM()
将PWM信号分配到合适的引脚上
GPIOPinConfigure()
使能PWM时钟,设置PWM分频器为2分频(PWM时钟源为10M)
SysCtlPWMClockSet();
配置为向下计数,参数立即更新模式
PWMGenConfigure()
设置周期时间(定时器计数范围),目标频率25K,PWM频率10M,则每一个信号周期有400个PWM周期,故装载值设为400-1(0到399共400个值)
PWMGenPeriodSet()
设置信号0占空比25%,信号1占空比75%
PWMPulseWidthSet()
启动PWM发生器的定时器
PWMGenEnable()
使能PWM输出
PWMOutputState()
#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c123gh6pm.h" //Register Definitions
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/uart.h"
#include "uartstdio.h"
#include "driverlib/systick.h"
#include "driverlib/pin_map.h"
#include "driverlib/pwm.h"
#define delay_ms(n); SysCtlDelay(n*(SysCtlClockGet()/3000));
/******************************************************************************************************************
*函数名: PWMInit()
*描 述:PWM初始化函数
*输 入:无
*线 路:PF2<->M1PWM6
PF4<->M1PWM7
******************************************************************************************************************/
void PWMInit(void)
//配置PWM时钟(设置USEPWMDIV分频器)
SysCtlPWMClockSet(SYSCTL_PWMDIV_1); //PWM时钟 16M
//使能时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); //使能PWM模块1时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); //使能GPIOF时钟
//使能引脚复用PWM功能
GPIOPinTypePWM(GPIO_PORTF_BASE,GPIO_PIN_2);
GPIOPinTypePWM(GPIO_PORTF_BASE,GPIO_PIN_3);
//PWM信号分配
GPIOPinConfigure(GPIO_PF2_M1PWM6); //PF2->PWM模块1信号6
GPIOPinConfigure(GPIO_PF3_M1PWM7); //PF3->PWM模块1信号7
//配置PWM发生器
//模块1->发生器3->上下计数,不同步
PWMGenConfigure(PWM1_BASE,PWM_GEN_3,PWM_GEN_MODE_UP_DOWN|PWM_GEN_MODE_NO_SYNC);
//配置PWM周期
PWMGenPeriodSet(PWM1_BASE,PWM_GEN_3,64000); //64*10^3/16/10^6=4ms
//配置PWM占空比
PWMPulseWidthSet(PWM1_BASE,PWM_OUT_6,PWMGenPeriodGet(PWM1_BASE, PWM_GEN_3)*0.01); //比较值为四分之一总计数值,25%
PWMPulseWidthSet(PWM1_BASE,PWM_OUT_7,PWMGenPeriodGet(PWM1_BASE, PWM_GEN_3)*0.01); //比较值为四分之三总计数值,75%
//使能PWM模块1输出
PWMOutputState(PWM1_BASE,PWM_OUT_6_BIT,true);
PWMOutputState(PWM1_BASE,PWM_OUT_7_BIT,true);
//使能PWM发生器
PWMGenEnable(PWM1_BASE,PWM_GEN_3);
/******************************************************************************************************************
*函数名: SetDuty(uint32_t ui32Base,uint32_t ui32PWMOut,float duty)
*描 述:PWM初始化函数
*输 入:PWM模块编号、信号编号、占空比
******************************************************************************************************************/
void SetDuty(uint32_t ui32Base,uint32_t ui32PWMOut,float duty)
uint32_t ui32Gen;
uint32_t ui32OutBits;
switch(ui32PWMOut)
case PWM_OUT_0: ui32Gen=PWM_GEN_0,ui32OutBits=PWM_OUT_0_BIT; break;
case PWM_OUT_1: ui32Gen=PWM_GEN_0,ui32OutBits=PWM_OUT_1_BIT; break;
case PWM_OUT_2: ui32Gen=PWM_GEN_1,ui32OutBits=PWM_OUT_2_BIT; break;
case PWM_OUT_3: ui32Gen=PWM_GEN_1,ui32OutBits=PWM_OUT_3_BIT; break;
case PWM_OUT_4: ui32Gen=PWM_GEN_2,ui32OutBits=PWM_OUT_4_BIT; break;
case PWM_OUT_5: ui32Gen=PWM_GEN_2,ui32OutBits=PWM_OUT_5_BIT; break;
case PWM_OUT_6: ui32Gen=PWM_GEN_3,ui32OutBits=PWM_OUT_6_BIT; break;
case PWM_OUT_7: ui32Gen=PWM_GEN_3,ui32OutBits=PWM_OUT_7_BIT; break;
//配置占空比
PWMPulseWidthSet(ui32Base, ui32PWMOut, PWMGenPeriodGet(ui32Base, ui32Gen)*duty);
PWMOutputState(ui32Base, ui32OutBits, true);
//使能发生器模块
PWMGenEnable(ui32Base, ui32Gen);
int main()
SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); //系统时钟16M
PWMInit();
float duty1=0.1,duty2=0.9;
float d=0.01;
while(1)
SetDuty(PWM1_BASE,PWM_OUT_6,duty1);
SetDuty(PWM1_BASE,PWM_OUT_7,duty2);
delay_ms(10);
duty1+=d;
duty2-=d;
if(duty1>=0.95 && duty2<=0.05)
d=-0.01;
else if(duty2>=0.95 && duty1<=0.05)
d=0.01;
以上是关于TM4C123G学习记录--PWM输出的主要内容,如果未能解决你的问题,请参考以下文章
TM4C123G红外触摸屏:开发板好不容易实现了原理,放到专家设计的板子上无法运行,于是专家跑路项目黄了