LPCXpresso1549试用报告——
(3)使用SWM将功能动态分配到任意引脚
| |
| LPCXpresso1549, LPCOpen, LPC1549, Keil MDK, ARM Cortex-M, SWM, 功能分配任意引脚 |
| 本文记述了介绍LPC15xx的SWM模块将芯片的功能分配到任意引脚,并可以再分配之后再次分配,即动态分配,采用LPCXpresso1549,将SCT0的OUT0作为PWM输出动态分配到板载三色LED的PIO0_3, PIO0_25, PIO1_1三个引脚,演示动态分配功能。 |
Mar4zhu
目 录
插图索引
表格索引
错误!未找到目录项。
1 概述LPC15xx系列芯片具有非常灵活的,基于矩阵的功能引脚分配模块SWM(Swtich Matrix Module),该模块其实是一个多路复选器(Mux),将一个功能通过复选器分配到一个引脚。
使用SWM,用户可以自由分配功能到任意引脚,只需要注意几点:
(1)没有功能冲突,即两个功能分配到同一个引脚造成冲突。
(2)有些功能具有一定的特殊要求, 比如模拟引脚、I2C要求、驱动、上下拉电阻等,需要注意对应的引脚应该满足这些要求。
(3)有些功能是固定引脚的,注意要在设计之前做好分配。
图 11 LPCXpresso15xx的SWM功能示意图
2 项目设计原理本项目采用LPCXpresso1549的板载LED,将SCT0的OUT0作为PWM输出动态分配到板载三色LED的PIO0_3, PIO0_25, PIO1_1三个引脚,轮流对三个颜色进行控制。其中PWM采用慢慢修改占空比的方式呈现呼吸灯效果。
2.1. PWM控制LED的呼吸灯设计PWM采用计时+比较,可以设置成不同周期和不同占空比的输出。 这样LED就呈现不同的亮度。如果控制成渐亮渐灭,仿佛人的呼吸一样,肺部一胀一缩,称之为呼吸灯。
LPCXpresso1549板载一个三色LED,共阳极,阴极分别连接到MCU的PIO0_3, PIO0_25, PIO1_1三个引脚。
图 21 LPCXpresso1549的板载三色LED原理图
为了实现PWM功能,采用了SCT0的PWM功能。
将MATCH0作为PWM总周期的计时,当MATCH0匹配时,设置为AUTOLIMIT,将计数器自动归零,同时触发event0,将PWM输出为Set。此时引脚输出为高电平,由于LED是共阳极连接,因此LED熄灭。
MATCH1作为PWM的占空比比较器。当MATCH1匹配时,触发event1,将PWM输出为clear。此时引脚输出为低电平,由于LED是共阳极连接,因此LED点亮。
通过main函数的延时循环,修改MATCH1寄存器,则PWM的占空比变化,这样LED的亮度也慢慢变化,MATCH1寄存器慢慢增大,则PWM占空比降低,慢慢减小,则PWM占空比增加。
图 22 SCT0的PWM功能示意图
PWM输出代码如下。
// main() {
// Chip_SCTPWM_SetRate
{
LPC_SCT0->CTRL |= (1<<2)|(1<<18);
LPC_SCT0->CTRL |= (1<<3)|(1<<19);
LPC_SCT0->MATCH0 = 0;
LPC_SCT0->MATCHREL0 = 1000;
LPC_SCT0->EV0_CTRL = 0|1<<12; // MATCH0 only
LPC_SCT0->EV0_STATE = 1<<0;
LPC_SCT0->CONFIG = 1|(1<<17); // AUTOLIMIT_L When match0 occurs
}
// app_setup_pin
{
LPC_SYSCON->SYSAHBCLKCTRL0 |= (1<<12); // Enable SWM clock
LPC_SWM->PINASSIGN7 &= ~(0xff<<8);
LPC_SWM->PINASSIGN7 |= (3<<8); //PIO0_3
LPC_SYSCON->SYSAHBCLKCTRL0 &= ~(1<<12); // Disable SWM clock
}
// Chip_SCTPWM_SetOutPin
{
LPC_SCT0->EV1_CTRL = 1|1<<12; // MATCH1 only
LPC_SCT0->EV1_STATE = 1;
LPC_SCT0->OUT0_SET = 1<<0; // Set when MATCH0
LPC_SCT0->OUT0_CLR = 1<<1; // Clear when MATCH1
//LPC_SCT0->RES =
LPC_SCT0->CTRL &= ~(1<<2|1<<18);
}
// Chip_SCTPWM_SetDutyCycle
{
LPC_SCT0->MATCHREL1 = 1000;
}
brightness = 0;
int brightstep = 1;
while(1) {
delay(10);
brightness += brightstep;
if (brightness >=1000) brightstep = -1;
else if (brightness <=0) brightstep = 1;
LPC_SCT0->MATCHREL1 = brightness;
}
}
// the end
2.2. 动态SWM切换SCT0_OUT0的输出引脚本项目将SCT0_OUT0通过SWM定时切换到这三个引脚上,实现动态切换引脚的功能。
设置SysTicker约3s一次中断,在SysTicker中中断中修改SCT0_OUT0的连接引脚在PIO0_3, PIO0_25, PIO1_1三个引脚之间切换。
// app_setup_pin
{
LPC_SYSCON->SYSAHBCLKCTRL0 |= (1<<12); // Enable SWM clock
LPC_SWM->PINASSIGN7 &= ~(0xff<<8);
LPC_SWM->PINASSIGN7 |= (3<<8); //PIO0_3
LPC_SYSCON->SYSAHBCLKCTRL0 &= ~(1<<12); // Disable SWM clock
}
// Enable the SysTicker
{
SysTick->VAL = 0;
SysTick->LOAD = 100000000;
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
SysTick->CTRL = (1<<0)|(1<<1)|(0<<2);
LPC_SYSCON->SYSTICKCLKDIV = 10;
}
void SysTick_Handler() {
// app_setup_pin
const static unsigned int PIO_Number[3] = {33, 3, 25};
static unsigned int index = 0;
index++;
if (index >= 3) index = 0;
{
LPC_SYSCON->SYSAHBCLKCTRL0 |= (1<<12); // Enable SWM clock
LPC_SWM->PINASSIGN7 &= ~( ((unsigned int)0xff) << 8);
LPC_SWM->PINASSIGN7 |= ((unsigned int)PIO_Number[index]<<8); //PIO0_3
LPC_SYSCON->SYSAHBCLKCTRL0 &= ~(1<<12); // Disable SWM clock
}
}
以上代码中的
const static unsigned int PIO_Number[3] = {33, 3, 25};
是由于PIO1_1,PIO0_3, PIO0_25, 对应的PIO序号为33、3、25。
3 实现效果演示视频:
图 31 SWM动态分配SCT0的PWM输出到三个LED效果图
4 总结本项目充分利用了SWM的引脚分配功能,演示了在运行中,动态改变功能到其他引脚的使用。测试了SWM的性能。可大大提高
本项目使用了SCT0、SWM、SysTicker三个外设,综合性较强。
本项目将LPCOpen例程对应的库函数函数重写为寄存器版本。
版本历史(Revision History)
本帖最后由 mars4zhu 于 2014-9-23 11:14 编辑